1 /*.............................................................................
2 * Project : SANE library for Plustek flatbed scanners.
3 *.............................................................................
4 */
5
6 /** @file plustek-usbio.c
7 * @brief Some I/O stuff.
8 *
9 * Based on sources acquired from Plustek Inc.<br>
10 * Copyright (C) 2001-2007 Gerhard Jaeger <gerhard@gjaeger.de>
11 *
12 * History:
13 * History:
14 * - 0.40 - starting version of the USB support
15 * - 0.41 - moved some functions to a sane library (sanei_lm983x.c)
16 * - 0.42 - no changes
17 * - 0.43 - no changes
18 * - 0.44 - added dump registers and dumpPic functions
19 * - beautified output of ASIC detection
20 * - 0.45 - fixed dumpRegs
21 * - added dimension stuff to dumpPic
22 * - 0.46 - disabled reset prior to the detection of Merlin
23 * - 0.47 - no changes
24 * - 0.48 - cleanup
25 * - 0.49 - no changes
26 * - 0.50 - usbio_DetectLM983x() now returns error if register
27 * could not be red
28 * - usbio_ResetLM983x() checks for reg7 value before writing
29 * - 0.51 - allow dumpRegs to be called without valid fd
30 * - 0.52 - no changes
31 * .
32 * <hr>
33 * This file is part of the SANE package.
34 *
35 * This program is free software; you can redistribute it and/or
36 * modify it under the terms of the GNU General Public License as
37 * published by the Free Software Foundation; either version 2 of the
38 * License, or (at your option) any later version.
39 *
40 * This program is distributed in the hope that it will be useful, but
41 * WITHOUT ANY WARRANTY; without even the implied warranty of
42 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
43 * General Public License for more details.
44 *
45 * You should have received a copy of the GNU General Public License
46 * along with this program. If not, see <https://www.gnu.org/licenses/>.
47 *
48 * As a special exception, the authors of SANE give permission for
49 * additional uses of the libraries contained in this release of SANE.
50 *
51 * The exception is that, if you link a SANE library with other files
52 * to produce an executable, this does not by itself cause the
53 * resulting executable to be covered by the GNU General Public
54 * License. Your use of that executable is in no way restricted on
55 * account of linking the SANE library code into it.
56 *
57 * This exception does not, however, invalidate any other reasons why
58 * the executable file might be covered by the GNU General Public
59 * License.
60 *
61 * If you submit changes to SANE to the maintainers to be included in
62 * a subsequent release, you agree by submitting the changes that
63 * those changes may be distributed with this exception intact.
64 *
65 * If you write modifications of your own for SANE, it is your choice
66 * whether to permit this exception to apply to your modifications.
67 * If you do not wish that, delete this exception notice.
68 * <hr>
69 */
70
71 #include "../include/sane/sanei_usb.h"
72 #include "../include/sane/sanei_lm983x.h"
73
74 #define _UIO(func) \
75 { \
76 SANE_Status status; \
77 status = func; \
78 if (status != SANE_STATUS_GOOD) { \
79 DBG( _DBG_ERROR, "UIO error\n" ); \
80 return SANE_FALSE; \
81 } \
82 }
83
84 #define usbio_ReadReg(fd, reg, value) \
85 sanei_lm983x_read (fd, reg, value, 1, 0)
86
87 typedef struct {
88
89 u_char depth;
90 u_long x;
91 u_long y;
92 } PicDef, *pPicDef;
93
94 static PicDef dPix;
95
96 /**
97 */
dumpPic( char* name, SANE_Byte *buffer, u_long len, int is_gray )98 static void dumpPic( char* name, SANE_Byte *buffer, u_long len, int is_gray )
99 {
100 u_short type;
101 FILE *fp;
102
103 if( DBG_LEVEL < _DBG_DPIC )
104 return;
105
106 if( NULL == buffer ) {
107
108 DBG( _DBG_DPIC, "Creating file '%s'\n", name );
109
110 fp = fopen( name, "w+b" );
111
112 if( NULL != fp ) {
113
114 if( 0 != dPix.x ) {
115
116 if (is_gray)
117 type = 5;
118 else
119 type = 6;
120
121 DBG( _DBG_DPIC, "> X=%lu, Y=%lu, depth=%u\n",
122 dPix.x, dPix.y, dPix.depth );
123 if( dPix.depth > 8 )
124 fprintf( fp, "P%u\n%lu %lu\n65535\n", type, dPix.x, dPix.y);
125 else
126 fprintf( fp, "P%u\n%lu %lu\n255\n", type, dPix.x, dPix.y);
127 }
128 }
129 } else {
130 fp = fopen( name, "a+b" );
131 }
132
133 if( NULL == fp ) {
134 DBG( _DBG_DPIC, "Can not open file '%s'\n", name );
135 return;
136 }
137
138 fwrite( buffer, 1, len, fp );
139 fclose( fp );
140 }
141
142 /**
143 */
dumpPicInit( ScanParam *sd, char* name )144 static void dumpPicInit( ScanParam *sd, char* name )
145 {
146 dPix.x = sd->Size.dwPhyBytes;
147
148 if( sd->bDataType == SCANDATATYPE_Color )
149 dPix.x /= 3;
150
151 if( sd->bBitDepth > 8 )
152 dPix.x /= 2;
153
154 dPix.y = sd->Size.dwLines;
155 dPix.depth = sd->bBitDepth;
156
157 if( sd->bDataType == SCANDATATYPE_Color )
158 dumpPic(name, NULL, 0, 0);
159 else
160 dumpPic(name, NULL, 0, 1);
161 }
162
163 /**
164 * dump the LM983x registers
165 */
dumpregs( int fd, SANE_Byte *cmp )166 static void dumpregs( int fd, SANE_Byte *cmp )
167 {
168 char buf[256], b2[10];
169 SANE_Byte regs[0x80];
170 int i;
171
172 if( DBG_LEVEL < _DBG_DREGS )
173 return;
174
175 buf[0] = '\0';
176
177 if( fd >= 0 ) {
178 usbio_ReadReg(fd, 0x01, ®s[0x01]);
179 usbio_ReadReg(fd, 0x02, ®s[0x02]);
180 usbio_ReadReg(fd, 0x03, ®s[0x03]);
181 usbio_ReadReg(fd, 0x04, ®s[0x04]);
182 usbio_ReadReg(fd, 0x07, ®s[0x07]);
183
184 sanei_lm983x_read( fd, 0x08, ®s[0x8], 0x80-0x8, SANE_TRUE );
185
186 for( i = 0x0; i < 0x80; i++ ) {
187
188 if((i%16) ==0 ) {
189
190 if( buf[0] )
191 DBG( _DBG_DREGS, "%s\n", buf );
192 sprintf( buf, "0x%02x:", i );
193 }
194
195 if((i%8)==0)
196 strcat( buf, " ");
197
198 /* the dataport read returns with "0 Bytes read", of course. */
199 if((i == 0) || (i == 5) || (i == 6))
200 strcat( buf, "XX ");
201 else {
202
203 sprintf( b2, "%02x ", regs[i]);
204 strcat( buf, b2 );
205 }
206 }
207 DBG( _DBG_DREGS, "%s\n", buf );
208 }
209
210 if( cmp ) {
211
212 buf[0] = '\0';
213
214 DBG( _DBG_DREGS, "Internal setting:\n" );
215 for( i = 0x0; i < 0x80; i++ ) {
216
217 if((i%16) ==0 ) {
218
219 if( buf[0] )
220 DBG( _DBG_DREGS, "%s\n", buf );
221 sprintf( buf, "0x%02x:", i );
222 }
223
224 if((i%8)==0)
225 strcat( buf, " ");
226
227 if((i == 0) || (i == 5) || (i == 6))
228 strcat( buf, "XX ");
229 else {
230 sprintf( b2, "%02x ", cmp[i]);
231 strcat( buf, b2 );
232 }
233 }
234 DBG( _DBG_DREGS, "%s\n", buf );
235 }
236 }
237
238 /**
239 * function to read the contents of a LM983x register and regarding some
240 * extra stuff, like flushing register 2 when writing register 0x58, etc
241 *
242 * @param handle -
243 * @param reg -
244 * @param value -
245 * @return
246 */
usbio_WriteReg( SANE_Int handle, SANE_Byte reg, SANE_Byte value )247 static SANE_Bool usbio_WriteReg( SANE_Int handle,
248 SANE_Byte reg, SANE_Byte value )
249 {
250 int i;
251 SANE_Byte data;
252
253 /* retry loop... */
254 for( i = 0; i < 100; i++ ) {
255
256 sanei_lm983x_write_byte( handle, reg, value );
257
258 /* Flush register 0x02 when register 0x58 is written */
259 if( 0x58 == reg ) {
260 _UIO( usbio_ReadReg( handle, 2, &data ));
261 _UIO( usbio_ReadReg( handle, 2, &data ));
262 }
263
264 if( reg != 7 )
265 return SANE_TRUE;
266
267 /* verify register 7 */
268 _UIO( usbio_ReadReg( handle, 7, &data ));
269 if( data == value ) {
270 return SANE_TRUE;
271 }
272 }
273
274 return SANE_FALSE;
275 }
276
277 /** try and read register 0x69 from a LM983x to find out which version we have.
278 */
usbio_DetectLM983x( SANE_Int fd, SANE_Byte *version )279 static SANE_Status usbio_DetectLM983x( SANE_Int fd, SANE_Byte *version )
280 {
281 char buf[256];
282 SANE_Byte value;
283 SANE_Status res;
284
285 DBG( _DBG_INFO, "usbio_DetectLM983x\n");
286
287 res = usbio_ReadReg(fd, 0x69, &value);
288 if( res != SANE_STATUS_GOOD ) {
289 DBG( _DBG_ERROR, " * could not read version register!\n");
290 return res;
291 }
292
293 value &= 7;
294 if (version)
295 *version = value;
296
297 res = SANE_STATUS_GOOD;
298
299 sprintf( buf, "usbio_DetectLM983x: found " );
300
301 switch((SANE_Int)value ) {
302
303 case 4: strcat( buf, "LM9832/3" ); break;
304 case 3: strcat( buf, "LM9831" ); break;
305 case 2: strcat( buf, "LM9830 --> unsupported!!!" );
306 res = SANE_STATUS_INVAL;
307 break;
308 default: DBG( _DBG_INFO, "Unknown chip v%d", value );
309 res = SANE_STATUS_INVAL;
310 break;
311 }
312
313 DBG( _DBG_INFO, "%s\n", buf );
314 return res;
315 }
316
317 /** well, this is more or less a reset function, for LM9831 based devices
318 * we issue a real reset command, while for LM9832/3 based devices, checking
319 * and resetting register 7 will be enough...
320 */
usbio_ResetLM983x( Plustek_Device *dev )321 static SANE_Status usbio_ResetLM983x( Plustek_Device *dev )
322 {
323 SANE_Byte value;
324 HWDef *hw = &dev->usbDev.HwSetting;
325
326 if( _LM9831 == hw->chip ) {
327
328 DBG( _DBG_INFO," * resetting LM9831 device!\n");
329 _UIO( sanei_lm983x_write_byte( dev->fd, 0x07, 0));
330 _UIO( sanei_lm983x_write_byte( dev->fd, 0x07,0x20));
331 _UIO( sanei_lm983x_write_byte( dev->fd, 0x07, 0));
332 _UIO( usbio_ReadReg( dev->fd, 0x07, &value));
333 if (value != 0) {
334 DBG( _DBG_ERROR, "usbio_ResetLM983x: reset was not "
335 "successful, status=%d\n", value );
336 return SANE_STATUS_INVAL;
337 }
338
339 } else {
340 _UIO( usbio_ReadReg( dev->fd, 0x07, &value));
341 if (value != 0 ) {
342 DBG( _DBG_INFO," * setting device to idle state!\n");
343 _UIO( sanei_lm983x_write_byte( dev->fd, 0x07, 0));
344 }
345 }
346 return SANE_STATUS_GOOD;
347 }
348
349 /* END PLUSTEK-USBIO.C ......................................................*/
350