1141cc406Sopenharmony_ci/** 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#undef BACKEND_NAME 42141cc406Sopenharmony_ci#define BACKEND_NAME umax_pp_low 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_ci#include "../include/sane/config.h" 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci#include <stdio.h> 47141cc406Sopenharmony_ci#include <stdlib.h> 48141cc406Sopenharmony_ci#include <string.h> 49141cc406Sopenharmony_ci#include <math.h> 50141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 51141cc406Sopenharmony_ci#include <sys/time.h> 52141cc406Sopenharmony_ci#endif 53141cc406Sopenharmony_ci#ifdef HAVE_SYS_TYPES_H 54141cc406Sopenharmony_ci#include <sys/types.h> 55141cc406Sopenharmony_ci#endif 56141cc406Sopenharmony_ci#include "../include/sane/sanei_directio.h" 57141cc406Sopenharmony_ci#ifdef HAVE_UNISTD_H 58141cc406Sopenharmony_ci#include <unistd.h> 59141cc406Sopenharmony_ci#endif 60141cc406Sopenharmony_ci#ifdef HAVE_FCNTL_H 61141cc406Sopenharmony_ci#include <fcntl.h> 62141cc406Sopenharmony_ci#endif 63141cc406Sopenharmony_ci#include "../include/sane/sanei_debug.h" 64141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 65141cc406Sopenharmony_ci#include <errno.h> 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_ci#ifdef HAVE_DEV_PPBUS_PPI_H 68141cc406Sopenharmony_ci#include <dev/ppbus/ppi.h> 69141cc406Sopenharmony_ci#include <dev/ppbus/ppbconf.h> 70141cc406Sopenharmony_ci#endif 71141cc406Sopenharmony_ci 72141cc406Sopenharmony_ci#ifdef HAVE_MACHINE_CPUFUNC_H 73141cc406Sopenharmony_ci#include <machine/cpufunc.h> 74141cc406Sopenharmony_ci#endif 75141cc406Sopenharmony_ci 76141cc406Sopenharmony_ci#ifdef HAVE_I386_SET_IOPERM 77141cc406Sopenharmony_ci#include <machine/sysarch.h> 78141cc406Sopenharmony_ci#endif 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 81141cc406Sopenharmony_ci#include <sys/ioctl.h> 82141cc406Sopenharmony_ci#include <linux/parport.h> 83141cc406Sopenharmony_ci#include <linux/ppdev.h> 84141cc406Sopenharmony_ci#endif 85141cc406Sopenharmony_ci 86141cc406Sopenharmony_ci#include "umax_pp_low.h" 87141cc406Sopenharmony_ci 88141cc406Sopenharmony_ci#ifdef DMALLOC 89141cc406Sopenharmony_ci#include "dmalloc.h" 90141cc406Sopenharmony_ci#endif 91141cc406Sopenharmony_ci 92141cc406Sopenharmony_ci#ifndef __IO__ 93141cc406Sopenharmony_ci#define __IO__ 94141cc406Sopenharmony_ci 95141cc406Sopenharmony_ci#define DATA gPort+0x00 96141cc406Sopenharmony_ci#define STATUS gPort+0x01 97141cc406Sopenharmony_ci#define CONTROL gPort+0x02 98141cc406Sopenharmony_ci#define EPPADDR gPort+0x03 99141cc406Sopenharmony_ci#define EPPDATA gPort+0x04 100141cc406Sopenharmony_ci 101141cc406Sopenharmony_ci#define ECPDATA gPort+0x400 102141cc406Sopenharmony_ci#define ECR gPort+0x402 103141cc406Sopenharmony_ci 104141cc406Sopenharmony_ci#define FIFO_WAIT 1000 105141cc406Sopenharmony_ci#endif 106141cc406Sopenharmony_ci 107141cc406Sopenharmony_cistatic int fonc001 (void); 108141cc406Sopenharmony_cistatic int foncSendWord (int *cmd); 109141cc406Sopenharmony_ci 110141cc406Sopenharmony_cistatic void setEPPMode (int mode); 111141cc406Sopenharmony_cistatic int getEPPMode (void); 112141cc406Sopenharmony_cistatic void setModel (int model); 113141cc406Sopenharmony_cistatic int getModel (void); 114141cc406Sopenharmony_cistatic int ringScanner (int count, unsigned long delay); 115141cc406Sopenharmony_cistatic int testVersion (int no); 116141cc406Sopenharmony_ci 117141cc406Sopenharmony_cistatic int probePS2 (unsigned char *dest); 118141cc406Sopenharmony_cistatic int probeEPP (unsigned char *dest); 119141cc406Sopenharmony_cistatic int probeECP (unsigned char *dest); 120141cc406Sopenharmony_ci 121141cc406Sopenharmony_cistatic int sendCommand (int cmd); 122141cc406Sopenharmony_cistatic void SPPResetLPT (void); 123141cc406Sopenharmony_cistatic int sendWord (int *cmd); 124141cc406Sopenharmony_cistatic int sendData (int *cmd, int len); 125141cc406Sopenharmony_cistatic int receiveData (int *cmd, int len); 126141cc406Sopenharmony_cistatic int sendLength (int *cmd, int len); 127141cc406Sopenharmony_ci 128141cc406Sopenharmony_cistatic int waitAck (void); 129141cc406Sopenharmony_cistatic void init001 (void); 130141cc406Sopenharmony_cistatic int init002 (int arg); 131141cc406Sopenharmony_cistatic int init005 (int arg); 132141cc406Sopenharmony_ci 133141cc406Sopenharmony_ci/* 610p comm functions */ 134141cc406Sopenharmony_cistatic int putByte610p (int data); 135141cc406Sopenharmony_cistatic int EPPputByte610p (int data); 136141cc406Sopenharmony_cistatic int sendLength610p (int *cmd); 137141cc406Sopenharmony_cistatic int sendData610p (int *cmd, int len); 138141cc406Sopenharmony_cistatic int receiveData610p (int *cmd, int len); 139141cc406Sopenharmony_cistatic int connect610p (void); 140141cc406Sopenharmony_cistatic int sync610p (void); 141141cc406Sopenharmony_cistatic int cmdSync610p (int cmd); 142141cc406Sopenharmony_cistatic int EPPcmdSync610p (int cmd); 143141cc406Sopenharmony_cistatic int getStatus610p (void); 144141cc406Sopenharmony_cistatic int EPPgetStatus610p (void); 145141cc406Sopenharmony_cistatic int disconnect610p (void); 146141cc406Sopenharmony_cistatic int EPPsendWord610p (int *cmd); 147141cc406Sopenharmony_cistatic int SPPsendWord610p (int *cmd); 148141cc406Sopenharmony_cistatic int cmdSet610p (int cmd, int len, int *buffer); 149141cc406Sopenharmony_cistatic int cmdGet610p (int cmd, int len, int *buffer); 150141cc406Sopenharmony_cistatic int EPPcmdSet610p (int cmd, int len, int *buffer); 151141cc406Sopenharmony_cistatic int EPPcmdGet610p (int cmd, int len, int *buffer); 152141cc406Sopenharmony_cistatic int initScanner610p (int recover); 153141cc406Sopenharmony_cistatic int cmdGetBuffer610p (int cmd, int len, unsigned char *buffer); 154141cc406Sopenharmony_ci 155141cc406Sopenharmony_ci 156141cc406Sopenharmony_ci/* parport mode setting */ 157141cc406Sopenharmony_cistatic void compatMode (void); 158141cc406Sopenharmony_cistatic void byteMode (void); 159141cc406Sopenharmony_cistatic void ECPFifoMode (void); 160141cc406Sopenharmony_ci 161141cc406Sopenharmony_ci/* block transfer init */ 162141cc406Sopenharmony_cistatic void ECPSetBuffer (int size); 163141cc406Sopenharmony_ci 164141cc406Sopenharmony_ci/* mode dependent operations */ 165141cc406Sopenharmony_cistatic int PS2Something (int reg); 166141cc406Sopenharmony_cistatic void PS2bufferRead (int size, unsigned char *dest); 167141cc406Sopenharmony_cistatic void PS2bufferWrite (int size, unsigned char *source); 168141cc406Sopenharmony_cistatic int PS2registerRead (int reg); 169141cc406Sopenharmony_cistatic void PS2registerWrite (int reg, int value); 170141cc406Sopenharmony_ci 171141cc406Sopenharmony_cistatic int EPPconnect (void); 172141cc406Sopenharmony_cistatic int EPPregisterRead (int reg); 173141cc406Sopenharmony_cistatic void EPPregisterWrite (int reg, int value); 174141cc406Sopenharmony_cistatic void EPPbufferRead (int size, unsigned char *dest); 175141cc406Sopenharmony_cistatic void EPPbufferWrite (int size, unsigned char *source); 176141cc406Sopenharmony_cistatic void EPPRead32Buffer (int size, unsigned char *dest); 177141cc406Sopenharmony_cistatic void EPPWrite32Buffer (int size, unsigned char *source); 178141cc406Sopenharmony_ci 179141cc406Sopenharmony_cistatic int ECPconnect (void); 180141cc406Sopenharmony_cistatic void ECPdisconnect (void); 181141cc406Sopenharmony_cistatic int ECPregisterRead (int reg); 182141cc406Sopenharmony_cistatic void ECPregisterWrite (int reg, int value); 183141cc406Sopenharmony_cistatic int ECPbufferRead (int size, unsigned char *dest); 184141cc406Sopenharmony_cistatic void ECPbufferWrite (int size, unsigned char *source); 185141cc406Sopenharmony_cistatic int waitFifoEmpty (void); 186141cc406Sopenharmony_cistatic int waitFifoNotEmpty (void); 187141cc406Sopenharmony_cistatic int waitFifoFull (void); 188141cc406Sopenharmony_ci 189141cc406Sopenharmony_ci/* generic operations */ 190141cc406Sopenharmony_cistatic int connect (void); 191141cc406Sopenharmony_cistatic void disconnect (void); 192141cc406Sopenharmony_cistatic void bufferRead (int size, unsigned char *dest); 193141cc406Sopenharmony_cistatic void bufferWrite (int size, unsigned char *source); 194141cc406Sopenharmony_cistatic int pausedBufferRead (int size, unsigned char *dest); 195141cc406Sopenharmony_ci 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_cistatic void ClearRegister (int reg); 198141cc406Sopenharmony_ci 199141cc406Sopenharmony_cistatic int connect_epat (int r08); 200141cc406Sopenharmony_cistatic int prologue (int r08); 201141cc406Sopenharmony_cistatic int epilogue (void); 202141cc406Sopenharmony_ci 203141cc406Sopenharmony_cistatic int cmdSet (int cmd, int len, int *buffer); 204141cc406Sopenharmony_cistatic int cmdGet (int cmd, int len, int *buffer); 205141cc406Sopenharmony_cistatic int cmdSetGet (int cmd, int len, int *buffer); 206141cc406Sopenharmony_ci 207141cc406Sopenharmony_ci 208141cc406Sopenharmony_cistatic int cmdGetBuffer (int cmd, int len, unsigned char *buffer); 209141cc406Sopenharmony_cistatic int cmdGetBuffer32 (int cmd, int len, unsigned char *buffer); 210141cc406Sopenharmony_cistatic int cmdGetBlockBuffer (int cmd, int len, int window, 211141cc406Sopenharmony_ci unsigned char *buffer); 212141cc406Sopenharmony_ci 213141cc406Sopenharmony_cistatic void bloc2Decode (int *op); 214141cc406Sopenharmony_cistatic void bloc8Decode (int *op); 215141cc406Sopenharmony_ci/* 216141cc406Sopenharmony_ci * high level operations 217141cc406Sopenharmony_ci */ 218141cc406Sopenharmony_cistatic int loadDefaultTables (void); 219141cc406Sopenharmony_cistatic int inquire (void); 220141cc406Sopenharmony_cistatic int offsetCalibration (int color, int *offRed, int *offGreen, 221141cc406Sopenharmony_ci int *offBlue); 222141cc406Sopenharmony_cistatic int coarseGainCalibration (int color, int dcRed, int dcGreen, 223141cc406Sopenharmony_ci int dcBlue, int *vgaRed, int *vgaGreen, 224141cc406Sopenharmony_ci int *vgaBlue); 225141cc406Sopenharmony_cistatic int 226141cc406Sopenharmony_cishadingCalibration (int color, int dcRed, int dcGreen, int dcBlue, 227141cc406Sopenharmony_ci int vgaRed, int vgaGreen, int vgaBlue, int *calibration); 228141cc406Sopenharmony_cistatic int leftShadingCalibration610p (int color, int dcRed, int dcGreen, 229141cc406Sopenharmony_ci int dcBlue, int vgaRed, int vgaGreen, 230141cc406Sopenharmony_ci int vgaBlue, int *calibration); 231141cc406Sopenharmony_ci 232141cc406Sopenharmony_ci#define WRITESLOW(x,y) \ 233141cc406Sopenharmony_ci PS2registerWrite((x),(y)); \ 234141cc406Sopenharmony_ci DBG(16,"PS2registerWrite(0x%X,0x%X) passed... (%s:%d)\n",(x),(y),__FILE__,__LINE__); 235141cc406Sopenharmony_ci#define SLOWNIBBLEREGISTERREAD(x,y) \ 236141cc406Sopenharmony_ci tmp=PS2registerRead(x);\ 237141cc406Sopenharmony_ci if(tmp!=y)\ 238141cc406Sopenharmony_ci {\ 239141cc406Sopenharmony_ci DBG(0,"PS2registerRead: found 0x%X expected 0x%X (%s:%d)\n",tmp,y,__FILE__,__LINE__);\ 240141cc406Sopenharmony_ci /*return 0;*/ \ 241141cc406Sopenharmony_ci }\ 242141cc406Sopenharmony_ci DBG(16,"PS2registerRead(0x%X)=0x%X passed... (%s:%d)\n",x,y,__FILE__,__LINE__); 243141cc406Sopenharmony_ci#define REGISTERWRITE(x,y) \ 244141cc406Sopenharmony_ci registerWrite((x),(y)); \ 245141cc406Sopenharmony_ci DBG(16,"registerWrite(0x%X,0x%X) passed... (%s:%d)\n",(x),(y),__FILE__,__LINE__); 246141cc406Sopenharmony_ci#define REGISTERREAD(x,y) \ 247141cc406Sopenharmony_ci tmp=registerRead(x);\ 248141cc406Sopenharmony_ci if(tmp!=y)\ 249141cc406Sopenharmony_ci {\ 250141cc406Sopenharmony_ci DBG(0,"registerRead, found 0x%X expected 0x%X (%s:%d)\n",tmp,y,__FILE__,__LINE__);\ 251141cc406Sopenharmony_ci return 0;\ 252141cc406Sopenharmony_ci }\ 253141cc406Sopenharmony_ci DBG(16,"registerRead(0x%X)=0x%X passed... (%s:%d)\n",x,y,__FILE__,__LINE__); 254141cc406Sopenharmony_ci#define TRACE(level,msg) DBG(level, msg" (%s:%d)\n",__FILE__,__LINE__); 255141cc406Sopenharmony_ci#define CMDSYNC(x) if(sanei_umax_pp_cmdSync(x)!=1)\ 256141cc406Sopenharmony_ci {\ 257141cc406Sopenharmony_ci DBG(0,"cmdSync(0x%02X) failed (%s:%d)\n",x,__FILE__,__LINE__);\ 258141cc406Sopenharmony_ci return 0;\ 259141cc406Sopenharmony_ci }\ 260141cc406Sopenharmony_ci DBG(16,"cmdSync(0x%02X)=%02X passed ... (%s:%d)\n",x,sanei_umax_pp_scannerStatus(),__FILE__,__LINE__) 261141cc406Sopenharmony_ci#define CMDSETGET(cmd,len,sent) if(cmdSetGet(cmd,len,sent)!=1)\ 262141cc406Sopenharmony_ci {\ 263141cc406Sopenharmony_ci DBG(0,"cmdSetGet(0x%02X,%d,sent) failed (%s:%d)\n",cmd,len,__FILE__,__LINE__);\ 264141cc406Sopenharmony_ci return 0;\ 265141cc406Sopenharmony_ci }\ 266141cc406Sopenharmony_ci TRACE(16,"cmdSetGet() passed ...") 267141cc406Sopenharmony_ci#define YOFFSET 40 268141cc406Sopenharmony_ci#define YOFFSET1220P 40 269141cc406Sopenharmony_ci#define YOFFSET2000P 40 270141cc406Sopenharmony_ci#define COMPLETIONWAIT if(completionWait()==0)\ 271141cc406Sopenharmony_ci {\ 272141cc406Sopenharmony_ci DBG(0,"completionWait() failed (%s:%d)\n",__FILE__,__LINE__);\ 273141cc406Sopenharmony_ci return 0;\ 274141cc406Sopenharmony_ci }\ 275141cc406Sopenharmony_ci TRACE(16,"completionWait() passed ...") 276141cc406Sopenharmony_ci#define MOVE(x,y,t) if(move(x,y,t)==0)\ 277141cc406Sopenharmony_ci {\ 278141cc406Sopenharmony_ci DBG(0,"move(%d,%d,buffer) failed (%s:%d)\n",x,y,__FILE__,__LINE__);\ 279141cc406Sopenharmony_ci return 0;\ 280141cc406Sopenharmony_ci }\ 281141cc406Sopenharmony_ci TRACE(16,"move() passed ...") 282141cc406Sopenharmony_ci#define CMDGETBUF(cmd,len,sent) if(cmdGetBuffer(cmd,len,sent)!=1)\ 283141cc406Sopenharmony_ci {\ 284141cc406Sopenharmony_ci DBG(0,"cmdGetBuffer(0x%02X,%ld,buffer) failed (%s:%d)\n",cmd,(long)len,__FILE__,__LINE__);\ 285141cc406Sopenharmony_ci return 0;\ 286141cc406Sopenharmony_ci }\ 287141cc406Sopenharmony_ci DBG(16,"cmdGetBuffer(%ld) passed ... (%s:%d)\n",(long)len,__FILE__,__LINE__); 288141cc406Sopenharmony_ci#define CMDGETBUF32(cmd,len,sent) if(cmdGetBuffer32(cmd,len,sent)!=1)\ 289141cc406Sopenharmony_ci {\ 290141cc406Sopenharmony_ci DBG(0,"cmdGetBuffer32(0x%02X,%ld,buffer) failed (%s:%d)\n",cmd,(long)len,__FILE__,__LINE__);\ 291141cc406Sopenharmony_ci return 0;\ 292141cc406Sopenharmony_ci }\ 293141cc406Sopenharmony_ci TRACE(16,"cmdGetBuffer32() passed ...") 294141cc406Sopenharmony_ci#define CMDSET(cmd,len,sent) if(cmdSet(cmd,len,sent)!=1)\ 295141cc406Sopenharmony_ci {\ 296141cc406Sopenharmony_ci DBG(0,"cmdSet(0x%02X,%d,sent) failed (%s:%d)\n",cmd,len,__FILE__,__LINE__);\ 297141cc406Sopenharmony_ci return 0;\ 298141cc406Sopenharmony_ci }\ 299141cc406Sopenharmony_ci TRACE(16,"cmdSet() passed ...") 300141cc406Sopenharmony_ci#define CMDGET(cmd,len,sent) if(cmdGet(cmd,len,sent)!=1)\ 301141cc406Sopenharmony_ci {\ 302141cc406Sopenharmony_ci DBG(0,"cmdGet(0x%02X,%d,read) failed (%s:%d)\n",cmd,len,__FILE__,__LINE__);\ 303141cc406Sopenharmony_ci return 0;\ 304141cc406Sopenharmony_ci }\ 305141cc406Sopenharmony_ci TRACE(16,"cmdGet() passed ...") 306141cc406Sopenharmony_cistatic int gPort = 0x378; 307141cc406Sopenharmony_cistatic float targetCode = 250.0; 308141cc406Sopenharmony_ci 309141cc406Sopenharmony_ci/* global control vars */ 310141cc406Sopenharmony_cistatic int gControl = 0; 311141cc406Sopenharmony_cistatic int gData = 0; 312141cc406Sopenharmony_cistatic int g674 = 0; /* semble indiquer qu'on utilise les IRQ */ 313141cc406Sopenharmony_cistatic int g67D = 0; 314141cc406Sopenharmony_cistatic int g67E = 0; 315141cc406Sopenharmony_cistatic int gEPAT = 0; /* signals fast mode ? */ 316141cc406Sopenharmony_cistatic int g6FE = 0; 317141cc406Sopenharmony_cistatic int gECP = 0; 318141cc406Sopenharmony_ci 319141cc406Sopenharmony_cistatic int gLeft = 144; /* default value for 1220P */ 320141cc406Sopenharmony_ci 321141cc406Sopenharmony_ci/* default gamma translation table */ 322141cc406Sopenharmony_cistatic int ggamma[256] = 323141cc406Sopenharmony_ci { 0x00, 0x06, 0x0A, 0x0D, 0x10, 0x12, 0x14, 0x17, 0x19, 0x1B, 0x1D, 324141cc406Sopenharmony_ci 0x1F, 325141cc406Sopenharmony_ci 0x21, 0x23, 0x24, 0x26, 0x28, 0x2A, 0x2B, 0x2D, 0x2E, 0x30, 0x31, 0x33, 326141cc406Sopenharmony_ci 0x34, 0x36, 0x37, 0x39, 0x3A, 0x3B, 0x3D, 0x3E, 0x40, 0x41, 0x42, 0x43, 327141cc406Sopenharmony_ci 0x45, 0x46, 0x47, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4F, 0x50, 0x51, 0x52, 328141cc406Sopenharmony_ci 0x53, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x60, 329141cc406Sopenharmony_ci 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 330141cc406Sopenharmony_ci 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 331141cc406Sopenharmony_ci 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 332141cc406Sopenharmony_ci 0x85, 0x86, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 333141cc406Sopenharmony_ci 0x90, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 334141cc406Sopenharmony_ci 0x9A, 0x9B, 0x9C, 0x9D, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 335141cc406Sopenharmony_ci 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAC, 0xAD, 336141cc406Sopenharmony_ci 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB4, 0xB5, 0xB6, 0xB7, 337141cc406Sopenharmony_ci 0xB8, 0xB8, 0xB9, 0xBA, 0xBB, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xBF, 0xC0, 338141cc406Sopenharmony_ci 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC5, 0xC5, 0xC6, 0xC7, 0xC8, 0xC8, 0xC9, 339141cc406Sopenharmony_ci 0xCA, 0xCB, 0xCB, 0xCC, 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD1, 0xD1, 0xD2, 340141cc406Sopenharmony_ci 0xD3, 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDB, 341141cc406Sopenharmony_ci 0xDC, 0xDC, 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE1, 0xE1, 0xE2, 0xE3, 0xE3, 342141cc406Sopenharmony_ci 0xE4, 0xE5, 0xE6, 0xE6, 0xE7, 0xE8, 0xE8, 0xE9, 0xEA, 0xEA, 0xEB, 0xEC, 343141cc406Sopenharmony_ci 0xEC, 0xED, 0xEE, 0xEF, 0xEF, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF3, 0xF4, 344141cc406Sopenharmony_ci 0xF5, 0xF5, 0xF6, 0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFC, 345141cc406Sopenharmony_ci 0xFD, 0xFE, 0xFE, 0xFF 346141cc406Sopenharmony_ci}; 347141cc406Sopenharmony_ci 348141cc406Sopenharmony_ci 349141cc406Sopenharmony_ci/* default gamma translation table */ 350141cc406Sopenharmony_cistatic int *ggGreen = ggamma; 351141cc406Sopenharmony_cistatic int *ggBlue = ggamma; 352141cc406Sopenharmony_cistatic int *ggRed = ggamma; 353141cc406Sopenharmony_cistatic int gParport = 0; 354141cc406Sopenharmony_cistatic int gCancel = 0; 355141cc406Sopenharmony_cistatic int gAutoSettings = 1; 356141cc406Sopenharmony_ci 357141cc406Sopenharmony_ci 358141cc406Sopenharmony_ci/*****************************************************************************/ 359141cc406Sopenharmony_ci/* output one byte on given port */ 360141cc406Sopenharmony_ci/*****************************************************************************/ 361141cc406Sopenharmony_cistatic void Outb (int port, int value); 362141cc406Sopenharmony_ci 363141cc406Sopenharmony_ci/*****************************************************************************/ 364141cc406Sopenharmony_ci/* output 'size' bytes stored in 'source' on given port */ 365141cc406Sopenharmony_ci/*****************************************************************************/ 366141cc406Sopenharmony_cistatic void Outsb (int port, unsigned char *source, int size); 367141cc406Sopenharmony_ci 368141cc406Sopenharmony_ci/*****************************************************************************/ 369141cc406Sopenharmony_ci/* output 'size' 32 bits words stored in 'source' on given port */ 370141cc406Sopenharmony_ci/*****************************************************************************/ 371141cc406Sopenharmony_cistatic void Outsw (int port, unsigned char *source, int size); 372141cc406Sopenharmony_ci 373141cc406Sopenharmony_ci 374141cc406Sopenharmony_ci/*****************************************************************************/ 375141cc406Sopenharmony_ci/* input one byte from given port */ 376141cc406Sopenharmony_ci/*****************************************************************************/ 377141cc406Sopenharmony_cistatic int Inb (int port); 378141cc406Sopenharmony_ci 379141cc406Sopenharmony_ci/*****************************************************************************/ 380141cc406Sopenharmony_ci/* input 'size' bytes from given port and store them in 'dest' */ 381141cc406Sopenharmony_ci/*****************************************************************************/ 382141cc406Sopenharmony_cistatic void Insb (int port, unsigned char *dest, int size); 383141cc406Sopenharmony_ci 384141cc406Sopenharmony_ci/*****************************************************************************/ 385141cc406Sopenharmony_ci/* input 'size' 32 bits word from given port and store them in 'dest' */ 386141cc406Sopenharmony_ci/*****************************************************************************/ 387141cc406Sopenharmony_cistatic void Insw (int port, unsigned char *dest, int size); 388141cc406Sopenharmony_ci 389141cc406Sopenharmony_ci 390141cc406Sopenharmony_ci 391141cc406Sopenharmony_cichar ** 392141cc406Sopenharmony_cisanei_parport_find_port (void) 393141cc406Sopenharmony_ci{ 394141cc406Sopenharmony_ci char **ports = NULL; 395141cc406Sopenharmony_ci#ifdef ENABLE_PARPORT_DIRECTIO 396141cc406Sopenharmony_ci int i, addr, ecpaddr; 397141cc406Sopenharmony_ci int found = 0; 398141cc406Sopenharmony_ci char name[80], buffer[80]; 399141cc406Sopenharmony_ci FILE *fic = NULL; 400141cc406Sopenharmony_ci 401141cc406Sopenharmony_ci /* direct I/O detection */ 402141cc406Sopenharmony_ci /* linux 2.4 + 2.6 with proc support */ 403141cc406Sopenharmony_ci for (i = 0; i < 4; i++) 404141cc406Sopenharmony_ci { 405141cc406Sopenharmony_ci /* try to ensure loading of lp module */ 406141cc406Sopenharmony_ci sprintf (name, "/dev/lp%d", i); 407141cc406Sopenharmony_ci fic = fopen (name, "wb"); 408141cc406Sopenharmony_ci if (fic != NULL) 409141cc406Sopenharmony_ci fclose (fic); 410141cc406Sopenharmony_ci sprintf (name, "/proc/sys/dev/parport/parport%d/base-addr", i); 411141cc406Sopenharmony_ci fic = fopen (name, "rb"); 412141cc406Sopenharmony_ci if (fic != NULL) 413141cc406Sopenharmony_ci { 414141cc406Sopenharmony_ci fread (buffer, 64, 1, fic); 415141cc406Sopenharmony_ci fclose (fic); 416141cc406Sopenharmony_ci if (sscanf (buffer, "%d %d", &addr, &ecpaddr) > 0) 417141cc406Sopenharmony_ci { 418141cc406Sopenharmony_ci DBG (16, "parport at 0x%X\n", addr); 419141cc406Sopenharmony_ci ports = 420141cc406Sopenharmony_ci (char **) realloc (ports, (found + 2) * sizeof (char *)); 421141cc406Sopenharmony_ci ports[found] = (char *) malloc (19); 422141cc406Sopenharmony_ci sprintf (ports[found], "0x%X", addr); 423141cc406Sopenharmony_ci found++; 424141cc406Sopenharmony_ci ports[found] = NULL; 425141cc406Sopenharmony_ci } 426141cc406Sopenharmony_ci } 427141cc406Sopenharmony_ci } 428141cc406Sopenharmony_ci#endif 429141cc406Sopenharmony_ci return ports; 430141cc406Sopenharmony_ci} 431141cc406Sopenharmony_ci 432141cc406Sopenharmony_ci 433141cc406Sopenharmony_cichar ** 434141cc406Sopenharmony_cisanei_parport_find_device (void) 435141cc406Sopenharmony_ci{ 436141cc406Sopenharmony_ci char *devices[] = { 437141cc406Sopenharmony_ci /* FreeBSD */ 438141cc406Sopenharmony_ci "/dev/ppi0", 439141cc406Sopenharmony_ci "/dev/ppi1", 440141cc406Sopenharmony_ci "/dev/ppi2", 441141cc406Sopenharmony_ci "/dev/ppi3", 442141cc406Sopenharmony_ci /* linux ppdev with devfs */ 443141cc406Sopenharmony_ci "/dev/parports/0", 444141cc406Sopenharmony_ci "/dev/parports/1", 445141cc406Sopenharmony_ci "/dev/parports/2", 446141cc406Sopenharmony_ci "/dev/parports/3", 447141cc406Sopenharmony_ci /* linux ppdev */ 448141cc406Sopenharmony_ci "/dev/parport0", 449141cc406Sopenharmony_ci "/dev/parport1", 450141cc406Sopenharmony_ci "/dev/parport2", 451141cc406Sopenharmony_ci "/dev/parport3", 452141cc406Sopenharmony_ci NULL 453141cc406Sopenharmony_ci }; 454141cc406Sopenharmony_ci int i, file; 455141cc406Sopenharmony_ci int rc = 0; 456141cc406Sopenharmony_ci int found = 0; 457141cc406Sopenharmony_ci char **ports = NULL; 458141cc406Sopenharmony_ci 459141cc406Sopenharmony_ci 460141cc406Sopenharmony_ci /* device finding */ 461141cc406Sopenharmony_ci i = 0; 462141cc406Sopenharmony_ci while (devices[i] != NULL) 463141cc406Sopenharmony_ci { 464141cc406Sopenharmony_ci DBG (16, "Controlling %s: ", devices[i]); 465141cc406Sopenharmony_ci file = open (devices[i], O_RDWR); 466141cc406Sopenharmony_ci if (file < 0) 467141cc406Sopenharmony_ci { 468141cc406Sopenharmony_ci switch (errno) 469141cc406Sopenharmony_ci { 470141cc406Sopenharmony_ci case ENOENT: 471141cc406Sopenharmony_ci#ifdef ENIO 472141cc406Sopenharmony_ci case ENXIO: 473141cc406Sopenharmony_ci#endif 474141cc406Sopenharmony_ci#ifdef ENODEV 475141cc406Sopenharmony_ci case ENODEV: 476141cc406Sopenharmony_ci#endif 477141cc406Sopenharmony_ci DBG (16, "no %s device ...\n", devices[i]); 478141cc406Sopenharmony_ci break; 479141cc406Sopenharmony_ci case EACCES: 480141cc406Sopenharmony_ci DBG (16, "current user cannot use existing %s device ...\n", 481141cc406Sopenharmony_ci devices[i]); 482141cc406Sopenharmony_ci break; 483141cc406Sopenharmony_ci default: 484141cc406Sopenharmony_ci perror (devices[i]); 485141cc406Sopenharmony_ci } 486141cc406Sopenharmony_ci } 487141cc406Sopenharmony_ci else 488141cc406Sopenharmony_ci { 489141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 490141cc406Sopenharmony_ci /* on kernel < 2.4.23, you have to CLAIM the device 491141cc406Sopenharmony_ci * to check it really exists 492141cc406Sopenharmony_ci * we may hang if another program already claimed it 493141cc406Sopenharmony_ci */ 494141cc406Sopenharmony_ci rc = ioctl (file, PPCLAIM); 495141cc406Sopenharmony_ci if (rc) 496141cc406Sopenharmony_ci { 497141cc406Sopenharmony_ci switch (errno) 498141cc406Sopenharmony_ci { 499141cc406Sopenharmony_ci case ENOENT: 500141cc406Sopenharmony_ci#ifdef ENXIO 501141cc406Sopenharmony_ci case ENXIO: 502141cc406Sopenharmony_ci#endif 503141cc406Sopenharmony_ci#ifdef ENODEV 504141cc406Sopenharmony_ci case ENODEV: 505141cc406Sopenharmony_ci#endif 506141cc406Sopenharmony_ci DBG (16, "no %s device ...\n", devices[i]); 507141cc406Sopenharmony_ci break; 508141cc406Sopenharmony_ci case EACCES: 509141cc406Sopenharmony_ci DBG (16, "current user cannot use existing %s device ...\n", 510141cc406Sopenharmony_ci devices[i]); 511141cc406Sopenharmony_ci break; 512141cc406Sopenharmony_ci default: 513141cc406Sopenharmony_ci DBG (16, "errno=%d\n", errno); 514141cc406Sopenharmony_ci perror (devices[i]); 515141cc406Sopenharmony_ci } 516141cc406Sopenharmony_ci } 517141cc406Sopenharmony_ci else 518141cc406Sopenharmony_ci { 519141cc406Sopenharmony_ci rc = ioctl (file, PPRELEASE); 520141cc406Sopenharmony_ci } 521141cc406Sopenharmony_ci#endif /* HAVE_LINUX_PPDEV_H */ 522141cc406Sopenharmony_ci close (file); 523141cc406Sopenharmony_ci if (!rc) 524141cc406Sopenharmony_ci { 525141cc406Sopenharmony_ci DBG (16, "adding %s to valid devices ...\n", devices[i]); 526141cc406Sopenharmony_ci ports = 527141cc406Sopenharmony_ci (char **) realloc (ports, (found + 2) * sizeof (char *)); 528141cc406Sopenharmony_ci ports[found] = strdup (devices[i]); 529141cc406Sopenharmony_ci found++; 530141cc406Sopenharmony_ci ports[found] = NULL; 531141cc406Sopenharmony_ci } 532141cc406Sopenharmony_ci } 533141cc406Sopenharmony_ci 534141cc406Sopenharmony_ci /* suite */ 535141cc406Sopenharmony_ci i++; 536141cc406Sopenharmony_ci } 537141cc406Sopenharmony_ci return ports; 538141cc406Sopenharmony_ci} 539141cc406Sopenharmony_ci 540141cc406Sopenharmony_ci 541141cc406Sopenharmony_ci 542141cc406Sopenharmony_ci/* 543141cc406Sopenharmony_ci * gain direct access to IO port, and set parport to the 'right' mode 544141cc406Sopenharmony_ci * returns 1 on success, 0 an failure 545141cc406Sopenharmony_ci */ 546141cc406Sopenharmony_ci 547141cc406Sopenharmony_ci 548141cc406Sopenharmony_ciint 549141cc406Sopenharmony_cisanei_umax_pp_initPort (int port, const char *name) 550141cc406Sopenharmony_ci{ 551141cc406Sopenharmony_ci#ifndef IO_SUPPORT_MISSING 552141cc406Sopenharmony_ci# ifdef HAVE_LINUX_PPDEV_H 553141cc406Sopenharmony_ci int found = 0; 554141cc406Sopenharmony_ci int fd; 555141cc406Sopenharmony_ci int mode, modes, rc; 556141cc406Sopenharmony_ci# ifdef PPGETMODES 557141cc406Sopenharmony_ci char strmodes[160]; 558141cc406Sopenharmony_ci# endif 559141cc406Sopenharmony_ci# endif 560141cc406Sopenharmony_ci# ifdef HAVE_DEV_PPBUS_PPI_H 561141cc406Sopenharmony_ci int found = 0; 562141cc406Sopenharmony_ci int fd; 563141cc406Sopenharmony_ci# endif 564141cc406Sopenharmony_ci# ifdef HAVE_IOPERM 565141cc406Sopenharmony_ci int ectr; 566141cc406Sopenharmony_ci# endif 567141cc406Sopenharmony_ci#endif 568141cc406Sopenharmony_ci 569141cc406Sopenharmony_ci /* since this function must be called before */ 570141cc406Sopenharmony_ci /* any other, we put debug init here */ 571141cc406Sopenharmony_ci DBG_INIT (); 572141cc406Sopenharmony_ci DBG (1, "SANE_INB level %d\n", SANE_INB); 573141cc406Sopenharmony_ci 574141cc406Sopenharmony_ci /* sets global vars */ 575141cc406Sopenharmony_ci ggGreen = ggamma; 576141cc406Sopenharmony_ci ggBlue = ggamma; 577141cc406Sopenharmony_ci ggRed = ggamma; 578141cc406Sopenharmony_ci gParport = 0; 579141cc406Sopenharmony_ci gCancel = 0; 580141cc406Sopenharmony_ci gAutoSettings = 1; 581141cc406Sopenharmony_ci gControl = 0; 582141cc406Sopenharmony_ci gData = 0; 583141cc406Sopenharmony_ci g674 = 0; 584141cc406Sopenharmony_ci g67D = 0; 585141cc406Sopenharmony_ci g67E = 0; 586141cc406Sopenharmony_ci gEPAT = 0; 587141cc406Sopenharmony_ci g6FE = 0; 588141cc406Sopenharmony_ci sanei_umax_pp_setparport (0); 589141cc406Sopenharmony_ci 590141cc406Sopenharmony_ci 591141cc406Sopenharmony_ci DBG (1, "sanei_umax_pp_InitPort(0x%X,%s)\n", port, name); 592141cc406Sopenharmony_ci#ifndef ENABLE_PARPORT_DIRECTIO 593141cc406Sopenharmony_ci if ((name == NULL) || ((name != NULL) && (strlen (name) < 4))) 594141cc406Sopenharmony_ci { 595141cc406Sopenharmony_ci DBG (0, "sanei_umax_pp_InitPort cannot use direct hardware access\n"); 596141cc406Sopenharmony_ci DBG (0, "if not compiled with --enable-parport-directio\n"); 597141cc406Sopenharmony_ci return 0; 598141cc406Sopenharmony_ci } 599141cc406Sopenharmony_ci#endif 600141cc406Sopenharmony_ci 601141cc406Sopenharmony_ci 602141cc406Sopenharmony_ci /* init global var holding port value */ 603141cc406Sopenharmony_ci gPort = port; 604141cc406Sopenharmony_ci 605141cc406Sopenharmony_ci#ifdef IO_SUPPORT_MISSING 606141cc406Sopenharmony_ci DBG (1, "*** Direct I/O or ppdev unavailable, giving up ***\n"); 607141cc406Sopenharmony_ci return 0; 608141cc406Sopenharmony_ci#else 609141cc406Sopenharmony_ci 610141cc406Sopenharmony_ci 611141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 612141cc406Sopenharmony_ci if (name != NULL) 613141cc406Sopenharmony_ci { 614141cc406Sopenharmony_ci if (strlen (name) > 3) 615141cc406Sopenharmony_ci { 616141cc406Sopenharmony_ci /* ppdev opening and configuration */ 617141cc406Sopenharmony_ci found = 0; 618141cc406Sopenharmony_ci fd = open (name, O_RDWR | O_NOCTTY | O_NONBLOCK); 619141cc406Sopenharmony_ci if (fd < 0) 620141cc406Sopenharmony_ci { 621141cc406Sopenharmony_ci switch (errno) 622141cc406Sopenharmony_ci { 623141cc406Sopenharmony_ci case ENOENT: 624141cc406Sopenharmony_ci DBG (1, "umax_pp: '%s' does not exist \n", name); 625141cc406Sopenharmony_ci break; 626141cc406Sopenharmony_ci case EACCES: 627141cc406Sopenharmony_ci DBG (1, 628141cc406Sopenharmony_ci "umax_pp: current user has not R/W permissions on '%s' \n", 629141cc406Sopenharmony_ci name); 630141cc406Sopenharmony_ci break; 631141cc406Sopenharmony_ci } 632141cc406Sopenharmony_ci return 0; 633141cc406Sopenharmony_ci 634141cc406Sopenharmony_ci } 635141cc406Sopenharmony_ci /* claim port */ 636141cc406Sopenharmony_ci if (ioctl (fd, PPCLAIM)) 637141cc406Sopenharmony_ci { 638141cc406Sopenharmony_ci DBG (1, "umax_pp: cannot claim port '%s'\n", name); 639141cc406Sopenharmony_ci } 640141cc406Sopenharmony_ci else 641141cc406Sopenharmony_ci { 642141cc406Sopenharmony_ci /* we check if parport does EPP or ECP */ 643141cc406Sopenharmony_ci#ifdef PPGETMODES 644141cc406Sopenharmony_ci if (ioctl (fd, PPGETMODES, &modes)) 645141cc406Sopenharmony_ci { 646141cc406Sopenharmony_ci DBG (16, 647141cc406Sopenharmony_ci "umax_pp: ppdev couldn't gave modes for port '%s'\n", 648141cc406Sopenharmony_ci name); 649141cc406Sopenharmony_ci } 650141cc406Sopenharmony_ci else 651141cc406Sopenharmony_ci { 652141cc406Sopenharmony_ci snprintf(strmodes, sizeof(strmodes), 653141cc406Sopenharmony_ci "\n%s%s%s%s%s%s", 654141cc406Sopenharmony_ci (modes & PARPORT_MODE_PCSPP)? "\t\tPARPORT_MODE_PCSPP\n": "", 655141cc406Sopenharmony_ci (modes & PARPORT_MODE_TRISTATE)? "\t\tPARPORT_MODE_TRISTATE\n": "", 656141cc406Sopenharmony_ci (modes & PARPORT_MODE_EPP)? "\t\tPARPORT_MODE_EPP\n": "", 657141cc406Sopenharmony_ci (modes & PARPORT_MODE_ECP)? "\t\tPARPORT_MODE_ECP\n": "", 658141cc406Sopenharmony_ci (modes & PARPORT_MODE_COMPAT)? "\t\tPARPORT_MODE_COMPAT\n": "", 659141cc406Sopenharmony_ci (modes & PARPORT_MODE_DMA)? "\t\tPARPORT_MODE_DMA\n": ""); 660141cc406Sopenharmony_ci 661141cc406Sopenharmony_ci if (modes & PARPORT_MODE_ECP) 662141cc406Sopenharmony_ci { 663141cc406Sopenharmony_ci gECP = 1; 664141cc406Sopenharmony_ci } 665141cc406Sopenharmony_ci 666141cc406Sopenharmony_ci DBG (32, "parport modes: %X\n", modes); 667141cc406Sopenharmony_ci DBG (32, "parport modes: %s\n", strmodes); 668141cc406Sopenharmony_ci if (!(modes & PARPORT_MODE_EPP) 669141cc406Sopenharmony_ci && !(modes & PARPORT_MODE_ECP)) 670141cc406Sopenharmony_ci { 671141cc406Sopenharmony_ci DBG (1, 672141cc406Sopenharmony_ci "port 0x%X does not have EPP or ECP, giving up ...\n", 673141cc406Sopenharmony_ci port); 674141cc406Sopenharmony_ci mode = IEEE1284_MODE_COMPAT; 675141cc406Sopenharmony_ci ioctl (fd, PPSETMODE, &mode); 676141cc406Sopenharmony_ci ioctl (fd, PPRELEASE); 677141cc406Sopenharmony_ci close (fd); 678141cc406Sopenharmony_ci return 0; 679141cc406Sopenharmony_ci } 680141cc406Sopenharmony_ci } 681141cc406Sopenharmony_ci 682141cc406Sopenharmony_ci#else 683141cc406Sopenharmony_ci DBG (16, 684141cc406Sopenharmony_ci "umax_pp: ppdev used to build SANE doesn't have PPGETMODES.\n"); 685141cc406Sopenharmony_ci /* faking result */ 686141cc406Sopenharmony_ci modes = 0xFFFFFFFF; 687141cc406Sopenharmony_ci#endif 688141cc406Sopenharmony_ci mode = 0; 689141cc406Sopenharmony_ci 690141cc406Sopenharmony_ci /* preferred mode is EPP */ 691141cc406Sopenharmony_ci if (modes & PARPORT_MODE_EPP) 692141cc406Sopenharmony_ci { 693141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP; 694141cc406Sopenharmony_ci 695141cc406Sopenharmony_ci /* negot always fail here ... */ 696141cc406Sopenharmony_ci rc = ioctl (fd, PPNEGOT, &mode); 697141cc406Sopenharmony_ci if (rc) 698141cc406Sopenharmony_ci { 699141cc406Sopenharmony_ci DBG (16, 700141cc406Sopenharmony_ci "umax_pp: ppdev couldn't negotiate mode IEEE1284_MODE_EPP for '%s' (ignored)\n", 701141cc406Sopenharmony_ci name); 702141cc406Sopenharmony_ci } 703141cc406Sopenharmony_ci if (ioctl (fd, PPSETMODE, &mode)) 704141cc406Sopenharmony_ci { 705141cc406Sopenharmony_ci DBG (16, 706141cc406Sopenharmony_ci "umax_pp: ppdev couldn't set mode to IEEE1284_MODE_EPP for '%s'\n", 707141cc406Sopenharmony_ci name); 708141cc406Sopenharmony_ci /* signal failure for ECP test */ 709141cc406Sopenharmony_ci mode = 0; 710141cc406Sopenharmony_ci } 711141cc406Sopenharmony_ci else 712141cc406Sopenharmony_ci { 713141cc406Sopenharmony_ci DBG (16, 714141cc406Sopenharmony_ci "umax_pp: mode set to PARPORT_MODE_EPP for '%s'\n", 715141cc406Sopenharmony_ci name); 716141cc406Sopenharmony_ci } 717141cc406Sopenharmony_ci } 718141cc406Sopenharmony_ci 719141cc406Sopenharmony_ci if ((modes & PARPORT_MODE_ECP) && (mode == 0)) 720141cc406Sopenharmony_ci { 721141cc406Sopenharmony_ci mode = IEEE1284_MODE_ECP; 722141cc406Sopenharmony_ci rc = ioctl (fd, PPNEGOT, &mode); 723141cc406Sopenharmony_ci if (rc) 724141cc406Sopenharmony_ci { 725141cc406Sopenharmony_ci DBG (16, 726141cc406Sopenharmony_ci "umax_pp: ppdev couldn't negotiate mode IEEE1284_MODE_ECP for '%s' (ignored)\n", 727141cc406Sopenharmony_ci name); 728141cc406Sopenharmony_ci } 729141cc406Sopenharmony_ci if (ioctl (fd, PPSETMODE, &mode)) 730141cc406Sopenharmony_ci { 731141cc406Sopenharmony_ci DBG (16, 732141cc406Sopenharmony_ci "umax_pp: ppdev couldn't set mode to IEEE1284_MODE_ECP for '%s'\n", 733141cc406Sopenharmony_ci name); 734141cc406Sopenharmony_ci DBG (1, 735141cc406Sopenharmony_ci "port 0x%X can't be set to EPP or ECP, giving up ...\n", 736141cc406Sopenharmony_ci port); 737141cc406Sopenharmony_ci 738141cc406Sopenharmony_ci mode = IEEE1284_MODE_COMPAT; 739141cc406Sopenharmony_ci ioctl (fd, PPSETMODE, &mode); 740141cc406Sopenharmony_ci ioctl (fd, PPRELEASE); 741141cc406Sopenharmony_ci close (fd); 742141cc406Sopenharmony_ci return 0; 743141cc406Sopenharmony_ci } 744141cc406Sopenharmony_ci else 745141cc406Sopenharmony_ci { 746141cc406Sopenharmony_ci gECP = 1; 747141cc406Sopenharmony_ci DBG (16, 748141cc406Sopenharmony_ci "umax_pp: mode set to PARPORT_MODE_ECP for '%s'\n", 749141cc406Sopenharmony_ci name); 750141cc406Sopenharmony_ci } 751141cc406Sopenharmony_ci } 752141cc406Sopenharmony_ci 753141cc406Sopenharmony_ci 754141cc406Sopenharmony_ci /* always start in compat mode (for probe) */ 755141cc406Sopenharmony_ci mode = IEEE1284_MODE_COMPAT; 756141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 757141cc406Sopenharmony_ci if (rc) 758141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", 759141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 760141cc406Sopenharmony_ci mode = 0; /* data forward */ 761141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 762141cc406Sopenharmony_ci if (rc) 763141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", 764141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 765141cc406Sopenharmony_ci mode = 1; /* FW IDLE */ 766141cc406Sopenharmony_ci rc = ioctl (fd, PPSETPHASE, &mode); 767141cc406Sopenharmony_ci if (rc) 768141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", 769141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 770141cc406Sopenharmony_ci found = 1; 771141cc406Sopenharmony_ci 772141cc406Sopenharmony_ci } 773141cc406Sopenharmony_ci 774141cc406Sopenharmony_ci if (!found) 775141cc406Sopenharmony_ci { 776141cc406Sopenharmony_ci DBG (1, "device %s does not fit ...\n", name); 777141cc406Sopenharmony_ci } 778141cc406Sopenharmony_ci else 779141cc406Sopenharmony_ci { 780141cc406Sopenharmony_ci DBG (1, "Using %s ...\n", name); 781141cc406Sopenharmony_ci sanei_umax_pp_setparport (fd); 782141cc406Sopenharmony_ci return 1; 783141cc406Sopenharmony_ci } 784141cc406Sopenharmony_ci } 785141cc406Sopenharmony_ci } 786141cc406Sopenharmony_ci#endif /* HAVE_LINUX_PPDEV_H */ 787141cc406Sopenharmony_ci 788141cc406Sopenharmony_ci 789141cc406Sopenharmony_ci#ifdef HAVE_DEV_PPBUS_PPI_H 790141cc406Sopenharmony_ci/* the ppi device let user access to parallel port on freebsd */ 791141cc406Sopenharmony_ci if (name != NULL) 792141cc406Sopenharmony_ci { 793141cc406Sopenharmony_ci if (strlen (name) > 3) 794141cc406Sopenharmony_ci { 795141cc406Sopenharmony_ci /* ppi opening and configuration */ 796141cc406Sopenharmony_ci found = 0; 797141cc406Sopenharmony_ci fd = open (name, O_RDONLY); 798141cc406Sopenharmony_ci if (fd < 0) 799141cc406Sopenharmony_ci { 800141cc406Sopenharmony_ci switch (errno) 801141cc406Sopenharmony_ci { 802141cc406Sopenharmony_ci case ENOENT: 803141cc406Sopenharmony_ci DBG (1, "umax_pp: '%s' does not exist \n", name); 804141cc406Sopenharmony_ci break; 805141cc406Sopenharmony_ci case EACCES: 806141cc406Sopenharmony_ci DBG (1, 807141cc406Sopenharmony_ci "umax_pp: current user has not read permissions on '%s' \n", 808141cc406Sopenharmony_ci name); 809141cc406Sopenharmony_ci break; 810141cc406Sopenharmony_ci } 811141cc406Sopenharmony_ci return 0; 812141cc406Sopenharmony_ci } 813141cc406Sopenharmony_ci else 814141cc406Sopenharmony_ci { 815141cc406Sopenharmony_ci DBG (1, "Using %s ...\n", name); 816141cc406Sopenharmony_ci sanei_umax_pp_setparport (fd); 817141cc406Sopenharmony_ci return 1; 818141cc406Sopenharmony_ci } 819141cc406Sopenharmony_ci } 820141cc406Sopenharmony_ci } 821141cc406Sopenharmony_ci#endif /* HAVE_DEV_PPBUS_PPI_H */ 822141cc406Sopenharmony_ci 823141cc406Sopenharmony_ci if (port < 0x400) 824141cc406Sopenharmony_ci { 825141cc406Sopenharmony_ci if (sanei_ioperm (port, 8, 1) != 0) 826141cc406Sopenharmony_ci { 827141cc406Sopenharmony_ci DBG (1, "sanei_ioperm() could not gain access to 0x%X\n", port); 828141cc406Sopenharmony_ci return 0; 829141cc406Sopenharmony_ci } 830141cc406Sopenharmony_ci DBG (1, "sanei_ioperm(0x%X, 8, 1) OK ...\n", port); 831141cc406Sopenharmony_ci } 832141cc406Sopenharmony_ci 833141cc406Sopenharmony_ci#ifdef HAVE_IOPERM 834141cc406Sopenharmony_ci /* ECP i/o range */ 835141cc406Sopenharmony_ci if (iopl (3) != 0) 836141cc406Sopenharmony_ci { 837141cc406Sopenharmony_ci DBG (1, "iopl could not raise IO permission to level 3\n"); 838141cc406Sopenharmony_ci DBG (1, "*NO* ECP support\n"); 839141cc406Sopenharmony_ci 840141cc406Sopenharmony_ci } 841141cc406Sopenharmony_ci else 842141cc406Sopenharmony_ci { 843141cc406Sopenharmony_ci /* any ECP out there ? */ 844141cc406Sopenharmony_ci ectr = Inb (ECR); 845141cc406Sopenharmony_ci if (ectr != 0xFF) 846141cc406Sopenharmony_ci { 847141cc406Sopenharmony_ci gECP = 1; 848141cc406Sopenharmony_ci 849141cc406Sopenharmony_ci } 850141cc406Sopenharmony_ci } 851141cc406Sopenharmony_ci#endif 852141cc406Sopenharmony_ci 853141cc406Sopenharmony_ci 854141cc406Sopenharmony_ci 855141cc406Sopenharmony_ci#endif /* IO_SUPPORT_MISSING */ 856141cc406Sopenharmony_ci return 1; 857141cc406Sopenharmony_ci} 858141cc406Sopenharmony_ci 859141cc406Sopenharmony_ci 860141cc406Sopenharmony_ci 861141cc406Sopenharmony_ci 862141cc406Sopenharmony_ci 863141cc406Sopenharmony_ci 864141cc406Sopenharmony_cistatic void 865141cc406Sopenharmony_ciOutb (int port, int value) 866141cc406Sopenharmony_ci{ 867141cc406Sopenharmony_ci#ifndef IO_SUPPORT_MISSING 868141cc406Sopenharmony_ci 869141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 870141cc406Sopenharmony_ci int fd, rc, mode, exmode; 871141cc406Sopenharmony_ci unsigned char val; 872141cc406Sopenharmony_ci 873141cc406Sopenharmony_ci 874141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 875141cc406Sopenharmony_ci val = (unsigned char) value; 876141cc406Sopenharmony_ci if (fd > 0) 877141cc406Sopenharmony_ci { 878141cc406Sopenharmony_ci /* there should be ECR that doesn't go through ppdev */ 879141cc406Sopenharmony_ci /* it will leave when all the I/O will be done with ppdev */ 880141cc406Sopenharmony_ci switch (port - gPort) 881141cc406Sopenharmony_ci { 882141cc406Sopenharmony_ci case 0: 883141cc406Sopenharmony_ci rc = ioctl (fd, PPWDATA, &val); 884141cc406Sopenharmony_ci if (rc) 885141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 886141cc406Sopenharmony_ci __FILE__, __LINE__); 887141cc406Sopenharmony_ci#ifdef IOLOG 888141cc406Sopenharmony_ci DBG (0, "outb DATA,%02X\n", value); 889141cc406Sopenharmony_ci#endif 890141cc406Sopenharmony_ci return; 891141cc406Sopenharmony_ci case 2: 892141cc406Sopenharmony_ci mode = val & 0x20; 893141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 894141cc406Sopenharmony_ci if (rc) 895141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", 896141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 897141cc406Sopenharmony_ci val = val & 0xDF; 898141cc406Sopenharmony_ci rc = ioctl (fd, PPWCONTROL, &val); 899141cc406Sopenharmony_ci if (rc) 900141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", 901141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 902141cc406Sopenharmony_ci#ifdef IOLOG 903141cc406Sopenharmony_ci DBG (0, "outb CONTROL,%02X\n", value); 904141cc406Sopenharmony_ci#endif 905141cc406Sopenharmony_ci return; 906141cc406Sopenharmony_ci case 4: 907141cc406Sopenharmony_ci rc = ioctl (fd, PPGETMODE, &exmode); 908141cc406Sopenharmony_ci if (rc) 909141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 910141cc406Sopenharmony_ci __FILE__, __LINE__); 911141cc406Sopenharmony_ci mode = 0; /* data forward */ 912141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 913141cc406Sopenharmony_ci if (rc) 914141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 915141cc406Sopenharmony_ci __FILE__, __LINE__); 916141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 917141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 918141cc406Sopenharmony_ci if (rc) 919141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 920141cc406Sopenharmony_ci __FILE__, __LINE__); 921141cc406Sopenharmony_ci rc = write (fd, &val, 1); 922141cc406Sopenharmony_ci if (rc != 1) 923141cc406Sopenharmony_ci DBG (0, "ppdev short write (%s:%d)\n", __FILE__, __LINE__); 924141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &exmode); 925141cc406Sopenharmony_ci if (rc) 926141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 927141cc406Sopenharmony_ci __FILE__, __LINE__); 928141cc406Sopenharmony_ci#ifdef IOLOG 929141cc406Sopenharmony_ci DBG (0, "outb EPPDATA,%02X\n", value); 930141cc406Sopenharmony_ci#endif 931141cc406Sopenharmony_ci return; 932141cc406Sopenharmony_ci case 3: 933141cc406Sopenharmony_ci rc = ioctl (fd, PPGETMODE, &exmode); 934141cc406Sopenharmony_ci if (rc) 935141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 936141cc406Sopenharmony_ci __FILE__, __LINE__); 937141cc406Sopenharmony_ci mode = 0; /* data forward */ 938141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 939141cc406Sopenharmony_ci if (rc) 940141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 941141cc406Sopenharmony_ci __FILE__, __LINE__); 942141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 943141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 944141cc406Sopenharmony_ci if (rc) 945141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 946141cc406Sopenharmony_ci __FILE__, __LINE__); 947141cc406Sopenharmony_ci rc = write (fd, &val, 1); 948141cc406Sopenharmony_ci if (rc != 1) 949141cc406Sopenharmony_ci DBG (0, "ppdev short write (%s:%d)\n", __FILE__, __LINE__); 950141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &exmode); 951141cc406Sopenharmony_ci if (rc) 952141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 953141cc406Sopenharmony_ci __FILE__, __LINE__); 954141cc406Sopenharmony_ci return; 955141cc406Sopenharmony_ci case 0x400: 956141cc406Sopenharmony_ci case 0x402: 957141cc406Sopenharmony_ci break; 958141cc406Sopenharmony_ci default: 959141cc406Sopenharmony_ci DBG (16, "Outb(0x%03X,0x%02X) escaped ppdev\n", port, value); 960141cc406Sopenharmony_ci return; 961141cc406Sopenharmony_ci } 962141cc406Sopenharmony_ci } 963141cc406Sopenharmony_ci#endif /* HAVE_LINUX_PPDEV_H */ 964141cc406Sopenharmony_ci 965141cc406Sopenharmony_ci 966141cc406Sopenharmony_ci#ifdef HAVE_DEV_PPBUS_PPI_H 967141cc406Sopenharmony_ci int fd, rc; 968141cc406Sopenharmony_ci unsigned char val; 969141cc406Sopenharmony_ci 970141cc406Sopenharmony_ci 971141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 972141cc406Sopenharmony_ci val = (unsigned char) value; 973141cc406Sopenharmony_ci if (fd > 0) 974141cc406Sopenharmony_ci { 975141cc406Sopenharmony_ci switch (port - gPort) 976141cc406Sopenharmony_ci { 977141cc406Sopenharmony_ci case 0: 978141cc406Sopenharmony_ci rc = ioctl (fd, PPISDATA, &val); 979141cc406Sopenharmony_ci if (rc) 980141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 981141cc406Sopenharmony_ci __FILE__, __LINE__); 982141cc406Sopenharmony_ci return; 983141cc406Sopenharmony_ci case 1: 984141cc406Sopenharmony_ci rc = ioctl (fd, PPISSTATUS, &val); 985141cc406Sopenharmony_ci if (rc) 986141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 987141cc406Sopenharmony_ci __FILE__, __LINE__); 988141cc406Sopenharmony_ci return; 989141cc406Sopenharmony_ci case 2: 990141cc406Sopenharmony_ci rc = ioctl (fd, PPISCTRL, &val); 991141cc406Sopenharmony_ci if (rc) 992141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 993141cc406Sopenharmony_ci __FILE__, __LINE__); 994141cc406Sopenharmony_ci return; 995141cc406Sopenharmony_ci case 3: 996141cc406Sopenharmony_ci rc = ioctl (fd, PPISEPPA, &val); 997141cc406Sopenharmony_ci if (rc) 998141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 999141cc406Sopenharmony_ci __FILE__, __LINE__); 1000141cc406Sopenharmony_ci return; 1001141cc406Sopenharmony_ci case 4: 1002141cc406Sopenharmony_ci rc = ioctl (fd, PPISEPPD, &val); 1003141cc406Sopenharmony_ci if (rc) 1004141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 1005141cc406Sopenharmony_ci __FILE__, __LINE__); 1006141cc406Sopenharmony_ci return; 1007141cc406Sopenharmony_ci case 0x402: 1008141cc406Sopenharmony_ci rc = ioctl (fd, PPISECR, &val); 1009141cc406Sopenharmony_ci if (rc) 1010141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 1011141cc406Sopenharmony_ci __FILE__, __LINE__); 1012141cc406Sopenharmony_ci return; 1013141cc406Sopenharmony_ci default: 1014141cc406Sopenharmony_ci DBG (16, "Outb(0x%03X,0x%02X) escaped ppi\n", port, value); 1015141cc406Sopenharmony_ci return; 1016141cc406Sopenharmony_ci } 1017141cc406Sopenharmony_ci } 1018141cc406Sopenharmony_ci#endif /* HAVE_DEV_PPBUS_PPI_H */ 1019141cc406Sopenharmony_ci 1020141cc406Sopenharmony_ci sanei_outb (port, value); 1021141cc406Sopenharmony_ci 1022141cc406Sopenharmony_ci#endif /* IO_SUPPORT_MISSING */ 1023141cc406Sopenharmony_ci} 1024141cc406Sopenharmony_ci 1025141cc406Sopenharmony_ci 1026141cc406Sopenharmony_ci 1027141cc406Sopenharmony_ci 1028141cc406Sopenharmony_ci 1029141cc406Sopenharmony_cistatic int 1030141cc406Sopenharmony_ciInb (int port) 1031141cc406Sopenharmony_ci{ 1032141cc406Sopenharmony_ci int res = 0xFF; 1033141cc406Sopenharmony_ci#ifndef IO_SUPPORT_MISSING 1034141cc406Sopenharmony_ci 1035141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 1036141cc406Sopenharmony_ci int fd, rc, mode; 1037141cc406Sopenharmony_ci unsigned char val; 1038141cc406Sopenharmony_ci 1039141cc406Sopenharmony_ci 1040141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 1041141cc406Sopenharmony_ci if (fd > 0) 1042141cc406Sopenharmony_ci { 1043141cc406Sopenharmony_ci /* there should be ECR that doesn't go through ppdev */ 1044141cc406Sopenharmony_ci /* it will leave when all the I/O will be done with ppdev */ 1045141cc406Sopenharmony_ci switch (port - gPort) 1046141cc406Sopenharmony_ci { 1047141cc406Sopenharmony_ci case 0: 1048141cc406Sopenharmony_ci rc = ioctl (fd, PPRDATA, &val); 1049141cc406Sopenharmony_ci if (rc) 1050141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 1051141cc406Sopenharmony_ci __FILE__, __LINE__); 1052141cc406Sopenharmony_ci res = val; 1053141cc406Sopenharmony_ci#ifdef IOLOG 1054141cc406Sopenharmony_ci DBG (0, "inb DATA,%02X\n", res); 1055141cc406Sopenharmony_ci#endif 1056141cc406Sopenharmony_ci return res; 1057141cc406Sopenharmony_ci 1058141cc406Sopenharmony_ci case 1: 1059141cc406Sopenharmony_ci rc = ioctl (fd, PPRSTATUS, &val); 1060141cc406Sopenharmony_ci if (rc) 1061141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 1062141cc406Sopenharmony_ci __FILE__, __LINE__); 1063141cc406Sopenharmony_ci res = val; 1064141cc406Sopenharmony_ci#ifdef IOLOG 1065141cc406Sopenharmony_ci DBG (0, "inb STATUS,%02X\n", res); 1066141cc406Sopenharmony_ci#endif 1067141cc406Sopenharmony_ci return res; 1068141cc406Sopenharmony_ci 1069141cc406Sopenharmony_ci case 2: 1070141cc406Sopenharmony_ci rc = ioctl (fd, PPRCONTROL, &val); 1071141cc406Sopenharmony_ci if (rc) 1072141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 1073141cc406Sopenharmony_ci __FILE__, __LINE__); 1074141cc406Sopenharmony_ci res = val; 1075141cc406Sopenharmony_ci#ifdef IOLOG 1076141cc406Sopenharmony_ci DBG (0, "inb CONTROL,%02X\n", res); 1077141cc406Sopenharmony_ci#endif 1078141cc406Sopenharmony_ci return res; 1079141cc406Sopenharmony_ci 1080141cc406Sopenharmony_ci case 4: 1081141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 1082141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 1083141cc406Sopenharmony_ci if (rc) 1084141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 1085141cc406Sopenharmony_ci __FILE__, __LINE__); 1086141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 1087141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 1088141cc406Sopenharmony_ci if (rc) 1089141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 1090141cc406Sopenharmony_ci __FILE__, __LINE__); 1091141cc406Sopenharmony_ci rc = read (fd, &val, 1); 1092141cc406Sopenharmony_ci if (rc != 1) 1093141cc406Sopenharmony_ci DBG (0, "ppdev short read (%s:%d)\n", __FILE__, __LINE__); 1094141cc406Sopenharmony_ci mode = 0; /* data_forward */ 1095141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 1096141cc406Sopenharmony_ci if (rc) 1097141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 1098141cc406Sopenharmony_ci __FILE__, __LINE__); 1099141cc406Sopenharmony_ci res = val; 1100141cc406Sopenharmony_ci#ifdef IOLOG 1101141cc406Sopenharmony_ci DBG (0, "inb EPPDATA,%02X\n", res); 1102141cc406Sopenharmony_ci#endif 1103141cc406Sopenharmony_ci return res; 1104141cc406Sopenharmony_ci case 0x400: 1105141cc406Sopenharmony_ci case 0x402: 1106141cc406Sopenharmony_ci default: 1107141cc406Sopenharmony_ci DBG (16, "Inb(0x%03X) escaped ppdev\n", port); 1108141cc406Sopenharmony_ci return 0xFF; 1109141cc406Sopenharmony_ci } 1110141cc406Sopenharmony_ci } 1111141cc406Sopenharmony_ci#endif /* HAVE_LINUX_PPDEV_H */ 1112141cc406Sopenharmony_ci 1113141cc406Sopenharmony_ci 1114141cc406Sopenharmony_ci#ifdef HAVE_DEV_PPBUS_PPI_H 1115141cc406Sopenharmony_ci int fd, rc; 1116141cc406Sopenharmony_ci unsigned char val; 1117141cc406Sopenharmony_ci 1118141cc406Sopenharmony_ci 1119141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 1120141cc406Sopenharmony_ci if (fd > 0) 1121141cc406Sopenharmony_ci { 1122141cc406Sopenharmony_ci switch (port - gPort) 1123141cc406Sopenharmony_ci { 1124141cc406Sopenharmony_ci case 0: 1125141cc406Sopenharmony_ci rc = ioctl (fd, PPIGDATA, &val); 1126141cc406Sopenharmony_ci if (rc) 1127141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 1128141cc406Sopenharmony_ci __FILE__, __LINE__); 1129141cc406Sopenharmony_ci res = val; 1130141cc406Sopenharmony_ci return res; 1131141cc406Sopenharmony_ci case 1: 1132141cc406Sopenharmony_ci rc = ioctl (fd, PPIGSTATUS, &val); 1133141cc406Sopenharmony_ci if (rc) 1134141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 1135141cc406Sopenharmony_ci __FILE__, __LINE__); 1136141cc406Sopenharmony_ci res = val; 1137141cc406Sopenharmony_ci return res; 1138141cc406Sopenharmony_ci case 2: 1139141cc406Sopenharmony_ci rc = ioctl (fd, PPIGCTRL, &val); 1140141cc406Sopenharmony_ci if (rc) 1141141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 1142141cc406Sopenharmony_ci __FILE__, __LINE__); 1143141cc406Sopenharmony_ci res = val; 1144141cc406Sopenharmony_ci return res; 1145141cc406Sopenharmony_ci case 3: 1146141cc406Sopenharmony_ci rc = ioctl (fd, PPIGEPPA, &val); 1147141cc406Sopenharmony_ci if (rc) 1148141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 1149141cc406Sopenharmony_ci __FILE__, __LINE__); 1150141cc406Sopenharmony_ci res = val; 1151141cc406Sopenharmony_ci return res; 1152141cc406Sopenharmony_ci case 4: 1153141cc406Sopenharmony_ci rc = ioctl (fd, PPIGEPPD, &val); 1154141cc406Sopenharmony_ci if (rc) 1155141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 1156141cc406Sopenharmony_ci __FILE__, __LINE__); 1157141cc406Sopenharmony_ci res = val; 1158141cc406Sopenharmony_ci return res; 1159141cc406Sopenharmony_ci case 0x402: 1160141cc406Sopenharmony_ci rc = ioctl (fd, PPIGECR, &val); 1161141cc406Sopenharmony_ci if (rc) 1162141cc406Sopenharmony_ci DBG (0, "ppi ioctl returned <%s> (%s:%d)\n", strerror (errno), 1163141cc406Sopenharmony_ci __FILE__, __LINE__); 1164141cc406Sopenharmony_ci res = val; 1165141cc406Sopenharmony_ci return res; 1166141cc406Sopenharmony_ci default: 1167141cc406Sopenharmony_ci DBG (16, "Inb(0x%03X) escaped ppi\n", port); 1168141cc406Sopenharmony_ci return 0xFF; 1169141cc406Sopenharmony_ci } 1170141cc406Sopenharmony_ci } 1171141cc406Sopenharmony_ci#endif /* HAVE_DEV_PPBUS_PPI_H */ 1172141cc406Sopenharmony_ci 1173141cc406Sopenharmony_ci res = sanei_inb (port); 1174141cc406Sopenharmony_ci 1175141cc406Sopenharmony_ci#endif /* IO_SUPPORT_MISSING */ 1176141cc406Sopenharmony_ci return res; 1177141cc406Sopenharmony_ci} 1178141cc406Sopenharmony_ci 1179141cc406Sopenharmony_ci 1180141cc406Sopenharmony_cistatic void 1181141cc406Sopenharmony_ciInsb (int port, unsigned char *dest, int size) 1182141cc406Sopenharmony_ci{ 1183141cc406Sopenharmony_ci#ifndef IO_SUPPORT_MISSING 1184141cc406Sopenharmony_ci 1185141cc406Sopenharmony_ci#ifdef HAVE_DEV_PPBUS_PPI_H 1186141cc406Sopenharmony_ci int i; 1187141cc406Sopenharmony_ci if (sanei_umax_pp_getparport () > 0) 1188141cc406Sopenharmony_ci { 1189141cc406Sopenharmony_ci for (i = 0; i < size; i++) 1190141cc406Sopenharmony_ci dest[i] = Inb (port); 1191141cc406Sopenharmony_ci return; 1192141cc406Sopenharmony_ci } 1193141cc406Sopenharmony_ci#endif /* HAVE_DEV_PPBUS_PPI_H */ 1194141cc406Sopenharmony_ci sanei_insb (port, dest, size); 1195141cc406Sopenharmony_ci 1196141cc406Sopenharmony_ci#endif 1197141cc406Sopenharmony_ci} 1198141cc406Sopenharmony_ci 1199141cc406Sopenharmony_cistatic void 1200141cc406Sopenharmony_ciOutsb (int port, unsigned char *source, int size) 1201141cc406Sopenharmony_ci{ 1202141cc406Sopenharmony_ci#ifndef IO_SUPPORT_MISSING 1203141cc406Sopenharmony_ci 1204141cc406Sopenharmony_ci#ifdef HAVE_DEV_PPBUS_PPI_H 1205141cc406Sopenharmony_ci int i; 1206141cc406Sopenharmony_ci 1207141cc406Sopenharmony_ci if (sanei_umax_pp_getparport () > 0) 1208141cc406Sopenharmony_ci { 1209141cc406Sopenharmony_ci for (i = 0; i < size; i++) 1210141cc406Sopenharmony_ci Outb (port, source[i]); 1211141cc406Sopenharmony_ci return; 1212141cc406Sopenharmony_ci } 1213141cc406Sopenharmony_ci#endif /* HAVE_DEV_PPBUS_PPI_H */ 1214141cc406Sopenharmony_ci 1215141cc406Sopenharmony_ci sanei_outsb (port, source, size); 1216141cc406Sopenharmony_ci 1217141cc406Sopenharmony_ci#endif 1218141cc406Sopenharmony_ci} 1219141cc406Sopenharmony_ci 1220141cc406Sopenharmony_ci 1221141cc406Sopenharmony_ci 1222141cc406Sopenharmony_ci/* size = nb words */ 1223141cc406Sopenharmony_cistatic void 1224141cc406Sopenharmony_ciInsw (int port, unsigned char *dest, int size) 1225141cc406Sopenharmony_ci{ 1226141cc406Sopenharmony_ci#ifndef IO_SUPPORT_MISSING 1227141cc406Sopenharmony_ci 1228141cc406Sopenharmony_ci#ifdef HAVE_DEV_PPBUS_PPI_H 1229141cc406Sopenharmony_ci int i; 1230141cc406Sopenharmony_ci 1231141cc406Sopenharmony_ci if (sanei_umax_pp_getparport () > 0) 1232141cc406Sopenharmony_ci { 1233141cc406Sopenharmony_ci for (i = 0; i < size * 4; i++) 1234141cc406Sopenharmony_ci dest[i] = Inb (port); 1235141cc406Sopenharmony_ci return; 1236141cc406Sopenharmony_ci } 1237141cc406Sopenharmony_ci#endif /* HAVE_DEV_PPBUS_PPI_H */ 1238141cc406Sopenharmony_ci 1239141cc406Sopenharmony_ci sanei_insl (port, dest, size); 1240141cc406Sopenharmony_ci 1241141cc406Sopenharmony_ci#endif 1242141cc406Sopenharmony_ci} 1243141cc406Sopenharmony_ci 1244141cc406Sopenharmony_cistatic void 1245141cc406Sopenharmony_ciOutsw (int port, unsigned char *source, int size) 1246141cc406Sopenharmony_ci{ 1247141cc406Sopenharmony_ci#ifndef IO_SUPPORT_MISSING 1248141cc406Sopenharmony_ci 1249141cc406Sopenharmony_ci#ifdef HAVE_DEV_PPBUS_PPI_H 1250141cc406Sopenharmony_ci int i; 1251141cc406Sopenharmony_ci 1252141cc406Sopenharmony_ci if (sanei_umax_pp_getparport () > 0) 1253141cc406Sopenharmony_ci { 1254141cc406Sopenharmony_ci for (i = 0; i < size * 4; i++) 1255141cc406Sopenharmony_ci Outb (port, source[i]); 1256141cc406Sopenharmony_ci return; 1257141cc406Sopenharmony_ci } 1258141cc406Sopenharmony_ci#endif /* HAVE_DEV_PPBUS_PPI_H */ 1259141cc406Sopenharmony_ci 1260141cc406Sopenharmony_ci sanei_outsl (port, source, size); 1261141cc406Sopenharmony_ci 1262141cc406Sopenharmony_ci#endif 1263141cc406Sopenharmony_ci} 1264141cc406Sopenharmony_ci 1265141cc406Sopenharmony_ci 1266141cc406Sopenharmony_ci/* we're trying to gather information on the scanner here, */ 1267141cc406Sopenharmony_ci/* and published it through an easy interface */ 1268141cc406Sopenharmony_ci/* will turn it into a struct when 610P code will be done */ 1269141cc406Sopenharmony_cistatic int scannerStatus = 0; 1270141cc406Sopenharmony_cistatic time_t gTime = 0; 1271141cc406Sopenharmony_cistatic time_t gDelay = 0; 1272141cc406Sopenharmony_cistatic int epp32 = 1; 1273141cc406Sopenharmony_cistatic int gMode = 0; 1274141cc406Sopenharmony_cistatic int gprobed = 0; 1275141cc406Sopenharmony_cistatic int model = 0x15; 1276141cc406Sopenharmony_cistatic int astra = 0; 1277141cc406Sopenharmony_cistatic int hasUTA = 0; 1278141cc406Sopenharmony_ci 1279141cc406Sopenharmony_ci/* signals that scan width matches full ccd width */ 1280141cc406Sopenharmony_cistatic int fullCCDWidth = 0; 1281141cc406Sopenharmony_ci 1282141cc406Sopenharmony_ciint 1283141cc406Sopenharmony_cisanei_umax_pp_getfull (void) 1284141cc406Sopenharmony_ci{ 1285141cc406Sopenharmony_ci return fullCCDWidth; 1286141cc406Sopenharmony_ci} 1287141cc406Sopenharmony_ci 1288141cc406Sopenharmony_civoid 1289141cc406Sopenharmony_cisanei_umax_pp_setfull (int mod) 1290141cc406Sopenharmony_ci{ 1291141cc406Sopenharmony_ci fullCCDWidth = mod; 1292141cc406Sopenharmony_ci} 1293141cc406Sopenharmony_ci 1294141cc406Sopenharmony_ci 1295141cc406Sopenharmony_ciint 1296141cc406Sopenharmony_cisanei_umax_pp_UTA (void) 1297141cc406Sopenharmony_ci{ 1298141cc406Sopenharmony_ci return hasUTA; 1299141cc406Sopenharmony_ci} 1300141cc406Sopenharmony_ci 1301141cc406Sopenharmony_ciint 1302141cc406Sopenharmony_cisanei_umax_pp_scannerStatus (void) 1303141cc406Sopenharmony_ci{ 1304141cc406Sopenharmony_ci struct timeval tv; 1305141cc406Sopenharmony_ci 1306141cc406Sopenharmony_ci /* the 610P ASIC needs some time to settle down after probe */ 1307141cc406Sopenharmony_ci if ((gTime > 0) && (gDelay > 0)) 1308141cc406Sopenharmony_ci { 1309141cc406Sopenharmony_ci gettimeofday (&tv, NULL); 1310141cc406Sopenharmony_ci /* delay elapsed ? */ 1311141cc406Sopenharmony_ci if (tv.tv_sec - gTime < gDelay) 1312141cc406Sopenharmony_ci /* still waiting */ 1313141cc406Sopenharmony_ci return ASIC_BIT; 1314141cc406Sopenharmony_ci /* wait finished */ 1315141cc406Sopenharmony_ci gDelay = 0; 1316141cc406Sopenharmony_ci gTime = 0; 1317141cc406Sopenharmony_ci } 1318141cc406Sopenharmony_ci 1319141cc406Sopenharmony_ci /* 0x07 variant returns status with bit 0 or 1 always set to 1 */ 1320141cc406Sopenharmony_ci /* so we mask it out */ 1321141cc406Sopenharmony_ci return scannerStatus & 0xFC; 1322141cc406Sopenharmony_ci} 1323141cc406Sopenharmony_ci 1324141cc406Sopenharmony_cistatic int 1325141cc406Sopenharmony_cigetEPPMode (void) 1326141cc406Sopenharmony_ci{ 1327141cc406Sopenharmony_ci if (epp32) 1328141cc406Sopenharmony_ci return 32; 1329141cc406Sopenharmony_ci return 8; 1330141cc406Sopenharmony_ci} 1331141cc406Sopenharmony_ci 1332141cc406Sopenharmony_cistatic void 1333141cc406Sopenharmony_cisetEPPMode (int mode) 1334141cc406Sopenharmony_ci{ 1335141cc406Sopenharmony_ci if (mode == 8) 1336141cc406Sopenharmony_ci epp32 = 0; 1337141cc406Sopenharmony_ci else 1338141cc406Sopenharmony_ci epp32 = 1; 1339141cc406Sopenharmony_ci} 1340141cc406Sopenharmony_ci 1341141cc406Sopenharmony_cistatic int 1342141cc406Sopenharmony_cigetModel (void) 1343141cc406Sopenharmony_ci{ 1344141cc406Sopenharmony_ci return model; 1345141cc406Sopenharmony_ci} 1346141cc406Sopenharmony_ci 1347141cc406Sopenharmony_cistatic void 1348141cc406Sopenharmony_cisetModel (int mod) 1349141cc406Sopenharmony_ci{ 1350141cc406Sopenharmony_ci model = mod; 1351141cc406Sopenharmony_ci} 1352141cc406Sopenharmony_ci 1353141cc406Sopenharmony_ci 1354141cc406Sopenharmony_ciint 1355141cc406Sopenharmony_cisanei_umax_pp_getparport (void) 1356141cc406Sopenharmony_ci{ 1357141cc406Sopenharmony_ci return gParport; 1358141cc406Sopenharmony_ci} 1359141cc406Sopenharmony_ci 1360141cc406Sopenharmony_civoid 1361141cc406Sopenharmony_cisanei_umax_pp_setparport (int fd) 1362141cc406Sopenharmony_ci{ 1363141cc406Sopenharmony_ci gParport = fd; 1364141cc406Sopenharmony_ci} 1365141cc406Sopenharmony_ci 1366141cc406Sopenharmony_ciint 1367141cc406Sopenharmony_cisanei_umax_pp_getport (void) 1368141cc406Sopenharmony_ci{ 1369141cc406Sopenharmony_ci return gPort; 1370141cc406Sopenharmony_ci} 1371141cc406Sopenharmony_ci 1372141cc406Sopenharmony_civoid 1373141cc406Sopenharmony_cisanei_umax_pp_setport (int port) 1374141cc406Sopenharmony_ci{ 1375141cc406Sopenharmony_ci gPort = port; 1376141cc406Sopenharmony_ci} 1377141cc406Sopenharmony_ci 1378141cc406Sopenharmony_ciint 1379141cc406Sopenharmony_cisanei_umax_pp_getastra (void) 1380141cc406Sopenharmony_ci{ 1381141cc406Sopenharmony_ci return astra; 1382141cc406Sopenharmony_ci} 1383141cc406Sopenharmony_ci 1384141cc406Sopenharmony_civoid 1385141cc406Sopenharmony_cisanei_umax_pp_setastra (int mod) 1386141cc406Sopenharmony_ci{ 1387141cc406Sopenharmony_ci astra = mod; 1388141cc406Sopenharmony_ci} 1389141cc406Sopenharmony_ci 1390141cc406Sopenharmony_ciint 1391141cc406Sopenharmony_cisanei_umax_pp_getLeft (void) 1392141cc406Sopenharmony_ci{ 1393141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 1394141cc406Sopenharmony_ci { 1395141cc406Sopenharmony_ci case 610: 1396141cc406Sopenharmony_ci return 92; 1397141cc406Sopenharmony_ci default: 1398141cc406Sopenharmony_ci return 144; 1399141cc406Sopenharmony_ci } 1400141cc406Sopenharmony_ci} 1401141cc406Sopenharmony_ci 1402141cc406Sopenharmony_civoid 1403141cc406Sopenharmony_cisanei_umax_pp_setLeft (int mod) 1404141cc406Sopenharmony_ci{ 1405141cc406Sopenharmony_ci gLeft = mod; 1406141cc406Sopenharmony_ci} 1407141cc406Sopenharmony_ci 1408141cc406Sopenharmony_ciint 1409141cc406Sopenharmony_cisanei_umax_pp_getauto (void) 1410141cc406Sopenharmony_ci{ 1411141cc406Sopenharmony_ci return gAutoSettings; 1412141cc406Sopenharmony_ci} 1413141cc406Sopenharmony_ci 1414141cc406Sopenharmony_civoid 1415141cc406Sopenharmony_cisanei_umax_pp_setauto (int autoset) 1416141cc406Sopenharmony_ci{ 1417141cc406Sopenharmony_ci gAutoSettings = autoset; 1418141cc406Sopenharmony_ci} 1419141cc406Sopenharmony_ci 1420141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 1421141cc406Sopenharmony_ci/* set to the parallel port needed using ppdev 1422141cc406Sopenharmony_ci * returns 1 if ok, 0 else 1423141cc406Sopenharmony_ci */ 1424141cc406Sopenharmony_cistatic int 1425141cc406Sopenharmony_cippdev_set_mode (int mode) 1426141cc406Sopenharmony_ci{ 1427141cc406Sopenharmony_ci int fd, rc; 1428141cc406Sopenharmony_ci 1429141cc406Sopenharmony_ci /* check we have ppdev working */ 1430141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 1431141cc406Sopenharmony_ci if (fd > 0) 1432141cc406Sopenharmony_ci { 1433141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 1434141cc406Sopenharmony_ci if (rc) 1435141cc406Sopenharmony_ci { 1436141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 1437141cc406Sopenharmony_ci __FILE__, __LINE__); 1438141cc406Sopenharmony_ci return 0; 1439141cc406Sopenharmony_ci } 1440141cc406Sopenharmony_ci return 1; 1441141cc406Sopenharmony_ci } 1442141cc406Sopenharmony_ci return 0; 1443141cc406Sopenharmony_ci} 1444141cc406Sopenharmony_ci#endif 1445141cc406Sopenharmony_ci 1446141cc406Sopenharmony_ci/* set parallel port mode to 'compatible'*/ 1447141cc406Sopenharmony_cistatic void 1448141cc406Sopenharmony_cicompatMode (void) 1449141cc406Sopenharmony_ci{ 1450141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 1451141cc406Sopenharmony_ci if (ppdev_set_mode (IEEE1284_MODE_COMPAT)) 1452141cc406Sopenharmony_ci return; 1453141cc406Sopenharmony_ci#endif 1454141cc406Sopenharmony_ci if (!gECP) 1455141cc406Sopenharmony_ci return; 1456141cc406Sopenharmony_ci Outb (ECR, 0x15); 1457141cc406Sopenharmony_ci} 1458141cc406Sopenharmony_ci 1459141cc406Sopenharmony_ci/* set parallel port mode to 'bidirectionel'*/ 1460141cc406Sopenharmony_cistatic void 1461141cc406Sopenharmony_cibyteMode (void) 1462141cc406Sopenharmony_ci{ 1463141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 1464141cc406Sopenharmony_ci if (ppdev_set_mode (IEEE1284_MODE_BYTE)) 1465141cc406Sopenharmony_ci return; 1466141cc406Sopenharmony_ci#endif 1467141cc406Sopenharmony_ci if (!gECP) 1468141cc406Sopenharmony_ci return; 1469141cc406Sopenharmony_ci Outb (ECR, 0x35); /* or 0x34 */ 1470141cc406Sopenharmony_ci} 1471141cc406Sopenharmony_ci 1472141cc406Sopenharmony_ci/* set parallel port mode to 'fifo'*/ 1473141cc406Sopenharmony_cistatic void 1474141cc406Sopenharmony_ciECPFifoMode (void) 1475141cc406Sopenharmony_ci{ 1476141cc406Sopenharmony_ci /* bits 7:5 : 1477141cc406Sopenharmony_ci 000 Standard Mode 1478141cc406Sopenharmony_ci 001 Byte Mode 1479141cc406Sopenharmony_ci 010 Parallel Port FIFO Mode 1480141cc406Sopenharmony_ci 011 ECP FIFO Mode 1481141cc406Sopenharmony_ci 100 EPP Mode 1482141cc406Sopenharmony_ci 101 Reserved 1483141cc406Sopenharmony_ci 110 FIFO Test Mode 1484141cc406Sopenharmony_ci 111 Configuration Mode 1485141cc406Sopenharmony_ci */ 1486141cc406Sopenharmony_ci /* logged as 74/75 */ 1487141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 1488141cc406Sopenharmony_ci if (ppdev_set_mode (IEEE1284_MODE_ECP)) 1489141cc406Sopenharmony_ci return; 1490141cc406Sopenharmony_ci#endif 1491141cc406Sopenharmony_ci if (!gECP) 1492141cc406Sopenharmony_ci return; 1493141cc406Sopenharmony_ci Outb (ECR, 0x75); 1494141cc406Sopenharmony_ci} 1495141cc406Sopenharmony_ci 1496141cc406Sopenharmony_ci/* wait for ack bit */ 1497141cc406Sopenharmony_ci/* return 1 on success, 0 on error */ 1498141cc406Sopenharmony_cistatic int 1499141cc406Sopenharmony_ciwaitAck () 1500141cc406Sopenharmony_ci{ 1501141cc406Sopenharmony_ci unsigned char breg = 0; 1502141cc406Sopenharmony_ci int i = 0; 1503141cc406Sopenharmony_ci 1504141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); /* select printer + initialize printer */ 1505141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 1506141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 1507141cc406Sopenharmony_ci breg = Inb (STATUS) & 0xF8; 1508141cc406Sopenharmony_ci while ((i < 1024) && ((breg & 0x04) == 0)) 1509141cc406Sopenharmony_ci { 1510141cc406Sopenharmony_ci Outb (CONTROL, 0x0E); /* autolinefeed ?.. */ 1511141cc406Sopenharmony_ci Outb (CONTROL, 0x0E); 1512141cc406Sopenharmony_ci Outb (CONTROL, 0x0E); 1513141cc406Sopenharmony_ci breg = Inb (STATUS) & 0xF8; 1514141cc406Sopenharmony_ci i++; 1515141cc406Sopenharmony_ci usleep (1000); 1516141cc406Sopenharmony_ci } 1517141cc406Sopenharmony_ci if (i == 1024) 1518141cc406Sopenharmony_ci { 1519141cc406Sopenharmony_ci DBG (1, "waitAck failed, time-out waiting for Ack (%s:%d)\n", 1520141cc406Sopenharmony_ci __FILE__, __LINE__); 1521141cc406Sopenharmony_ci /* return 0; seems to be non-blocking ... */ 1522141cc406Sopenharmony_ci } 1523141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* printer reset */ 1524141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1525141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1526141cc406Sopenharmony_ci return 1; 1527141cc406Sopenharmony_ci} 1528141cc406Sopenharmony_ci 1529141cc406Sopenharmony_cistatic int 1530141cc406Sopenharmony_ciwaitFifoEmpty (void) 1531141cc406Sopenharmony_ci{ 1532141cc406Sopenharmony_ci int i; 1533141cc406Sopenharmony_ci unsigned char breg; 1534141cc406Sopenharmony_ci 1535141cc406Sopenharmony_ci breg = Inb (ECR); 1536141cc406Sopenharmony_ci i = 0; 1537141cc406Sopenharmony_ci while ((i < FIFO_WAIT) && ((breg & 0x01) == 0)) 1538141cc406Sopenharmony_ci { 1539141cc406Sopenharmony_ci breg = Inb (ECR); 1540141cc406Sopenharmony_ci i++; 1541141cc406Sopenharmony_ci } 1542141cc406Sopenharmony_ci if (i == FIFO_WAIT) 1543141cc406Sopenharmony_ci { 1544141cc406Sopenharmony_ci DBG (0, "waitFifoEmpty failed, time-out waiting for FIFO (%s:%d)\n", 1545141cc406Sopenharmony_ci __FILE__, __LINE__); 1546141cc406Sopenharmony_ci return 0; 1547141cc406Sopenharmony_ci } 1548141cc406Sopenharmony_ci return 1; 1549141cc406Sopenharmony_ci} 1550141cc406Sopenharmony_ci 1551141cc406Sopenharmony_cistatic int 1552141cc406Sopenharmony_ciwaitFifoNotEmpty (void) 1553141cc406Sopenharmony_ci{ 1554141cc406Sopenharmony_ci int i; 1555141cc406Sopenharmony_ci unsigned char breg; 1556141cc406Sopenharmony_ci 1557141cc406Sopenharmony_ci breg = Inb (ECR); 1558141cc406Sopenharmony_ci i = 0; 1559141cc406Sopenharmony_ci while ((i < FIFO_WAIT) && ((breg & 0x01) != 0)) 1560141cc406Sopenharmony_ci { 1561141cc406Sopenharmony_ci breg = Inb (ECR); 1562141cc406Sopenharmony_ci i++; 1563141cc406Sopenharmony_ci /* usleep (2000); */ 1564141cc406Sopenharmony_ci } 1565141cc406Sopenharmony_ci if (i == FIFO_WAIT) 1566141cc406Sopenharmony_ci { 1567141cc406Sopenharmony_ci DBG (0, "waitFifoNotEmpty failed, time-out waiting for FIFO (%s:%d)\n", 1568141cc406Sopenharmony_ci __FILE__, __LINE__); 1569141cc406Sopenharmony_ci return 0; 1570141cc406Sopenharmony_ci } 1571141cc406Sopenharmony_ci return 1; 1572141cc406Sopenharmony_ci} 1573141cc406Sopenharmony_ci 1574141cc406Sopenharmony_ci 1575141cc406Sopenharmony_cistatic int 1576141cc406Sopenharmony_ciwaitFifoFull (void) 1577141cc406Sopenharmony_ci{ 1578141cc406Sopenharmony_ci int i; 1579141cc406Sopenharmony_ci unsigned char breg; 1580141cc406Sopenharmony_ci 1581141cc406Sopenharmony_ci breg = Inb (ECR); 1582141cc406Sopenharmony_ci 1583141cc406Sopenharmony_ci /* two wait loop */ 1584141cc406Sopenharmony_ci /* the first apply to fast data transfer (ie when no scaaning is undergoing) */ 1585141cc406Sopenharmony_ci /* and we fallback to the second in case the scanner is answering slowly */ 1586141cc406Sopenharmony_ci i = 0; 1587141cc406Sopenharmony_ci while ((i < FIFO_WAIT) && ((breg & 0x02) == 0)) 1588141cc406Sopenharmony_ci { 1589141cc406Sopenharmony_ci breg = Inb (ECR); 1590141cc406Sopenharmony_ci i++; 1591141cc406Sopenharmony_ci } 1592141cc406Sopenharmony_ci /* don't need to wait any longer */ 1593141cc406Sopenharmony_ci if (i < FIFO_WAIT) 1594141cc406Sopenharmony_ci return 1; 1595141cc406Sopenharmony_ci i = 0; 1596141cc406Sopenharmony_ci while ((i < FIFO_WAIT) && ((breg & 0x02) == 0)) 1597141cc406Sopenharmony_ci { 1598141cc406Sopenharmony_ci breg = Inb (ECR); 1599141cc406Sopenharmony_ci i++; 1600141cc406Sopenharmony_ci usleep (500); 1601141cc406Sopenharmony_ci } 1602141cc406Sopenharmony_ci if (i == FIFO_WAIT) 1603141cc406Sopenharmony_ci { 1604141cc406Sopenharmony_ci DBG (0, "waitFifoFull failed, time-out waiting for FIFO (%s:%d)\n", 1605141cc406Sopenharmony_ci __FILE__, __LINE__); 1606141cc406Sopenharmony_ci return 0; 1607141cc406Sopenharmony_ci } 1608141cc406Sopenharmony_ci return 1; 1609141cc406Sopenharmony_ci} 1610141cc406Sopenharmony_ci 1611141cc406Sopenharmony_ci/* 1612141cc406Sopenharmony_ci * surely some register reading in PS2 mode 1613141cc406Sopenharmony_ci * only one nibble is accessed, may be 1614141cc406Sopenharmony_ci * PS2RegisterLowNibbleRead(reg) 1615141cc406Sopenharmony_ci */ 1616141cc406Sopenharmony_cistatic int 1617141cc406Sopenharmony_ciPS2Something (int reg) 1618141cc406Sopenharmony_ci{ 1619141cc406Sopenharmony_ci unsigned char breg, low, high = 0; 1620141cc406Sopenharmony_ci 1621141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1622141cc406Sopenharmony_ci Outb (DATA, reg); /* register number ? */ 1623141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 1624141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 1625141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 1626141cc406Sopenharmony_ci breg = Inb (STATUS) & 0xF8; 1627141cc406Sopenharmony_ci low = breg; 1628141cc406Sopenharmony_ci breg = breg & 0x08; 1629141cc406Sopenharmony_ci /* surely means register(0x10)=0x0B */ 1630141cc406Sopenharmony_ci /* since reg & 0x08 != 0, high and low nibble 1631141cc406Sopenharmony_ci * differ, but we don't care, since we surely expect it 1632141cc406Sopenharmony_ci * to be 0 1633141cc406Sopenharmony_ci */ 1634141cc406Sopenharmony_ci if (breg != 0x08) 1635141cc406Sopenharmony_ci { 1636141cc406Sopenharmony_ci DBG (0, "PS2Something failed, expecting 0x08, got 0x%02X (%s:%d)\n", 1637141cc406Sopenharmony_ci breg, __FILE__, __LINE__); 1638141cc406Sopenharmony_ci } 1639141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 1640141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 1641141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 1642141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 1643141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 1644141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1645141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1646141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1647141cc406Sopenharmony_ci if (breg != 0x08) 1648141cc406Sopenharmony_ci high = Inb (STATUS) & 0xF0; 1649141cc406Sopenharmony_ci return high + ((low & 0xF0) >> 4); 1650141cc406Sopenharmony_ci} 1651141cc406Sopenharmony_ci 1652141cc406Sopenharmony_cistatic int 1653141cc406Sopenharmony_ciPS2Read (void) 1654141cc406Sopenharmony_ci{ 1655141cc406Sopenharmony_ci int res; 1656141cc406Sopenharmony_ci int tmp; 1657141cc406Sopenharmony_ci 1658141cc406Sopenharmony_ci res = Inb (STATUS); 1659141cc406Sopenharmony_ci res = Inb (STATUS); 1660141cc406Sopenharmony_ci res = res & 0xF0; 1661141cc406Sopenharmony_ci Outb (CONTROL, 5); 1662141cc406Sopenharmony_ci Outb (CONTROL, 5); 1663141cc406Sopenharmony_ci Outb (CONTROL, 5); 1664141cc406Sopenharmony_ci Outb (CONTROL, 5); 1665141cc406Sopenharmony_ci Outb (CONTROL, 5); 1666141cc406Sopenharmony_ci Outb (CONTROL, 5); 1667141cc406Sopenharmony_ci Outb (CONTROL, 4); 1668141cc406Sopenharmony_ci Outb (CONTROL, 4); 1669141cc406Sopenharmony_ci Outb (CONTROL, 4); 1670141cc406Sopenharmony_ci Outb (CONTROL, 4); 1671141cc406Sopenharmony_ci Outb (CONTROL, 4); 1672141cc406Sopenharmony_ci Outb (CONTROL, 4); 1673141cc406Sopenharmony_ci 1674141cc406Sopenharmony_ci tmp = Inb (STATUS); 1675141cc406Sopenharmony_ci tmp = Inb (STATUS); 1676141cc406Sopenharmony_ci tmp = (tmp & 0xF0) >> 4; 1677141cc406Sopenharmony_ci res = res | tmp; 1678141cc406Sopenharmony_ci Outb (CONTROL, 5); 1679141cc406Sopenharmony_ci Outb (CONTROL, 5); 1680141cc406Sopenharmony_ci Outb (CONTROL, 5); 1681141cc406Sopenharmony_ci Outb (CONTROL, 5); 1682141cc406Sopenharmony_ci Outb (CONTROL, 5); 1683141cc406Sopenharmony_ci Outb (CONTROL, 5); 1684141cc406Sopenharmony_ci Outb (CONTROL, 4); 1685141cc406Sopenharmony_ci Outb (CONTROL, 4); 1686141cc406Sopenharmony_ci Outb (CONTROL, 4); 1687141cc406Sopenharmony_ci Outb (CONTROL, 4); 1688141cc406Sopenharmony_ci Outb (CONTROL, 4); 1689141cc406Sopenharmony_ci Outb (CONTROL, 4); 1690141cc406Sopenharmony_ci 1691141cc406Sopenharmony_ci return res; 1692141cc406Sopenharmony_ci} 1693141cc406Sopenharmony_ci 1694141cc406Sopenharmony_ci 1695141cc406Sopenharmony_ci/******************************************************************************/ 1696141cc406Sopenharmony_ci/* PS2registerWrite: write value in register, slow method */ 1697141cc406Sopenharmony_ci/******************************************************************************/ 1698141cc406Sopenharmony_cistatic void 1699141cc406Sopenharmony_ciPS2registerWrite (int reg, int value) 1700141cc406Sopenharmony_ci{ 1701141cc406Sopenharmony_ci /* select register */ 1702141cc406Sopenharmony_ci Outb (DATA, reg | 0x60); 1703141cc406Sopenharmony_ci Outb (DATA, reg | 0x60); 1704141cc406Sopenharmony_ci Outb (CONTROL, 0x01); 1705141cc406Sopenharmony_ci Outb (CONTROL, 0x01); 1706141cc406Sopenharmony_ci Outb (CONTROL, 0x01); 1707141cc406Sopenharmony_ci 1708141cc406Sopenharmony_ci /* send value */ 1709141cc406Sopenharmony_ci Outb (DATA, value); 1710141cc406Sopenharmony_ci Outb (DATA, value); 1711141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1712141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1713141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1714141cc406Sopenharmony_ci} 1715141cc406Sopenharmony_ci 1716141cc406Sopenharmony_ci 1717141cc406Sopenharmony_ci 1718141cc406Sopenharmony_ci/*****************************************************************************/ 1719141cc406Sopenharmony_ci/* Send command returns 0 on failure, 1 on success */ 1720141cc406Sopenharmony_ci/*****************************************************************************/ 1721141cc406Sopenharmony_cistatic int 1722141cc406Sopenharmony_cisendCommand (int cmd) 1723141cc406Sopenharmony_ci{ 1724141cc406Sopenharmony_ci int control; 1725141cc406Sopenharmony_ci int tmp; 1726141cc406Sopenharmony_ci int val; 1727141cc406Sopenharmony_ci int i; 1728141cc406Sopenharmony_ci 1729141cc406Sopenharmony_ci if (g674 != 0) 1730141cc406Sopenharmony_ci { 1731141cc406Sopenharmony_ci DBG (0, "No scanner attached, sendCommand(0x%X) failed\n", cmd); 1732141cc406Sopenharmony_ci return 0; 1733141cc406Sopenharmony_ci } 1734141cc406Sopenharmony_ci 1735141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 1736141cc406Sopenharmony_ci tmp = cmd & 0xF8; 1737141cc406Sopenharmony_ci 1738141cc406Sopenharmony_ci 1739141cc406Sopenharmony_ci if ((g67D != 1) && (tmp != 0xE0) && (tmp != 0x20) && (tmp != 0x40) 1740141cc406Sopenharmony_ci && (tmp != 0xD0) && (tmp != 0x08) && (tmp != 0x48)) 1741141cc406Sopenharmony_ci { 1742141cc406Sopenharmony_ci Outb (CONTROL, 4); /* reset printer */ 1743141cc406Sopenharmony_ci } 1744141cc406Sopenharmony_ci else 1745141cc406Sopenharmony_ci { 1746141cc406Sopenharmony_ci val = control & 0x1F; 1747141cc406Sopenharmony_ci if (g67D != 1) 1748141cc406Sopenharmony_ci val = val & 0xF; /* no IRQ */ 1749141cc406Sopenharmony_ci val = val | 0x4; 1750141cc406Sopenharmony_ci Outb (CONTROL, val); 1751141cc406Sopenharmony_ci Outb (CONTROL, val); 1752141cc406Sopenharmony_ci } 1753141cc406Sopenharmony_ci 1754141cc406Sopenharmony_ci /* send sequence */ 1755141cc406Sopenharmony_ci Outb (DATA, 0x22); 1756141cc406Sopenharmony_ci Outb (DATA, 0x22); 1757141cc406Sopenharmony_ci Outb (DATA, 0xAA); 1758141cc406Sopenharmony_ci Outb (DATA, 0xAA); 1759141cc406Sopenharmony_ci Outb (DATA, 0x55); 1760141cc406Sopenharmony_ci Outb (DATA, 0x55); 1761141cc406Sopenharmony_ci Outb (DATA, 0x00); 1762141cc406Sopenharmony_ci Outb (DATA, 0x00); 1763141cc406Sopenharmony_ci Outb (DATA, 0xFF); 1764141cc406Sopenharmony_ci Outb (DATA, 0xFF); 1765141cc406Sopenharmony_ci Outb (DATA, 0x87); 1766141cc406Sopenharmony_ci Outb (DATA, 0x87); 1767141cc406Sopenharmony_ci Outb (DATA, 0x78); 1768141cc406Sopenharmony_ci Outb (DATA, 0x78); 1769141cc406Sopenharmony_ci Outb (DATA, cmd); 1770141cc406Sopenharmony_ci Outb (DATA, cmd); 1771141cc406Sopenharmony_ci 1772141cc406Sopenharmony_ci cmd = cmd & 0xF8; 1773141cc406Sopenharmony_ci 1774141cc406Sopenharmony_ci if ((g67D == 1) && (cmd == 0xE0)) 1775141cc406Sopenharmony_ci { 1776141cc406Sopenharmony_ci val = Inb (CONTROL); 1777141cc406Sopenharmony_ci val = (val & 0xC) | 0x01; 1778141cc406Sopenharmony_ci Outb (CONTROL, val); 1779141cc406Sopenharmony_ci Outb (CONTROL, val); 1780141cc406Sopenharmony_ci val = val & 0xC; 1781141cc406Sopenharmony_ci Outb (CONTROL, val); 1782141cc406Sopenharmony_ci Outb (CONTROL, val); 1783141cc406Sopenharmony_ci goto sendCommandEnd; 1784141cc406Sopenharmony_ci } 1785141cc406Sopenharmony_ci 1786141cc406Sopenharmony_ci if ((cmd != 8) && (cmd != 0x48)) 1787141cc406Sopenharmony_ci { 1788141cc406Sopenharmony_ci tmp = Inb (CONTROL); 1789141cc406Sopenharmony_ci tmp = Inb (CONTROL); 1790141cc406Sopenharmony_ci tmp = tmp & 0x1E; 1791141cc406Sopenharmony_ci if (g67D != 1) 1792141cc406Sopenharmony_ci tmp = tmp & 0xE; 1793141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1794141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1795141cc406Sopenharmony_ci } 1796141cc406Sopenharmony_ci 1797141cc406Sopenharmony_ci if (cmd == 0x10) 1798141cc406Sopenharmony_ci { 1799141cc406Sopenharmony_ci tmp = PS2Read (); 1800141cc406Sopenharmony_ci tmp = tmp * 256 + PS2Read (); 1801141cc406Sopenharmony_ci goto sendCommandEnd; 1802141cc406Sopenharmony_ci } 1803141cc406Sopenharmony_ci 1804141cc406Sopenharmony_ci if (cmd == 8) 1805141cc406Sopenharmony_ci { 1806141cc406Sopenharmony_ci if (g67D == 1) 1807141cc406Sopenharmony_ci { 1808141cc406Sopenharmony_ci i = 0; 1809141cc406Sopenharmony_ci while (i < g67E) 1810141cc406Sopenharmony_ci { 1811141cc406Sopenharmony_ci tmp = Inb (CONTROL); 1812141cc406Sopenharmony_ci tmp = Inb (CONTROL); 1813141cc406Sopenharmony_ci tmp = (tmp & 0x1E) | 0x1; 1814141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1815141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1816141cc406Sopenharmony_ci Inb (STATUS); 1817141cc406Sopenharmony_ci tmp = tmp & 0x1E; 1818141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1819141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1820141cc406Sopenharmony_ci 1821141cc406Sopenharmony_ci /* next read */ 1822141cc406Sopenharmony_ci i++; 1823141cc406Sopenharmony_ci if (i < g67E) 1824141cc406Sopenharmony_ci { 1825141cc406Sopenharmony_ci Outb (DATA, i | 8); 1826141cc406Sopenharmony_ci Outb (DATA, i | 8); 1827141cc406Sopenharmony_ci } 1828141cc406Sopenharmony_ci } 1829141cc406Sopenharmony_ci goto sendCommandEnd; 1830141cc406Sopenharmony_ci } 1831141cc406Sopenharmony_ci else 1832141cc406Sopenharmony_ci { 1833141cc406Sopenharmony_ci DBG (0, "UNEXPLORED BRANCH %s:%d\n", __FILE__, __LINE__); 1834141cc406Sopenharmony_ci return 0; 1835141cc406Sopenharmony_ci } 1836141cc406Sopenharmony_ci } 1837141cc406Sopenharmony_ci 1838141cc406Sopenharmony_ci /* */ 1839141cc406Sopenharmony_ci if (cmd == 0) 1840141cc406Sopenharmony_ci { 1841141cc406Sopenharmony_ci i = 0; 1842141cc406Sopenharmony_ci do 1843141cc406Sopenharmony_ci { 1844141cc406Sopenharmony_ci tmp = Inb (CONTROL); 1845141cc406Sopenharmony_ci tmp = (tmp & 0xE) | 0x1; 1846141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1847141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1848141cc406Sopenharmony_ci tmp = tmp & 0xE; 1849141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1850141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1851141cc406Sopenharmony_ci 1852141cc406Sopenharmony_ci i++; 1853141cc406Sopenharmony_ci if (i < g67E) 1854141cc406Sopenharmony_ci { 1855141cc406Sopenharmony_ci Outb (DATA, i); 1856141cc406Sopenharmony_ci Outb (DATA, i); 1857141cc406Sopenharmony_ci } 1858141cc406Sopenharmony_ci } 1859141cc406Sopenharmony_ci while (i < g67E); 1860141cc406Sopenharmony_ci goto sendCommandEnd; 1861141cc406Sopenharmony_ci } 1862141cc406Sopenharmony_ci 1863141cc406Sopenharmony_ci if (cmd == 0x48) 1864141cc406Sopenharmony_ci { 1865141cc406Sopenharmony_ci /* this case is unneeded, should fit with the rest */ 1866141cc406Sopenharmony_ci tmp = Inb (CONTROL) & 0x1E; 1867141cc406Sopenharmony_ci if (g67D != 1) 1868141cc406Sopenharmony_ci tmp = tmp & 0xE; 1869141cc406Sopenharmony_ci Outb (CONTROL, tmp | 0x1); 1870141cc406Sopenharmony_ci Outb (CONTROL, tmp | 0x1); 1871141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1872141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1873141cc406Sopenharmony_ci goto sendCommandEnd; 1874141cc406Sopenharmony_ci } 1875141cc406Sopenharmony_ci 1876141cc406Sopenharmony_ci /* */ 1877141cc406Sopenharmony_ci tmp = Inb (CONTROL) & 0x1E; 1878141cc406Sopenharmony_ci if (g67D != 1) 1879141cc406Sopenharmony_ci tmp = tmp & 0xE; 1880141cc406Sopenharmony_ci Outb (CONTROL, tmp | 0x1); 1881141cc406Sopenharmony_ci Outb (CONTROL, tmp | 0x1); 1882141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1883141cc406Sopenharmony_ci Outb (CONTROL, tmp); 1884141cc406Sopenharmony_ci 1885141cc406Sopenharmony_ci /* success */ 1886141cc406Sopenharmony_cisendCommandEnd: 1887141cc406Sopenharmony_ci 1888141cc406Sopenharmony_ci if (cmd == 0x48) 1889141cc406Sopenharmony_ci Outb (CONTROL, (control & 0xF) | 0x4); 1890141cc406Sopenharmony_ci if (cmd == 0x30) 1891141cc406Sopenharmony_ci Outb (CONTROL, (gControl & 0xF) | 0x4); 1892141cc406Sopenharmony_ci 1893141cc406Sopenharmony_ci /* end signature */ 1894141cc406Sopenharmony_ci Outb (DATA, 0xFF); 1895141cc406Sopenharmony_ci Outb (DATA, 0xFF); 1896141cc406Sopenharmony_ci 1897141cc406Sopenharmony_ci if (cmd == 8) 1898141cc406Sopenharmony_ci { 1899141cc406Sopenharmony_ci Outb (CONTROL, control); 1900141cc406Sopenharmony_ci return 1; 1901141cc406Sopenharmony_ci } 1902141cc406Sopenharmony_ci 1903141cc406Sopenharmony_ci if (cmd == 0x30) 1904141cc406Sopenharmony_ci { 1905141cc406Sopenharmony_ci Outb (CONTROL, gControl); 1906141cc406Sopenharmony_ci return 1; 1907141cc406Sopenharmony_ci } 1908141cc406Sopenharmony_ci 1909141cc406Sopenharmony_ci if (cmd != 0xE0) 1910141cc406Sopenharmony_ci Outb (CONTROL, control); 1911141cc406Sopenharmony_ci 1912141cc406Sopenharmony_ci return 1; 1913141cc406Sopenharmony_ci} 1914141cc406Sopenharmony_ci 1915141cc406Sopenharmony_ci 1916141cc406Sopenharmony_cistatic void 1917141cc406Sopenharmony_ciClearRegister (int reg) 1918141cc406Sopenharmony_ci{ 1919141cc406Sopenharmony_ci 1920141cc406Sopenharmony_ci /* choose register */ 1921141cc406Sopenharmony_ci Outb (DATA, reg); 1922141cc406Sopenharmony_ci Outb (DATA, reg); 1923141cc406Sopenharmony_ci Outb (CONTROL, 1); 1924141cc406Sopenharmony_ci Outb (CONTROL, 1); 1925141cc406Sopenharmony_ci if ((g6FE == 0) || (g674 != 0)) 1926141cc406Sopenharmony_ci { 1927141cc406Sopenharmony_ci Outb (CONTROL, 1); 1928141cc406Sopenharmony_ci Outb (CONTROL, 1); 1929141cc406Sopenharmony_ci Outb (CONTROL, 1); 1930141cc406Sopenharmony_ci Outb (CONTROL, 1); 1931141cc406Sopenharmony_ci } 1932141cc406Sopenharmony_ci 1933141cc406Sopenharmony_ci /* clears it by not sending new value */ 1934141cc406Sopenharmony_ci Outb (CONTROL, 4); 1935141cc406Sopenharmony_ci Outb (CONTROL, 4); 1936141cc406Sopenharmony_ci Outb (CONTROL, 4); 1937141cc406Sopenharmony_ci Outb (CONTROL, 4); 1938141cc406Sopenharmony_ci} 1939141cc406Sopenharmony_ci 1940141cc406Sopenharmony_cistatic void 1941141cc406Sopenharmony_ciSPPResetLPT (void) 1942141cc406Sopenharmony_ci{ 1943141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 1944141cc406Sopenharmony_ci} 1945141cc406Sopenharmony_ci 1946141cc406Sopenharmony_ci 1947141cc406Sopenharmony_cistatic int 1948141cc406Sopenharmony_ciPS2registerRead (int reg) 1949141cc406Sopenharmony_ci{ 1950141cc406Sopenharmony_ci int low, high; 1951141cc406Sopenharmony_ci 1952141cc406Sopenharmony_ci 1953141cc406Sopenharmony_ci /* send register number */ 1954141cc406Sopenharmony_ci Outb (DATA, reg); 1955141cc406Sopenharmony_ci Outb (DATA, reg); 1956141cc406Sopenharmony_ci 1957141cc406Sopenharmony_ci /* get low nibble */ 1958141cc406Sopenharmony_ci Outb (CONTROL, 1); 1959141cc406Sopenharmony_ci Outb (CONTROL, 3); 1960141cc406Sopenharmony_ci Outb (CONTROL, 3); 1961141cc406Sopenharmony_ci Outb (CONTROL, 3); 1962141cc406Sopenharmony_ci Outb (CONTROL, 3); 1963141cc406Sopenharmony_ci low = Inb (STATUS); 1964141cc406Sopenharmony_ci low = Inb (STATUS); 1965141cc406Sopenharmony_ci 1966141cc406Sopenharmony_ci /* get high nibble */ 1967141cc406Sopenharmony_ci Outb (CONTROL, 4); 1968141cc406Sopenharmony_ci Outb (CONTROL, 4); 1969141cc406Sopenharmony_ci Outb (CONTROL, 4); 1970141cc406Sopenharmony_ci high = Inb (STATUS); 1971141cc406Sopenharmony_ci high = Inb (STATUS); 1972141cc406Sopenharmony_ci 1973141cc406Sopenharmony_ci /* merge nibbles and return */ 1974141cc406Sopenharmony_ci high = (high & 0xF0) | ((low & 0xF0) >> 4); 1975141cc406Sopenharmony_ci return high; 1976141cc406Sopenharmony_ci} 1977141cc406Sopenharmony_ci 1978141cc406Sopenharmony_ci 1979141cc406Sopenharmony_cistatic void 1980141cc406Sopenharmony_ciPS2bufferRead (int size, unsigned char *dest) 1981141cc406Sopenharmony_ci{ 1982141cc406Sopenharmony_ci int high; 1983141cc406Sopenharmony_ci int low; 1984141cc406Sopenharmony_ci int i; 1985141cc406Sopenharmony_ci int count; 1986141cc406Sopenharmony_ci int bytel, byteh; 1987141cc406Sopenharmony_ci 1988141cc406Sopenharmony_ci /* init transfer */ 1989141cc406Sopenharmony_ci Outb (DATA, 7); 1990141cc406Sopenharmony_ci Outb (DATA, 7); 1991141cc406Sopenharmony_ci Outb (CONTROL, 1); 1992141cc406Sopenharmony_ci Outb (CONTROL, 1); 1993141cc406Sopenharmony_ci Outb (CONTROL, 3); 1994141cc406Sopenharmony_ci Outb (CONTROL, 3); 1995141cc406Sopenharmony_ci Outb (CONTROL, 3); 1996141cc406Sopenharmony_ci Outb (DATA, 0xFF); 1997141cc406Sopenharmony_ci Outb (DATA, 0xFF); 1998141cc406Sopenharmony_ci count = (size - 2) / 2; 1999141cc406Sopenharmony_ci i = 0; 2000141cc406Sopenharmony_ci bytel = 0x06; /* signals low byte of word */ 2001141cc406Sopenharmony_ci byteh = 0x07; /* signals high byte of word */ 2002141cc406Sopenharmony_ci 2003141cc406Sopenharmony_ci /* read loop */ 2004141cc406Sopenharmony_ci while (count > 0) 2005141cc406Sopenharmony_ci { 2006141cc406Sopenharmony_ci /* low nibble byte 0 */ 2007141cc406Sopenharmony_ci Outb (CONTROL, bytel); 2008141cc406Sopenharmony_ci Outb (CONTROL, bytel); 2009141cc406Sopenharmony_ci Outb (CONTROL, bytel); 2010141cc406Sopenharmony_ci low = Inb (STATUS); 2011141cc406Sopenharmony_ci if ((low & 0x08) == 0) 2012141cc406Sopenharmony_ci { 2013141cc406Sopenharmony_ci /* high nibble <> low nibble */ 2014141cc406Sopenharmony_ci Outb (CONTROL, bytel & 0x05); 2015141cc406Sopenharmony_ci Outb (CONTROL, bytel & 0x05); 2016141cc406Sopenharmony_ci Outb (CONTROL, bytel & 0x05); 2017141cc406Sopenharmony_ci high = Inb (STATUS); 2018141cc406Sopenharmony_ci } 2019141cc406Sopenharmony_ci else 2020141cc406Sopenharmony_ci { 2021141cc406Sopenharmony_ci high = low; 2022141cc406Sopenharmony_ci } 2023141cc406Sopenharmony_ci low = low & 0xF0; 2024141cc406Sopenharmony_ci high = high & 0xF0; 2025141cc406Sopenharmony_ci dest[i] = (unsigned char) (high | (low >> 4)); 2026141cc406Sopenharmony_ci i++; 2027141cc406Sopenharmony_ci 2028141cc406Sopenharmony_ci /* low nibble byte 1 */ 2029141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2030141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2031141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2032141cc406Sopenharmony_ci low = Inb (STATUS); 2033141cc406Sopenharmony_ci if ((low & 0x08) == 0) 2034141cc406Sopenharmony_ci { 2035141cc406Sopenharmony_ci /* high nibble <> low nibble */ 2036141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2037141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2038141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2039141cc406Sopenharmony_ci high = Inb (STATUS); 2040141cc406Sopenharmony_ci } 2041141cc406Sopenharmony_ci else 2042141cc406Sopenharmony_ci { 2043141cc406Sopenharmony_ci high = low; 2044141cc406Sopenharmony_ci } 2045141cc406Sopenharmony_ci low = low & 0xF0; 2046141cc406Sopenharmony_ci high = high & 0xF0; 2047141cc406Sopenharmony_ci dest[i] = (unsigned char) (high | (low >> 4)); 2048141cc406Sopenharmony_ci i++; 2049141cc406Sopenharmony_ci 2050141cc406Sopenharmony_ci /* next read */ 2051141cc406Sopenharmony_ci count--; 2052141cc406Sopenharmony_ci } 2053141cc406Sopenharmony_ci 2054141cc406Sopenharmony_ci /* final read */ 2055141cc406Sopenharmony_ci /* low nibble byte 0 */ 2056141cc406Sopenharmony_ci Outb (CONTROL, bytel); 2057141cc406Sopenharmony_ci Outb (CONTROL, bytel); 2058141cc406Sopenharmony_ci Outb (CONTROL, bytel); 2059141cc406Sopenharmony_ci low = Inb (STATUS); 2060141cc406Sopenharmony_ci if ((low & 0x08) == 0) 2061141cc406Sopenharmony_ci { 2062141cc406Sopenharmony_ci /* high nibble <> low nibble */ 2063141cc406Sopenharmony_ci Outb (CONTROL, bytel & 0x05); 2064141cc406Sopenharmony_ci Outb (CONTROL, bytel & 0x05); 2065141cc406Sopenharmony_ci Outb (CONTROL, bytel & 0x05); 2066141cc406Sopenharmony_ci high = Inb (STATUS); 2067141cc406Sopenharmony_ci } 2068141cc406Sopenharmony_ci else 2069141cc406Sopenharmony_ci { 2070141cc406Sopenharmony_ci high = low; 2071141cc406Sopenharmony_ci } 2072141cc406Sopenharmony_ci low = low & 0xF0; 2073141cc406Sopenharmony_ci high = high & 0xF0; 2074141cc406Sopenharmony_ci dest[i] = (unsigned char) (high | (low >> 4)); 2075141cc406Sopenharmony_ci i++; 2076141cc406Sopenharmony_ci 2077141cc406Sopenharmony_ci /* uneven size need an extra read */ 2078141cc406Sopenharmony_ci if ((size & 0x01) == 1) 2079141cc406Sopenharmony_ci { 2080141cc406Sopenharmony_ci /* low nibble byte 1 */ 2081141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2082141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2083141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2084141cc406Sopenharmony_ci low = Inb (STATUS); 2085141cc406Sopenharmony_ci if ((low & 0x08) == 0) 2086141cc406Sopenharmony_ci { 2087141cc406Sopenharmony_ci /* high nibble <> low nibble */ 2088141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2089141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2090141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2091141cc406Sopenharmony_ci high = Inb (STATUS); 2092141cc406Sopenharmony_ci } 2093141cc406Sopenharmony_ci else 2094141cc406Sopenharmony_ci { 2095141cc406Sopenharmony_ci high = low; 2096141cc406Sopenharmony_ci } 2097141cc406Sopenharmony_ci low = low & 0xF0; 2098141cc406Sopenharmony_ci high = high & 0xF0; 2099141cc406Sopenharmony_ci dest[i] = (unsigned char) (high | (low >> 4)); 2100141cc406Sopenharmony_ci i++; 2101141cc406Sopenharmony_ci 2102141cc406Sopenharmony_ci /* swap high/low word */ 2103141cc406Sopenharmony_ci count = bytel; 2104141cc406Sopenharmony_ci bytel = byteh; 2105141cc406Sopenharmony_ci byteh = count; 2106141cc406Sopenharmony_ci } 2107141cc406Sopenharmony_ci 2108141cc406Sopenharmony_ci /* final byte ... */ 2109141cc406Sopenharmony_ci Outb (DATA, 0xFD); 2110141cc406Sopenharmony_ci Outb (DATA, 0xFD); 2111141cc406Sopenharmony_ci Outb (DATA, 0xFD); 2112141cc406Sopenharmony_ci 2113141cc406Sopenharmony_ci /* low nibble */ 2114141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2115141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2116141cc406Sopenharmony_ci Outb (CONTROL, byteh); 2117141cc406Sopenharmony_ci low = Inb (STATUS); 2118141cc406Sopenharmony_ci if ((low & 0x08) == 0) 2119141cc406Sopenharmony_ci { 2120141cc406Sopenharmony_ci /* high nibble <> low nibble */ 2121141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2122141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2123141cc406Sopenharmony_ci Outb (CONTROL, byteh & 0x05); 2124141cc406Sopenharmony_ci high = Inb (STATUS); 2125141cc406Sopenharmony_ci } 2126141cc406Sopenharmony_ci else 2127141cc406Sopenharmony_ci { 2128141cc406Sopenharmony_ci high = low; 2129141cc406Sopenharmony_ci } 2130141cc406Sopenharmony_ci low = low & 0xF0; 2131141cc406Sopenharmony_ci high = high & 0xF0; 2132141cc406Sopenharmony_ci dest[i] = (unsigned char) (high | (low >> 4)); 2133141cc406Sopenharmony_ci i++; 2134141cc406Sopenharmony_ci 2135141cc406Sopenharmony_ci /* reset port */ 2136141cc406Sopenharmony_ci Outb (DATA, 0x00); 2137141cc406Sopenharmony_ci Outb (DATA, 0x00); 2138141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2139141cc406Sopenharmony_ci} 2140141cc406Sopenharmony_ci 2141141cc406Sopenharmony_cistatic void 2142141cc406Sopenharmony_ciPS2bufferWrite (int size, unsigned char *source) 2143141cc406Sopenharmony_ci{ 2144141cc406Sopenharmony_ci int i; 2145141cc406Sopenharmony_ci int count; 2146141cc406Sopenharmony_ci int val; 2147141cc406Sopenharmony_ci 2148141cc406Sopenharmony_ci /* init buffer write */ 2149141cc406Sopenharmony_ci i = 0; 2150141cc406Sopenharmony_ci count = size / 2; 2151141cc406Sopenharmony_ci Outb (DATA, 0x67); 2152141cc406Sopenharmony_ci Outb (CONTROL, 0x01); 2153141cc406Sopenharmony_ci Outb (CONTROL, 0x01); 2154141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2155141cc406Sopenharmony_ci 2156141cc406Sopenharmony_ci /* write loop */ 2157141cc406Sopenharmony_ci while (count > 0) 2158141cc406Sopenharmony_ci { 2159141cc406Sopenharmony_ci /* low byte of word */ 2160141cc406Sopenharmony_ci val = source[i]; 2161141cc406Sopenharmony_ci i++; 2162141cc406Sopenharmony_ci Outb (DATA, val); 2163141cc406Sopenharmony_ci Outb (DATA, val); 2164141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2165141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2166141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2167141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2168141cc406Sopenharmony_ci 2169141cc406Sopenharmony_ci /* high byte of word */ 2170141cc406Sopenharmony_ci val = source[i]; 2171141cc406Sopenharmony_ci i++; 2172141cc406Sopenharmony_ci Outb (DATA, val); 2173141cc406Sopenharmony_ci Outb (DATA, val); 2174141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2175141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2176141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2177141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2178141cc406Sopenharmony_ci 2179141cc406Sopenharmony_ci /* next write */ 2180141cc406Sopenharmony_ci count--; 2181141cc406Sopenharmony_ci } 2182141cc406Sopenharmony_ci 2183141cc406Sopenharmony_ci /* termination sequence */ 2184141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2185141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2186141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2187141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 2188141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2189141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2190141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2191141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2192141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2193141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2194141cc406Sopenharmony_ci} 2195141cc406Sopenharmony_ci 2196141cc406Sopenharmony_ci 2197141cc406Sopenharmony_ci 2198141cc406Sopenharmony_ci 2199141cc406Sopenharmony_cistatic void 2200141cc406Sopenharmony_ciinit001 (void) 2201141cc406Sopenharmony_ci{ 2202141cc406Sopenharmony_ci int i; 2203141cc406Sopenharmony_ci int val; 2204141cc406Sopenharmony_ci int status; 2205141cc406Sopenharmony_ci 2206141cc406Sopenharmony_ci ClearRegister (0); 2207141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 2208141cc406Sopenharmony_ci if (g674 != 0) 2209141cc406Sopenharmony_ci { 2210141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 2211141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 2212141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 2213141cc406Sopenharmony_ci } 2214141cc406Sopenharmony_ci Outb (DATA, 0x40); 2215141cc406Sopenharmony_ci if (g674 != 0) 2216141cc406Sopenharmony_ci { 2217141cc406Sopenharmony_ci Outb (DATA, 0x40); 2218141cc406Sopenharmony_ci Outb (DATA, 0x40); 2219141cc406Sopenharmony_ci Outb (DATA, 0x40); 2220141cc406Sopenharmony_ci } 2221141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 2222141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 2223141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 2224141cc406Sopenharmony_ci if (g674 != 0) 2225141cc406Sopenharmony_ci { 2226141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 2227141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 2228141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 2229141cc406Sopenharmony_ci } 2230141cc406Sopenharmony_ci 2231141cc406Sopenharmony_ci /* sync loop */ 2232141cc406Sopenharmony_ci i = 256; 2233141cc406Sopenharmony_ci do 2234141cc406Sopenharmony_ci { 2235141cc406Sopenharmony_ci status = Inb (STATUS); 2236141cc406Sopenharmony_ci i--; 2237141cc406Sopenharmony_ci } 2238141cc406Sopenharmony_ci while ((i > 0) && ((status & 0x40))); 2239141cc406Sopenharmony_ci val = 0x0C; 2240141cc406Sopenharmony_ci if (i > 0) 2241141cc406Sopenharmony_ci { 2242141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2243141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2244141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2245141cc406Sopenharmony_ci if (g674 != 0) 2246141cc406Sopenharmony_ci { 2247141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2248141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2249141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 2250141cc406Sopenharmony_ci } 2251141cc406Sopenharmony_ci val = 0x04; 2252141cc406Sopenharmony_ci Outb (CONTROL, val); 2253141cc406Sopenharmony_ci Outb (CONTROL, val); 2254141cc406Sopenharmony_ci Outb (CONTROL, val); 2255141cc406Sopenharmony_ci if (g674 != 0) 2256141cc406Sopenharmony_ci { 2257141cc406Sopenharmony_ci Outb (CONTROL, val); 2258141cc406Sopenharmony_ci Outb (CONTROL, val); 2259141cc406Sopenharmony_ci Outb (CONTROL, val); 2260141cc406Sopenharmony_ci } 2261141cc406Sopenharmony_ci } 2262141cc406Sopenharmony_ci val = val | 0x0C; 2263141cc406Sopenharmony_ci Outb (CONTROL, val); 2264141cc406Sopenharmony_ci Outb (CONTROL, val); 2265141cc406Sopenharmony_ci Outb (CONTROL, val); 2266141cc406Sopenharmony_ci if (g674 != 0) 2267141cc406Sopenharmony_ci { 2268141cc406Sopenharmony_ci Outb (CONTROL, val); 2269141cc406Sopenharmony_ci Outb (CONTROL, val); 2270141cc406Sopenharmony_ci Outb (CONTROL, val); 2271141cc406Sopenharmony_ci } 2272141cc406Sopenharmony_ci val = val & 0xF7; 2273141cc406Sopenharmony_ci Outb (CONTROL, val); 2274141cc406Sopenharmony_ci Outb (CONTROL, val); 2275141cc406Sopenharmony_ci Outb (CONTROL, val); 2276141cc406Sopenharmony_ci if (g674 != 0) 2277141cc406Sopenharmony_ci { 2278141cc406Sopenharmony_ci Outb (CONTROL, val); 2279141cc406Sopenharmony_ci Outb (CONTROL, val); 2280141cc406Sopenharmony_ci Outb (CONTROL, val); 2281141cc406Sopenharmony_ci } 2282141cc406Sopenharmony_ci} 2283141cc406Sopenharmony_ci 2284141cc406Sopenharmony_ci/* SPP register reading */ 2285141cc406Sopenharmony_cistatic int 2286141cc406Sopenharmony_ciinit002 (int arg) 2287141cc406Sopenharmony_ci{ 2288141cc406Sopenharmony_ci int data; 2289141cc406Sopenharmony_ci 2290141cc406Sopenharmony_ci if (arg == 1) 2291141cc406Sopenharmony_ci return 0; 2292141cc406Sopenharmony_ci Outb (DATA, 0x0B); 2293141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2294141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2295141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2296141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 2297141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 2298141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 2299141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2300141cc406Sopenharmony_ci Outb (CONTROL, 0x24); 2301141cc406Sopenharmony_ci Outb (CONTROL, 0x24); 2302141cc406Sopenharmony_ci Outb (CONTROL, 0x26); 2303141cc406Sopenharmony_ci Outb (CONTROL, 0x26); 2304141cc406Sopenharmony_ci 2305141cc406Sopenharmony_ci data = Inb (DATA); 2306141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2307141cc406Sopenharmony_ci if (data == gEPAT) 2308141cc406Sopenharmony_ci { 2309141cc406Sopenharmony_ci return 1; 2310141cc406Sopenharmony_ci } 2311141cc406Sopenharmony_ci return 0; 2312141cc406Sopenharmony_ci} 2313141cc406Sopenharmony_ci 2314141cc406Sopenharmony_ci/* 2315141cc406Sopenharmony_ci * connecct to the EPAT chip, and 2316141cc406Sopenharmony_ci * prepare command sending 2317141cc406Sopenharmony_ci */ 2318141cc406Sopenharmony_cistatic int 2319141cc406Sopenharmony_ciECPconnect (void) 2320141cc406Sopenharmony_ci{ 2321141cc406Sopenharmony_ci int ret, control; 2322141cc406Sopenharmony_ci 2323141cc406Sopenharmony_ci /* these 3 lines set to 'inital mode' */ 2324141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); */ 2325141cc406Sopenharmony_ci Outb (DATA, 0x04); /* gData */ 2326141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); /* gControl */ 2327141cc406Sopenharmony_ci 2328141cc406Sopenharmony_ci Inb (ECR); /* 0x35 */ 2329141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); */ 2330141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); */ 2331141cc406Sopenharmony_ci 2332141cc406Sopenharmony_ci gData = Inb (DATA); 2333141cc406Sopenharmony_ci gControl = Inb (CONTROL); 2334141cc406Sopenharmony_ci 2335141cc406Sopenharmony_ci Inb (DATA); 2336141cc406Sopenharmony_ci control = Inb (CONTROL); 2337141cc406Sopenharmony_ci Outb (CONTROL, control & 0x1F); 2338141cc406Sopenharmony_ci control = Inb (CONTROL); 2339141cc406Sopenharmony_ci Outb (CONTROL, control & 0x1F); 2340141cc406Sopenharmony_ci sendCommand (0xE0); 2341141cc406Sopenharmony_ci 2342141cc406Sopenharmony_ci Outb (DATA, 0xFF); 2343141cc406Sopenharmony_ci Outb (DATA, 0xFF); 2344141cc406Sopenharmony_ci ClearRegister (0); 2345141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 2346141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2347141cc406Sopenharmony_ci ClearRegister (0); 2348141cc406Sopenharmony_ci ret = PS2Something (0x10); 2349141cc406Sopenharmony_ci if (ret != 0x0B) 2350141cc406Sopenharmony_ci { 2351141cc406Sopenharmony_ci DBG (16, 2352141cc406Sopenharmony_ci "PS2Something returned 0x%02X, 0x0B expected (%s:%d)\n", ret, 2353141cc406Sopenharmony_ci __FILE__, __LINE__); 2354141cc406Sopenharmony_ci } 2355141cc406Sopenharmony_ci return 1; 2356141cc406Sopenharmony_ci} 2357141cc406Sopenharmony_ci 2358141cc406Sopenharmony_cistatic void 2359141cc406Sopenharmony_ciEPPdisconnect (void) 2360141cc406Sopenharmony_ci{ 2361141cc406Sopenharmony_ci if (getModel () != 0x07) 2362141cc406Sopenharmony_ci sendCommand (40); 2363141cc406Sopenharmony_ci sendCommand (30); 2364141cc406Sopenharmony_ci Outb (DATA, gData); 2365141cc406Sopenharmony_ci Outb (CONTROL, gControl); 2366141cc406Sopenharmony_ci} 2367141cc406Sopenharmony_ci 2368141cc406Sopenharmony_cistatic void 2369141cc406Sopenharmony_ciECPdisconnect (void) 2370141cc406Sopenharmony_ci{ 2371141cc406Sopenharmony_ci int control; 2372141cc406Sopenharmony_ci 2373141cc406Sopenharmony_ci if (getModel () != 0x07) /* guessed */ 2374141cc406Sopenharmony_ci sendCommand (40); /* guessed */ 2375141cc406Sopenharmony_ci sendCommand (0x30); 2376141cc406Sopenharmony_ci control = Inb (CONTROL) | 0x01; 2377141cc406Sopenharmony_ci Outb (CONTROL, control); 2378141cc406Sopenharmony_ci Outb (CONTROL, control); 2379141cc406Sopenharmony_ci control = control & 0x04; 2380141cc406Sopenharmony_ci Outb (CONTROL, control); 2381141cc406Sopenharmony_ci Outb (CONTROL, control); 2382141cc406Sopenharmony_ci control = control | 0x08; 2383141cc406Sopenharmony_ci Outb (CONTROL, control); 2384141cc406Sopenharmony_ci Outb (DATA, 0xFF); 2385141cc406Sopenharmony_ci Outb (DATA, 0xFF); 2386141cc406Sopenharmony_ci Outb (CONTROL, control); 2387141cc406Sopenharmony_ci} 2388141cc406Sopenharmony_ci 2389141cc406Sopenharmony_cistatic int 2390141cc406Sopenharmony_ciECPregisterRead (int reg) 2391141cc406Sopenharmony_ci{ 2392141cc406Sopenharmony_ci unsigned char breg, value; 2393141cc406Sopenharmony_ci 2394141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2395141cc406Sopenharmony_ci int rc, mode, fd; 2396141cc406Sopenharmony_ci unsigned char bval; 2397141cc406Sopenharmony_ci 2398141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 2399141cc406Sopenharmony_ci if (fd > 0) 2400141cc406Sopenharmony_ci { 2401141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2402141cc406Sopenharmony_ci ECPFifoMode (); 2403141cc406Sopenharmony_ci Outb (DATA, reg); 2404141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 2405141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 2406141cc406Sopenharmony_ci if (rc) 2407141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2408141cc406Sopenharmony_ci __FILE__, __LINE__); 2409141cc406Sopenharmony_ci rc = read (fd, &bval, 1); 2410141cc406Sopenharmony_ci if (rc != 1) 2411141cc406Sopenharmony_ci DBG (0, "ppdev short read (%s:%d)\n", __FILE__, __LINE__); 2412141cc406Sopenharmony_ci value = bval; 2413141cc406Sopenharmony_ci breg = (Inb (CONTROL) & 0x3F); 2414141cc406Sopenharmony_ci if (breg != 0x20) 2415141cc406Sopenharmony_ci { 2416141cc406Sopenharmony_ci DBG (0, 2417141cc406Sopenharmony_ci "ECPregisterRead failed, expecting 0x20, got 0x%02X (%s:%d)\n", 2418141cc406Sopenharmony_ci breg, __FILE__, __LINE__); 2419141cc406Sopenharmony_ci } 2420141cc406Sopenharmony_ci 2421141cc406Sopenharmony_ci /* restore port state */ 2422141cc406Sopenharmony_ci mode = 0; /* data_forward */ 2423141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 2424141cc406Sopenharmony_ci if (rc) 2425141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2426141cc406Sopenharmony_ci __FILE__, __LINE__); 2427141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2428141cc406Sopenharmony_ci byteMode (); 2429141cc406Sopenharmony_ci return value; 2430141cc406Sopenharmony_ci } 2431141cc406Sopenharmony_ci#endif 2432141cc406Sopenharmony_ci 2433141cc406Sopenharmony_ci Outb (CONTROL, 0x4); 2434141cc406Sopenharmony_ci 2435141cc406Sopenharmony_ci /* ECP FIFO mode, interrupt bit, dma disabled, 2436141cc406Sopenharmony_ci service bit, fifo full=0, fifo empty=0 */ 2437141cc406Sopenharmony_ci ECPFifoMode (); /*Outb (ECR, 0x60); */ 2438141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2439141cc406Sopenharmony_ci { 2440141cc406Sopenharmony_ci DBG (0, "ECPregisterRead failed, FIFO time-out (%s:%d)\n", 2441141cc406Sopenharmony_ci __FILE__, __LINE__); 2442141cc406Sopenharmony_ci } 2443141cc406Sopenharmony_ci breg = Inb (ECR); 2444141cc406Sopenharmony_ci 2445141cc406Sopenharmony_ci Outb (DATA, reg); 2446141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2447141cc406Sopenharmony_ci { 2448141cc406Sopenharmony_ci DBG (0, "ECPregisterRead failed, FIFO time-out (%s:%d)\n", 2449141cc406Sopenharmony_ci __FILE__, __LINE__); 2450141cc406Sopenharmony_ci } 2451141cc406Sopenharmony_ci breg = Inb (ECR); 2452141cc406Sopenharmony_ci 2453141cc406Sopenharmony_ci /* byte mode, interrupt bit, dma disabled, 2454141cc406Sopenharmony_ci service bit, fifo full=0, fifo empty=0 */ 2455141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); */ 2456141cc406Sopenharmony_ci Outb (CONTROL, 0x20); /* data reverse */ 2457141cc406Sopenharmony_ci 2458141cc406Sopenharmony_ci /* ECP FIFO mode, interrupt bit, dma disabled, 2459141cc406Sopenharmony_ci service bit, fifo full=0, fifo empty=0 */ 2460141cc406Sopenharmony_ci ECPFifoMode (); /*Outb (ECR, 0x60); */ 2461141cc406Sopenharmony_ci if (waitFifoNotEmpty () == 0) 2462141cc406Sopenharmony_ci { 2463141cc406Sopenharmony_ci DBG (0, "ECPregisterRead failed, FIFO time-out (%s:%d)\n", 2464141cc406Sopenharmony_ci __FILE__, __LINE__); 2465141cc406Sopenharmony_ci } 2466141cc406Sopenharmony_ci breg = Inb (ECR); 2467141cc406Sopenharmony_ci value = Inb (ECPDATA); 2468141cc406Sopenharmony_ci 2469141cc406Sopenharmony_ci /* according to the spec bit 7 and 6 are unused */ 2470141cc406Sopenharmony_ci breg = (Inb (CONTROL) & 0x3F); 2471141cc406Sopenharmony_ci if (breg != 0x20) 2472141cc406Sopenharmony_ci { 2473141cc406Sopenharmony_ci DBG (0, "ECPregisterRead failed, expecting 0x20, got 0x%02X (%s:%d)\n", 2474141cc406Sopenharmony_ci breg, __FILE__, __LINE__); 2475141cc406Sopenharmony_ci } 2476141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2477141cc406Sopenharmony_ci byteMode (); 2478141cc406Sopenharmony_ci return value; 2479141cc406Sopenharmony_ci} 2480141cc406Sopenharmony_ci 2481141cc406Sopenharmony_cistatic int 2482141cc406Sopenharmony_ciEPPregisterRead (int reg) 2483141cc406Sopenharmony_ci{ 2484141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2485141cc406Sopenharmony_ci int fd, mode, rc; 2486141cc406Sopenharmony_ci unsigned char breg, bval; 2487141cc406Sopenharmony_ci int value; 2488141cc406Sopenharmony_ci#endif 2489141cc406Sopenharmony_ci int control; 2490141cc406Sopenharmony_ci 2491141cc406Sopenharmony_ci 2492141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2493141cc406Sopenharmony_ci /* check we have ppdev working */ 2494141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 2495141cc406Sopenharmony_ci if (fd > 0) 2496141cc406Sopenharmony_ci { 2497141cc406Sopenharmony_ci breg = (unsigned char) (reg); 2498141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 2499141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2500141cc406Sopenharmony_ci if (rc) 2501141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2502141cc406Sopenharmony_ci __FILE__, __LINE__); 2503141cc406Sopenharmony_ci rc = write (fd, &breg, 1); 2504141cc406Sopenharmony_ci if (rc != 1) 2505141cc406Sopenharmony_ci DBG (0, "ppdev short write (%s:%d)\n", __FILE__, __LINE__); 2506141cc406Sopenharmony_ci 2507141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 2508141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 2509141cc406Sopenharmony_ci if (rc) 2510141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2511141cc406Sopenharmony_ci __FILE__, __LINE__); 2512141cc406Sopenharmony_ci 2513141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 2514141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2515141cc406Sopenharmony_ci if (rc) 2516141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2517141cc406Sopenharmony_ci __FILE__, __LINE__); 2518141cc406Sopenharmony_ci rc = read (fd, &bval, 1); 2519141cc406Sopenharmony_ci if (rc != 1) 2520141cc406Sopenharmony_ci DBG (0, "ppdev short read (%s:%d)\n", __FILE__, __LINE__); 2521141cc406Sopenharmony_ci value = bval; 2522141cc406Sopenharmony_ci 2523141cc406Sopenharmony_ci mode = 0; /* forward */ 2524141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 2525141cc406Sopenharmony_ci if (rc) 2526141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2527141cc406Sopenharmony_ci __FILE__, __LINE__); 2528141cc406Sopenharmony_ci 2529141cc406Sopenharmony_ci return value; 2530141cc406Sopenharmony_ci } 2531141cc406Sopenharmony_ci /* if not, direct hardware access */ 2532141cc406Sopenharmony_ci#endif 2533141cc406Sopenharmony_ci 2534141cc406Sopenharmony_ci Outb (EPPADDR, reg); 2535141cc406Sopenharmony_ci control = Inb (CONTROL); 2536141cc406Sopenharmony_ci control = (control & 0x1F) | 0x20; 2537141cc406Sopenharmony_ci Outb (CONTROL, control); 2538141cc406Sopenharmony_ci Inb (EPPDATA); 2539141cc406Sopenharmony_ci control = Inb (CONTROL); 2540141cc406Sopenharmony_ci control = control & 0x1F; 2541141cc406Sopenharmony_ci Outb (CONTROL, control); 2542141cc406Sopenharmony_ci return 0xFF; 2543141cc406Sopenharmony_ci /* return value; */ 2544141cc406Sopenharmony_ci} 2545141cc406Sopenharmony_ci 2546141cc406Sopenharmony_cistatic int 2547141cc406Sopenharmony_ciregisterRead (int reg) 2548141cc406Sopenharmony_ci{ 2549141cc406Sopenharmony_ci switch (gMode) 2550141cc406Sopenharmony_ci { 2551141cc406Sopenharmony_ci case UMAX_PP_PARPORT_ECP: 2552141cc406Sopenharmony_ci return ECPregisterRead (reg); 2553141cc406Sopenharmony_ci case UMAX_PP_PARPORT_BYTE: 2554141cc406Sopenharmony_ci DBG (0, "STEF: gMode BYTE in registerRead !!\n"); 2555141cc406Sopenharmony_ci return 0xFF; 2556141cc406Sopenharmony_ci case UMAX_PP_PARPORT_EPP: 2557141cc406Sopenharmony_ci return EPPregisterRead (reg); 2558141cc406Sopenharmony_ci case UMAX_PP_PARPORT_PS2: 2559141cc406Sopenharmony_ci DBG (0, "STEF: gMode PS2 in registerRead !!\n"); 2560141cc406Sopenharmony_ci return PS2registerRead (reg); 2561141cc406Sopenharmony_ci default: 2562141cc406Sopenharmony_ci DBG (0, "STEF: gMode unset in registerRead !!\n"); 2563141cc406Sopenharmony_ci return 0xFF; 2564141cc406Sopenharmony_ci } 2565141cc406Sopenharmony_ci} 2566141cc406Sopenharmony_ci 2567141cc406Sopenharmony_ci 2568141cc406Sopenharmony_cistatic void 2569141cc406Sopenharmony_ciECPregisterWrite (int reg, int value) 2570141cc406Sopenharmony_ci{ 2571141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2572141cc406Sopenharmony_ci unsigned char breg; 2573141cc406Sopenharmony_ci int rc, fd; 2574141cc406Sopenharmony_ci 2575141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 2576141cc406Sopenharmony_ci if (fd > 0) 2577141cc406Sopenharmony_ci { 2578141cc406Sopenharmony_ci ECPFifoMode (); 2579141cc406Sopenharmony_ci Outb (DATA, reg); 2580141cc406Sopenharmony_ci breg = value; 2581141cc406Sopenharmony_ci rc = write (fd, &breg, 1); 2582141cc406Sopenharmony_ci if (rc != 1) 2583141cc406Sopenharmony_ci DBG (0, "ppdev short write (%s:%d)\n", __FILE__, __LINE__); 2584141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2585141cc406Sopenharmony_ci byteMode (); 2586141cc406Sopenharmony_ci return; 2587141cc406Sopenharmony_ci } 2588141cc406Sopenharmony_ci#endif 2589141cc406Sopenharmony_ci 2590141cc406Sopenharmony_ci /* standard mode, interrupt bit, dma disabled, 2591141cc406Sopenharmony_ci service bit, fifo full=0, fifo empty=0 */ 2592141cc406Sopenharmony_ci compatMode (); 2593141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset ? */ 2594141cc406Sopenharmony_ci 2595141cc406Sopenharmony_ci /* ECP FIFO mode, interrupt bit, dma disabled, 2596141cc406Sopenharmony_ci service bit, fifo full=0, fifo empty=0 */ 2597141cc406Sopenharmony_ci ECPFifoMode (); /*Outb (ECR, 0x60); */ 2598141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2599141cc406Sopenharmony_ci { 2600141cc406Sopenharmony_ci DBG (0, "ECPregisterWrite failed, time-out waiting for FIFO (%s:%d)\n", 2601141cc406Sopenharmony_ci __FILE__, __LINE__); 2602141cc406Sopenharmony_ci return; 2603141cc406Sopenharmony_ci } 2604141cc406Sopenharmony_ci Inb (ECR); 2605141cc406Sopenharmony_ci 2606141cc406Sopenharmony_ci Outb (DATA, reg); 2607141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2608141cc406Sopenharmony_ci { 2609141cc406Sopenharmony_ci DBG (0, "ECPregisterWrite failed, time-out waiting for FIFO (%s:%d)\n", 2610141cc406Sopenharmony_ci __FILE__, __LINE__); 2611141cc406Sopenharmony_ci return; 2612141cc406Sopenharmony_ci } 2613141cc406Sopenharmony_ci Inb (ECR); 2614141cc406Sopenharmony_ci 2615141cc406Sopenharmony_ci Outb (ECPDATA, value); 2616141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2617141cc406Sopenharmony_ci { 2618141cc406Sopenharmony_ci DBG (0, "ECPregisterWrite failed, time-out waiting for FIFO (%s:%d)\n", 2619141cc406Sopenharmony_ci __FILE__, __LINE__); 2620141cc406Sopenharmony_ci return; 2621141cc406Sopenharmony_ci } 2622141cc406Sopenharmony_ci Inb (ECR); 2623141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2624141cc406Sopenharmony_ci byteMode (); 2625141cc406Sopenharmony_ci return; 2626141cc406Sopenharmony_ci} 2627141cc406Sopenharmony_ci 2628141cc406Sopenharmony_cistatic void 2629141cc406Sopenharmony_ciEPPregisterWrite (int reg, int value) 2630141cc406Sopenharmony_ci{ 2631141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2632141cc406Sopenharmony_ci int fd, mode, rc; 2633141cc406Sopenharmony_ci unsigned char breg, bval; 2634141cc406Sopenharmony_ci#endif 2635141cc406Sopenharmony_ci 2636141cc406Sopenharmony_ci reg = reg | 0x40; 2637141cc406Sopenharmony_ci 2638141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2639141cc406Sopenharmony_ci /* check we have ppdev working */ 2640141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 2641141cc406Sopenharmony_ci if (fd > 0) 2642141cc406Sopenharmony_ci { 2643141cc406Sopenharmony_ci breg = (unsigned char) (reg); 2644141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 2645141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2646141cc406Sopenharmony_ci if (rc) 2647141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2648141cc406Sopenharmony_ci __FILE__, __LINE__); 2649141cc406Sopenharmony_ci rc = write (fd, &breg, 1); 2650141cc406Sopenharmony_ci if (rc != 1) 2651141cc406Sopenharmony_ci DBG (0, "ppdev short write (%s:%d)\n", __FILE__, __LINE__); 2652141cc406Sopenharmony_ci 2653141cc406Sopenharmony_ci bval = (unsigned char) (value); 2654141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 2655141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2656141cc406Sopenharmony_ci if (rc) 2657141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2658141cc406Sopenharmony_ci __FILE__, __LINE__); 2659141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 2660141cc406Sopenharmony_ci 2661141cc406Sopenharmony_ci return; 2662141cc406Sopenharmony_ci } 2663141cc406Sopenharmony_ci /* if not, direct hardware access */ 2664141cc406Sopenharmony_ci#endif 2665141cc406Sopenharmony_ci Outb (EPPADDR, reg); 2666141cc406Sopenharmony_ci Outb (EPPDATA, value); 2667141cc406Sopenharmony_ci} 2668141cc406Sopenharmony_ci 2669141cc406Sopenharmony_cistatic void 2670141cc406Sopenharmony_ciregisterWrite (int reg, int value) 2671141cc406Sopenharmony_ci{ 2672141cc406Sopenharmony_ci switch (gMode) 2673141cc406Sopenharmony_ci { 2674141cc406Sopenharmony_ci case UMAX_PP_PARPORT_PS2: 2675141cc406Sopenharmony_ci PS2registerWrite (reg, value); 2676141cc406Sopenharmony_ci DBG (0, "STEF: gMode PS2 in registerWrite !!\n"); 2677141cc406Sopenharmony_ci break; 2678141cc406Sopenharmony_ci case UMAX_PP_PARPORT_ECP: 2679141cc406Sopenharmony_ci ECPregisterWrite (reg, value); 2680141cc406Sopenharmony_ci break; 2681141cc406Sopenharmony_ci case UMAX_PP_PARPORT_EPP: 2682141cc406Sopenharmony_ci EPPregisterWrite (reg, value); 2683141cc406Sopenharmony_ci break; 2684141cc406Sopenharmony_ci case UMAX_PP_PARPORT_BYTE: 2685141cc406Sopenharmony_ci DBG (0, "STEF: gMode BYTE in registerWrite !!\n"); 2686141cc406Sopenharmony_ci break; 2687141cc406Sopenharmony_ci default: 2688141cc406Sopenharmony_ci DBG (0, "STEF: gMode unset in registerWrite !!\n"); 2689141cc406Sopenharmony_ci break; 2690141cc406Sopenharmony_ci } 2691141cc406Sopenharmony_ci} 2692141cc406Sopenharmony_ci 2693141cc406Sopenharmony_cistatic void 2694141cc406Sopenharmony_ciEPPBlockMode (int flag) 2695141cc406Sopenharmony_ci{ 2696141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2697141cc406Sopenharmony_ci int fd, mode, rc; 2698141cc406Sopenharmony_ci unsigned char bval; 2699141cc406Sopenharmony_ci 2700141cc406Sopenharmony_ci /* check we have ppdev working */ 2701141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 2702141cc406Sopenharmony_ci if (fd > 0) 2703141cc406Sopenharmony_ci { 2704141cc406Sopenharmony_ci bval = (unsigned char) (flag); 2705141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 2706141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2707141cc406Sopenharmony_ci if (rc) 2708141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2709141cc406Sopenharmony_ci __FILE__, __LINE__); 2710141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 2711141cc406Sopenharmony_ci return; 2712141cc406Sopenharmony_ci } 2713141cc406Sopenharmony_ci#endif 2714141cc406Sopenharmony_ci Outb (EPPADDR, flag); 2715141cc406Sopenharmony_ci} 2716141cc406Sopenharmony_ci 2717141cc406Sopenharmony_cistatic void 2718141cc406Sopenharmony_ciEPPbufferRead (int size, unsigned char *dest) 2719141cc406Sopenharmony_ci{ 2720141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2721141cc406Sopenharmony_ci int fd, mode, rc, nb; 2722141cc406Sopenharmony_ci unsigned char bval; 2723141cc406Sopenharmony_ci#endif 2724141cc406Sopenharmony_ci int control; 2725141cc406Sopenharmony_ci 2726141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2727141cc406Sopenharmony_ci /* check we have ppdev working */ 2728141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 2729141cc406Sopenharmony_ci if (fd > 0) 2730141cc406Sopenharmony_ci { 2731141cc406Sopenharmony_ci 2732141cc406Sopenharmony_ci bval = 0x80; 2733141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 2734141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2735141cc406Sopenharmony_ci if (rc) 2736141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2737141cc406Sopenharmony_ci __FILE__, __LINE__); 2738141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 2739141cc406Sopenharmony_ci 2740141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 2741141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 2742141cc406Sopenharmony_ci if (rc) 2743141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2744141cc406Sopenharmony_ci __FILE__, __LINE__); 2745141cc406Sopenharmony_ci#ifdef PPSETFLAGS 2746141cc406Sopenharmony_ci mode = PP_FASTREAD; 2747141cc406Sopenharmony_ci rc = ioctl (fd, PPSETFLAGS, &mode); 2748141cc406Sopenharmony_ci if (rc) 2749141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2750141cc406Sopenharmony_ci __FILE__, __LINE__); 2751141cc406Sopenharmony_ci#endif 2752141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 2753141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2754141cc406Sopenharmony_ci if (rc) 2755141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2756141cc406Sopenharmony_ci __FILE__, __LINE__); 2757141cc406Sopenharmony_ci nb = 0; 2758141cc406Sopenharmony_ci while (nb < size - 1) 2759141cc406Sopenharmony_ci { 2760141cc406Sopenharmony_ci rc = read (fd, dest + nb, size - 1 - nb); 2761141cc406Sopenharmony_ci nb += rc; 2762141cc406Sopenharmony_ci } 2763141cc406Sopenharmony_ci 2764141cc406Sopenharmony_ci mode = 0; /* forward */ 2765141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 2766141cc406Sopenharmony_ci if (rc) 2767141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2768141cc406Sopenharmony_ci __FILE__, __LINE__); 2769141cc406Sopenharmony_ci bval = 0xA0; 2770141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 2771141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2772141cc406Sopenharmony_ci if (rc) 2773141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2774141cc406Sopenharmony_ci __FILE__, __LINE__); 2775141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 2776141cc406Sopenharmony_ci 2777141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 2778141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 2779141cc406Sopenharmony_ci if (rc) 2780141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2781141cc406Sopenharmony_ci __FILE__, __LINE__); 2782141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 2783141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2784141cc406Sopenharmony_ci if (rc) 2785141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2786141cc406Sopenharmony_ci __FILE__, __LINE__); 2787141cc406Sopenharmony_ci rc = read (fd, dest + size - 1, 1); 2788141cc406Sopenharmony_ci 2789141cc406Sopenharmony_ci mode = 0; /* forward */ 2790141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 2791141cc406Sopenharmony_ci if (rc) 2792141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2793141cc406Sopenharmony_ci __FILE__, __LINE__); 2794141cc406Sopenharmony_ci 2795141cc406Sopenharmony_ci return; 2796141cc406Sopenharmony_ci } 2797141cc406Sopenharmony_ci /* if not, direct hardware access */ 2798141cc406Sopenharmony_ci#endif 2799141cc406Sopenharmony_ci 2800141cc406Sopenharmony_ci EPPBlockMode (0x80); 2801141cc406Sopenharmony_ci control = Inb (CONTROL); 2802141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F) | 0x20); /* reverse */ 2803141cc406Sopenharmony_ci Insb (EPPDATA, dest, size - 1); 2804141cc406Sopenharmony_ci control = Inb (CONTROL); 2805141cc406Sopenharmony_ci 2806141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F)); /* forward */ 2807141cc406Sopenharmony_ci EPPBlockMode (0xA0); 2808141cc406Sopenharmony_ci control = Inb (CONTROL); 2809141cc406Sopenharmony_ci 2810141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F) | 0x20); /* reverse */ 2811141cc406Sopenharmony_ci Insb (EPPDATA, (unsigned char *) (dest + size - 1), 1); 2812141cc406Sopenharmony_ci 2813141cc406Sopenharmony_ci control = Inb (CONTROL); 2814141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F)); /* forward */ 2815141cc406Sopenharmony_ci} 2816141cc406Sopenharmony_ci 2817141cc406Sopenharmony_ci 2818141cc406Sopenharmony_ci/* block transfer init */ 2819141cc406Sopenharmony_cistatic void 2820141cc406Sopenharmony_ciECPSetBuffer (int size) 2821141cc406Sopenharmony_ci{ 2822141cc406Sopenharmony_ci static int last = 0; 2823141cc406Sopenharmony_ci 2824141cc406Sopenharmony_ci /* routine XX */ 2825141cc406Sopenharmony_ci compatMode (); 2826141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset ? */ 2827141cc406Sopenharmony_ci 2828141cc406Sopenharmony_ci /* we set size only if it has changed */ 2829141cc406Sopenharmony_ci /* from last time */ 2830141cc406Sopenharmony_ci if (size == last) 2831141cc406Sopenharmony_ci return; 2832141cc406Sopenharmony_ci last = size; 2833141cc406Sopenharmony_ci 2834141cc406Sopenharmony_ci /* mode and size setting */ 2835141cc406Sopenharmony_ci ECPFifoMode (); /*Outb (ECR, 0x60); */ 2836141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2837141cc406Sopenharmony_ci { 2838141cc406Sopenharmony_ci DBG (0, "ECPSetBuffer failed, time-out waiting for FIFO (%s:%d)\n", 2839141cc406Sopenharmony_ci __FILE__, __LINE__); 2840141cc406Sopenharmony_ci return; 2841141cc406Sopenharmony_ci } 2842141cc406Sopenharmony_ci Inb (ECR); 2843141cc406Sopenharmony_ci 2844141cc406Sopenharmony_ci Outb (DATA, 0x0E); 2845141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2846141cc406Sopenharmony_ci { 2847141cc406Sopenharmony_ci DBG (0, "ECPSetBuffer failed, time-out waiting for FIFO (%s:%d)\n", 2848141cc406Sopenharmony_ci __FILE__, __LINE__); 2849141cc406Sopenharmony_ci return; 2850141cc406Sopenharmony_ci } 2851141cc406Sopenharmony_ci Inb (ECR); 2852141cc406Sopenharmony_ci 2853141cc406Sopenharmony_ci Outb (ECPDATA, 0x0B); /* R0E=0x0B */ 2854141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2855141cc406Sopenharmony_ci { 2856141cc406Sopenharmony_ci DBG (0, "ECPSetBuffer failed, time-out waiting for FIFO (%s:%d)\n", 2857141cc406Sopenharmony_ci __FILE__, __LINE__); 2858141cc406Sopenharmony_ci return; 2859141cc406Sopenharmony_ci } 2860141cc406Sopenharmony_ci Inb (ECR); 2861141cc406Sopenharmony_ci 2862141cc406Sopenharmony_ci Outb (DATA, 0x0F); /* R0F=size MSB */ 2863141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2864141cc406Sopenharmony_ci { 2865141cc406Sopenharmony_ci DBG (0, "ECPSetBuffer failed, time-out waiting for FIFO (%s:%d)\n", 2866141cc406Sopenharmony_ci __FILE__, __LINE__); 2867141cc406Sopenharmony_ci return; 2868141cc406Sopenharmony_ci } 2869141cc406Sopenharmony_ci Inb (ECR); 2870141cc406Sopenharmony_ci 2871141cc406Sopenharmony_ci Outb (ECPDATA, size / 256); 2872141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2873141cc406Sopenharmony_ci { 2874141cc406Sopenharmony_ci DBG (0, "ECPSetBuffer failed, time-out waiting for FIFO (%s:%d)\n", 2875141cc406Sopenharmony_ci __FILE__, __LINE__); 2876141cc406Sopenharmony_ci return; 2877141cc406Sopenharmony_ci } 2878141cc406Sopenharmony_ci Inb (ECR); 2879141cc406Sopenharmony_ci 2880141cc406Sopenharmony_ci Outb (DATA, 0x0B); /* R0B=size LSB */ 2881141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2882141cc406Sopenharmony_ci { 2883141cc406Sopenharmony_ci DBG (0, "ECPSetBuffer failed, time-out waiting for FIFO (%s:%d)\n", 2884141cc406Sopenharmony_ci __FILE__, __LINE__); 2885141cc406Sopenharmony_ci return; 2886141cc406Sopenharmony_ci } 2887141cc406Sopenharmony_ci Inb (ECR); 2888141cc406Sopenharmony_ci 2889141cc406Sopenharmony_ci Outb (ECPDATA, size % 256); 2890141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2891141cc406Sopenharmony_ci { 2892141cc406Sopenharmony_ci DBG (0, "ECPSetBuffer failed, time-out waiting for FIFO (%s:%d)\n", 2893141cc406Sopenharmony_ci __FILE__, __LINE__); 2894141cc406Sopenharmony_ci return; 2895141cc406Sopenharmony_ci } 2896141cc406Sopenharmony_ci Inb (ECR); 2897141cc406Sopenharmony_ci DBG (16, "ECPSetBuffer(%d) passed ...\n", size); 2898141cc406Sopenharmony_ci} 2899141cc406Sopenharmony_ci 2900141cc406Sopenharmony_ci 2901141cc406Sopenharmony_ci 2902141cc406Sopenharmony_cistatic int 2903141cc406Sopenharmony_ciECPbufferRead (int size, unsigned char *dest) 2904141cc406Sopenharmony_ci{ 2905141cc406Sopenharmony_ci int n, idx, remain; 2906141cc406Sopenharmony_ci 2907141cc406Sopenharmony_ci idx = 0; 2908141cc406Sopenharmony_ci n = size / 16; 2909141cc406Sopenharmony_ci remain = size - 16 * n; 2910141cc406Sopenharmony_ci 2911141cc406Sopenharmony_ci /* block transfer */ 2912141cc406Sopenharmony_ci Inb (ECR); /* 0x15,0x75 expected: fifo empty */ 2913141cc406Sopenharmony_ci 2914141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); byte mode */ 2915141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 2916141cc406Sopenharmony_ci 2917141cc406Sopenharmony_ci ECPFifoMode (); /*Outb (ECR, 0x60); */ 2918141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2919141cc406Sopenharmony_ci { 2920141cc406Sopenharmony_ci DBG (0, "ECPbufferRead failed, time-out waiting for FIFO (%s:%d)\n", 2921141cc406Sopenharmony_ci __FILE__, __LINE__); 2922141cc406Sopenharmony_ci return idx; 2923141cc406Sopenharmony_ci } 2924141cc406Sopenharmony_ci Inb (ECR); 2925141cc406Sopenharmony_ci 2926141cc406Sopenharmony_ci Outb (DATA, 0x80); 2927141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 2928141cc406Sopenharmony_ci { 2929141cc406Sopenharmony_ci DBG (0, "ECPbufferRead failed, time-out waiting for FIFO (%s:%d)\n", 2930141cc406Sopenharmony_ci __FILE__, __LINE__); 2931141cc406Sopenharmony_ci return idx; 2932141cc406Sopenharmony_ci } 2933141cc406Sopenharmony_ci Inb (ECR); /* 0x75 expected */ 2934141cc406Sopenharmony_ci 2935141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); byte mode */ 2936141cc406Sopenharmony_ci Outb (CONTROL, 0x20); /* data reverse */ 2937141cc406Sopenharmony_ci ECPFifoMode (); /*Outb (ECR, 0x60); */ 2938141cc406Sopenharmony_ci 2939141cc406Sopenharmony_ci while (n > 0) 2940141cc406Sopenharmony_ci { 2941141cc406Sopenharmony_ci if (waitFifoFull () == 0) 2942141cc406Sopenharmony_ci { 2943141cc406Sopenharmony_ci DBG (0, 2944141cc406Sopenharmony_ci "ECPbufferRead failed, time-out waiting for FIFO idx=%d (%s:%d)\n", 2945141cc406Sopenharmony_ci idx, __FILE__, __LINE__); 2946141cc406Sopenharmony_ci return idx; 2947141cc406Sopenharmony_ci } 2948141cc406Sopenharmony_ci Insb (ECPDATA, dest + idx, 16); 2949141cc406Sopenharmony_ci idx += 16; 2950141cc406Sopenharmony_ci n--; 2951141cc406Sopenharmony_ci } 2952141cc406Sopenharmony_ci 2953141cc406Sopenharmony_ci /* reading trailing bytes */ 2954141cc406Sopenharmony_ci while (remain > 0) 2955141cc406Sopenharmony_ci { 2956141cc406Sopenharmony_ci if (waitFifoNotEmpty () == 0) 2957141cc406Sopenharmony_ci { 2958141cc406Sopenharmony_ci DBG (0, "ECPbufferRead failed, FIFO time-out (%s:%d)\n", 2959141cc406Sopenharmony_ci __FILE__, __LINE__); 2960141cc406Sopenharmony_ci } 2961141cc406Sopenharmony_ci dest[idx] = Inb (ECPDATA); 2962141cc406Sopenharmony_ci idx++; 2963141cc406Sopenharmony_ci remain--; 2964141cc406Sopenharmony_ci } 2965141cc406Sopenharmony_ci 2966141cc406Sopenharmony_ci return idx; 2967141cc406Sopenharmony_ci} 2968141cc406Sopenharmony_ci 2969141cc406Sopenharmony_cistatic void 2970141cc406Sopenharmony_ciEPPbufferWrite (int size, unsigned char *source) 2971141cc406Sopenharmony_ci{ 2972141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2973141cc406Sopenharmony_ci int fd, mode, rc; 2974141cc406Sopenharmony_ci unsigned char bval; 2975141cc406Sopenharmony_ci#endif 2976141cc406Sopenharmony_ci 2977141cc406Sopenharmony_ci 2978141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 2979141cc406Sopenharmony_ci /* check we have ppdev working */ 2980141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 2981141cc406Sopenharmony_ci if (fd > 0) 2982141cc406Sopenharmony_ci { 2983141cc406Sopenharmony_ci bval = 0xC0; 2984141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 2985141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2986141cc406Sopenharmony_ci if (rc) 2987141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2988141cc406Sopenharmony_ci __FILE__, __LINE__); 2989141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 2990141cc406Sopenharmony_ci 2991141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 2992141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 2993141cc406Sopenharmony_ci if (rc) 2994141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 2995141cc406Sopenharmony_ci __FILE__, __LINE__); 2996141cc406Sopenharmony_ci rc = write (fd, source, size); 2997141cc406Sopenharmony_ci return; 2998141cc406Sopenharmony_ci } 2999141cc406Sopenharmony_ci /* if not, direct hardware access */ 3000141cc406Sopenharmony_ci#endif 3001141cc406Sopenharmony_ci EPPBlockMode (0xC0); 3002141cc406Sopenharmony_ci Outsb (EPPDATA, source, size); 3003141cc406Sopenharmony_ci} 3004141cc406Sopenharmony_ci 3005141cc406Sopenharmony_cistatic void 3006141cc406Sopenharmony_ciECPbufferWrite (int size, unsigned char *source) 3007141cc406Sopenharmony_ci{ 3008141cc406Sopenharmony_ci unsigned char breg; 3009141cc406Sopenharmony_ci int n, idx; 3010141cc406Sopenharmony_ci 3011141cc406Sopenharmony_ci /* until we know to handle that case, fail */ 3012141cc406Sopenharmony_ci if (size % 16 != 0) 3013141cc406Sopenharmony_ci { 3014141cc406Sopenharmony_ci DBG (0, "ECPbufferWrite failed, size %%16 !=0 (%s:%d)\n", 3015141cc406Sopenharmony_ci __FILE__, __LINE__); 3016141cc406Sopenharmony_ci return; 3017141cc406Sopenharmony_ci } 3018141cc406Sopenharmony_ci 3019141cc406Sopenharmony_ci /* prepare actual transfer */ 3020141cc406Sopenharmony_ci compatMode (); 3021141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset ? */ 3022141cc406Sopenharmony_ci breg = Inb (CONTROL); 3023141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* data forward */ 3024141cc406Sopenharmony_ci ECPFifoMode (); /*Outb (ECR, 0x60); */ 3025141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 3026141cc406Sopenharmony_ci { 3027141cc406Sopenharmony_ci DBG (0, "ECPWriteBuffer failed, time-out waiting for FIFO (%s:%d)\n", 3028141cc406Sopenharmony_ci __FILE__, __LINE__); 3029141cc406Sopenharmony_ci return; 3030141cc406Sopenharmony_ci } 3031141cc406Sopenharmony_ci breg = Inb (ECR); 3032141cc406Sopenharmony_ci breg = (Inb (STATUS)) & 0xF8; 3033141cc406Sopenharmony_ci n = 0; 3034141cc406Sopenharmony_ci while ((n < 1024) && (breg != 0xF8)) 3035141cc406Sopenharmony_ci { 3036141cc406Sopenharmony_ci breg = (Inb (STATUS)) & 0xF8; 3037141cc406Sopenharmony_ci n++; 3038141cc406Sopenharmony_ci } 3039141cc406Sopenharmony_ci if (breg != 0xF8) 3040141cc406Sopenharmony_ci { 3041141cc406Sopenharmony_ci DBG (0, 3042141cc406Sopenharmony_ci "ECPbufferWrite failed, expected status=0xF8, got 0x%02X (%s:%d)\n", 3043141cc406Sopenharmony_ci breg, __FILE__, __LINE__); 3044141cc406Sopenharmony_ci return; 3045141cc406Sopenharmony_ci } 3046141cc406Sopenharmony_ci 3047141cc406Sopenharmony_ci /* wait for FIFO empty (bit 0) */ 3048141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 3049141cc406Sopenharmony_ci { 3050141cc406Sopenharmony_ci DBG (0, "ECPbufferWrite failed, time-out waiting for FIFO (%s:%d)\n", 3051141cc406Sopenharmony_ci __FILE__, __LINE__); 3052141cc406Sopenharmony_ci return; 3053141cc406Sopenharmony_ci } 3054141cc406Sopenharmony_ci breg = Inb (ECR); 3055141cc406Sopenharmony_ci 3056141cc406Sopenharmony_ci /* block transfer direction 3057141cc406Sopenharmony_ci * 0x80 means from scanner to PC, 0xC0 means PC to scanner 3058141cc406Sopenharmony_ci */ 3059141cc406Sopenharmony_ci Outb (DATA, 0xC0); 3060141cc406Sopenharmony_ci 3061141cc406Sopenharmony_ci n = size / 16; 3062141cc406Sopenharmony_ci idx = 0; 3063141cc406Sopenharmony_ci while (n > 0) 3064141cc406Sopenharmony_ci { 3065141cc406Sopenharmony_ci /* wait for FIFO empty */ 3066141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 3067141cc406Sopenharmony_ci { 3068141cc406Sopenharmony_ci DBG (0, 3069141cc406Sopenharmony_ci "ECPbufferWrite failed, time-out waiting for FIFO (%s:%d)\n", 3070141cc406Sopenharmony_ci __FILE__, __LINE__); 3071141cc406Sopenharmony_ci return; 3072141cc406Sopenharmony_ci } 3073141cc406Sopenharmony_ci breg = Inb (ECR); 3074141cc406Sopenharmony_ci 3075141cc406Sopenharmony_ci Outsb (ECPDATA, source + idx * 16, 16); 3076141cc406Sopenharmony_ci idx++; 3077141cc406Sopenharmony_ci n--; 3078141cc406Sopenharmony_ci } 3079141cc406Sopenharmony_ci 3080141cc406Sopenharmony_ci 3081141cc406Sopenharmony_ci /* final FIFO check and go to Byte mode */ 3082141cc406Sopenharmony_ci if (waitFifoEmpty () == 0) 3083141cc406Sopenharmony_ci { 3084141cc406Sopenharmony_ci DBG (0, "ECPbufferWrite failed, time-out waiting for FIFO (%s:%d)\n", 3085141cc406Sopenharmony_ci __FILE__, __LINE__); 3086141cc406Sopenharmony_ci return; 3087141cc406Sopenharmony_ci } 3088141cc406Sopenharmony_ci breg = Inb (ECR); 3089141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 3090141cc406Sopenharmony_ci byteMode (); 3091141cc406Sopenharmony_ci} 3092141cc406Sopenharmony_ci 3093141cc406Sopenharmony_cistatic void 3094141cc406Sopenharmony_cibufferWrite (int size, unsigned char *source) 3095141cc406Sopenharmony_ci{ 3096141cc406Sopenharmony_ci switch (gMode) 3097141cc406Sopenharmony_ci { 3098141cc406Sopenharmony_ci case UMAX_PP_PARPORT_PS2: 3099141cc406Sopenharmony_ci PS2bufferWrite (size, source); 3100141cc406Sopenharmony_ci DBG (0, "STEF: gMode PS2 in bufferWrite !!\n"); 3101141cc406Sopenharmony_ci break; 3102141cc406Sopenharmony_ci case UMAX_PP_PARPORT_ECP: 3103141cc406Sopenharmony_ci ECPbufferWrite (size, source); 3104141cc406Sopenharmony_ci break; 3105141cc406Sopenharmony_ci case UMAX_PP_PARPORT_EPP: 3106141cc406Sopenharmony_ci switch (getEPPMode ()) 3107141cc406Sopenharmony_ci { 3108141cc406Sopenharmony_ci case 32: 3109141cc406Sopenharmony_ci EPPWrite32Buffer (size, source); 3110141cc406Sopenharmony_ci break; 3111141cc406Sopenharmony_ci default: 3112141cc406Sopenharmony_ci EPPbufferWrite (size, source); 3113141cc406Sopenharmony_ci break; 3114141cc406Sopenharmony_ci } 3115141cc406Sopenharmony_ci break; 3116141cc406Sopenharmony_ci default: 3117141cc406Sopenharmony_ci DBG (0, "STEF: gMode PS2 in bufferWrite !!\n"); 3118141cc406Sopenharmony_ci break; 3119141cc406Sopenharmony_ci } 3120141cc406Sopenharmony_ci return; 3121141cc406Sopenharmony_ci} 3122141cc406Sopenharmony_ci 3123141cc406Sopenharmony_cistatic void 3124141cc406Sopenharmony_cibufferRead (int size, unsigned char *dest) 3125141cc406Sopenharmony_ci{ 3126141cc406Sopenharmony_ci switch (gMode) 3127141cc406Sopenharmony_ci { 3128141cc406Sopenharmony_ci case UMAX_PP_PARPORT_PS2: 3129141cc406Sopenharmony_ci PS2bufferRead (size, dest); 3130141cc406Sopenharmony_ci DBG (0, "STEF: gMode PS2 in bufferRead !!\n"); 3131141cc406Sopenharmony_ci break; 3132141cc406Sopenharmony_ci case UMAX_PP_PARPORT_ECP: 3133141cc406Sopenharmony_ci ECPbufferRead (size, dest); 3134141cc406Sopenharmony_ci break; 3135141cc406Sopenharmony_ci case UMAX_PP_PARPORT_EPP: 3136141cc406Sopenharmony_ci switch (getEPPMode ()) 3137141cc406Sopenharmony_ci { 3138141cc406Sopenharmony_ci case 32: 3139141cc406Sopenharmony_ci EPPRead32Buffer (size, dest); 3140141cc406Sopenharmony_ci break; 3141141cc406Sopenharmony_ci default: 3142141cc406Sopenharmony_ci EPPbufferRead (size, dest); 3143141cc406Sopenharmony_ci break; 3144141cc406Sopenharmony_ci } 3145141cc406Sopenharmony_ci break; 3146141cc406Sopenharmony_ci default: 3147141cc406Sopenharmony_ci DBG (0, "STEF: gMode unset in bufferRead !!\n"); 3148141cc406Sopenharmony_ci break; 3149141cc406Sopenharmony_ci } 3150141cc406Sopenharmony_ci return; 3151141cc406Sopenharmony_ci} 3152141cc406Sopenharmony_ci 3153141cc406Sopenharmony_cistatic int 3154141cc406Sopenharmony_ciconnect (void) 3155141cc406Sopenharmony_ci{ 3156141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 3157141cc406Sopenharmony_ci return connect610p (); 3158141cc406Sopenharmony_ci 3159141cc406Sopenharmony_ci switch (gMode) 3160141cc406Sopenharmony_ci { 3161141cc406Sopenharmony_ci case UMAX_PP_PARPORT_PS2: 3162141cc406Sopenharmony_ci DBG (0, "STEF: unimplemented gMode PS2 in connect() !!\n"); 3163141cc406Sopenharmony_ci return 0; 3164141cc406Sopenharmony_ci break; 3165141cc406Sopenharmony_ci case UMAX_PP_PARPORT_ECP: 3166141cc406Sopenharmony_ci return ECPconnect (); 3167141cc406Sopenharmony_ci break; 3168141cc406Sopenharmony_ci case UMAX_PP_PARPORT_BYTE: 3169141cc406Sopenharmony_ci DBG (0, "STEF: unimplemented gMode BYTE in connect() !!\n"); 3170141cc406Sopenharmony_ci return 0; 3171141cc406Sopenharmony_ci break; 3172141cc406Sopenharmony_ci case UMAX_PP_PARPORT_EPP: 3173141cc406Sopenharmony_ci return EPPconnect (); 3174141cc406Sopenharmony_ci default: 3175141cc406Sopenharmony_ci DBG (0, "STEF: gMode unset in connect() !!\n"); 3176141cc406Sopenharmony_ci break; 3177141cc406Sopenharmony_ci } 3178141cc406Sopenharmony_ci return 0; 3179141cc406Sopenharmony_ci} 3180141cc406Sopenharmony_ci 3181141cc406Sopenharmony_ci 3182141cc406Sopenharmony_cistatic void 3183141cc406Sopenharmony_cidisconnect (void) 3184141cc406Sopenharmony_ci{ 3185141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 3186141cc406Sopenharmony_ci disconnect610p (); 3187141cc406Sopenharmony_ci switch (gMode) 3188141cc406Sopenharmony_ci { 3189141cc406Sopenharmony_ci case UMAX_PP_PARPORT_PS2: 3190141cc406Sopenharmony_ci DBG (0, "STEF: unimplemented gMode PS2 in disconnect() !!\n"); 3191141cc406Sopenharmony_ci break; 3192141cc406Sopenharmony_ci case UMAX_PP_PARPORT_ECP: 3193141cc406Sopenharmony_ci ECPdisconnect (); 3194141cc406Sopenharmony_ci break; 3195141cc406Sopenharmony_ci case UMAX_PP_PARPORT_BYTE: 3196141cc406Sopenharmony_ci DBG (0, "STEF: unimplemented gMode BYTE in disconnect() !!\n"); 3197141cc406Sopenharmony_ci break; 3198141cc406Sopenharmony_ci case UMAX_PP_PARPORT_EPP: 3199141cc406Sopenharmony_ci EPPdisconnect (); 3200141cc406Sopenharmony_ci break; 3201141cc406Sopenharmony_ci default: 3202141cc406Sopenharmony_ci DBG (0, "STEF: gMode unset in disconnect() !!\n"); 3203141cc406Sopenharmony_ci break; 3204141cc406Sopenharmony_ci } 3205141cc406Sopenharmony_ci} 3206141cc406Sopenharmony_ci 3207141cc406Sopenharmony_ci 3208141cc406Sopenharmony_ci/* returns 0 if mode OK, else -1 */ 3209141cc406Sopenharmony_cistatic int 3210141cc406Sopenharmony_cicheckEPAT (void) 3211141cc406Sopenharmony_ci{ 3212141cc406Sopenharmony_ci int version; 3213141cc406Sopenharmony_ci 3214141cc406Sopenharmony_ci version = registerRead (0x0B); 3215141cc406Sopenharmony_ci if (version == 0xC7) 3216141cc406Sopenharmony_ci return 0; 3217141cc406Sopenharmony_ci DBG (0, "checkEPAT: expected EPAT version 0xC7, got 0x%X! (%s:%d)\n", 3218141cc406Sopenharmony_ci version, __FILE__, __LINE__); 3219141cc406Sopenharmony_ci return -1; 3220141cc406Sopenharmony_ci 3221141cc406Sopenharmony_ci} 3222141cc406Sopenharmony_ci 3223141cc406Sopenharmony_cistatic int 3224141cc406Sopenharmony_ciinit005 (int arg) 3225141cc406Sopenharmony_ci{ 3226141cc406Sopenharmony_ci int count = 5; 3227141cc406Sopenharmony_ci int res; 3228141cc406Sopenharmony_ci 3229141cc406Sopenharmony_ci while (count > 0) 3230141cc406Sopenharmony_ci { 3231141cc406Sopenharmony_ci registerWrite (0x0A, arg); 3232141cc406Sopenharmony_ci Outb (DATA, 0xFF); 3233141cc406Sopenharmony_ci res = registerRead (0x0A); 3234141cc406Sopenharmony_ci 3235141cc406Sopenharmony_ci /* failed ? */ 3236141cc406Sopenharmony_ci if (res != arg) 3237141cc406Sopenharmony_ci return 1; 3238141cc406Sopenharmony_ci 3239141cc406Sopenharmony_ci /* ror arg */ 3240141cc406Sopenharmony_ci res = arg & 0x01; 3241141cc406Sopenharmony_ci arg = arg / 2; 3242141cc406Sopenharmony_ci if (res == 1) 3243141cc406Sopenharmony_ci arg = arg | 0x80; 3244141cc406Sopenharmony_ci 3245141cc406Sopenharmony_ci /* next loop */ 3246141cc406Sopenharmony_ci count--; 3247141cc406Sopenharmony_ci } 3248141cc406Sopenharmony_ci return 0; 3249141cc406Sopenharmony_ci} 3250141cc406Sopenharmony_ci 3251141cc406Sopenharmony_ci/* write 1 byte in EPP mode, returning scnner's status */ 3252141cc406Sopenharmony_cistatic int 3253141cc406Sopenharmony_ciEPPputByte610p (int data) 3254141cc406Sopenharmony_ci{ 3255141cc406Sopenharmony_ci int status, control; 3256141cc406Sopenharmony_ci 3257141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3258141cc406Sopenharmony_ci if ((status != 0xC8) && (status != 0xC0) && (status != 0xD0)) 3259141cc406Sopenharmony_ci { 3260141cc406Sopenharmony_ci DBG (0, 3261141cc406Sopenharmony_ci "EPPputByte610p failed, expected 0xC8, 0xD0 or 0xC0 got 0x%02X ! (%s:%d)\n", 3262141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3263141cc406Sopenharmony_ci return 0; 3264141cc406Sopenharmony_ci } 3265141cc406Sopenharmony_ci control = (Inb (CONTROL) & 0x44) | 0x44; /* data forward, bit 5 cleared (!!) */ 3266141cc406Sopenharmony_ci Outb (CONTROL, control); 3267141cc406Sopenharmony_ci Outb (EPPDATA, data); 3268141cc406Sopenharmony_ci return status; 3269141cc406Sopenharmony_ci} 3270141cc406Sopenharmony_ci 3271141cc406Sopenharmony_cistatic int 3272141cc406Sopenharmony_ciputByte610p (int data) 3273141cc406Sopenharmony_ci{ 3274141cc406Sopenharmony_ci int status, control, j; 3275141cc406Sopenharmony_ci 3276141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 3277141cc406Sopenharmony_ci return EPPputByte610p (data); 3278141cc406Sopenharmony_ci j = 0; 3279141cc406Sopenharmony_ci do 3280141cc406Sopenharmony_ci { 3281141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3282141cc406Sopenharmony_ci j++; 3283141cc406Sopenharmony_ci } 3284141cc406Sopenharmony_ci while ((j < 20) && (status & 0x08)); 3285141cc406Sopenharmony_ci 3286141cc406Sopenharmony_ci if ((status != 0xC8) && (status != 0xC0)) 3287141cc406Sopenharmony_ci { 3288141cc406Sopenharmony_ci DBG (0, 3289141cc406Sopenharmony_ci "putByte610p failed, expected 0xC8 or 0xC0 got 0x%02X ! (%s:%d)\n", 3290141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3291141cc406Sopenharmony_ci return 0; 3292141cc406Sopenharmony_ci } 3293141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x1F; /* data forward */ 3294141cc406Sopenharmony_ci Outb (CONTROL, control); 3295141cc406Sopenharmony_ci 3296141cc406Sopenharmony_ci Outb (DATA, data); 3297141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 3298141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3299141cc406Sopenharmony_ci if ((status != 0x48) && (status != 0x40)) 3300141cc406Sopenharmony_ci { 3301141cc406Sopenharmony_ci DBG (0, 3302141cc406Sopenharmony_ci "putByte610p failed, expected 0x48 or 0x40 got 0x%02X ! (%s:%d)\n", 3303141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3304141cc406Sopenharmony_ci return 0; 3305141cc406Sopenharmony_ci } 3306141cc406Sopenharmony_ci 3307141cc406Sopenharmony_ci 3308141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 3309141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3310141cc406Sopenharmony_ci Outb (CONTROL, control); 3311141cc406Sopenharmony_ci return status; 3312141cc406Sopenharmony_ci} 3313141cc406Sopenharmony_ci 3314141cc406Sopenharmony_ci 3315141cc406Sopenharmony_ci/* 1 OK, 0 failure */ 3316141cc406Sopenharmony_cistatic int 3317141cc406Sopenharmony_cisync610p (void) 3318141cc406Sopenharmony_ci{ 3319141cc406Sopenharmony_ci int status; 3320141cc406Sopenharmony_ci 3321141cc406Sopenharmony_ci Outb (DATA, 0x40); 3322141cc406Sopenharmony_ci Outb (CONTROL, 0x06); 3323141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3324141cc406Sopenharmony_ci if (status != 0x38) 3325141cc406Sopenharmony_ci { 3326141cc406Sopenharmony_ci DBG (0, "sync610p failed (got 0x%02X expected 0x38)! (%s:%d)\n", 3327141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3328141cc406Sopenharmony_ci return 0; 3329141cc406Sopenharmony_ci } 3330141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 3331141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3332141cc406Sopenharmony_ci if (status != 0x38) 3333141cc406Sopenharmony_ci { 3334141cc406Sopenharmony_ci DBG (0, "sync610p failed (got 0x%02X expected 0x38)! (%s:%d)\n", 3335141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3336141cc406Sopenharmony_ci return 0; 3337141cc406Sopenharmony_ci } 3338141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 3339141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3340141cc406Sopenharmony_ci if (status != 0xF8) 3341141cc406Sopenharmony_ci { 3342141cc406Sopenharmony_ci DBG (0, "sync610p failed (got 0x%02X expected 0xF8)! (%s:%d)\n", 3343141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3344141cc406Sopenharmony_ci return 0; 3345141cc406Sopenharmony_ci } 3346141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 3347141cc406Sopenharmony_ci Inb (CONTROL); /* 0x05 expected */ 3348141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 3349141cc406Sopenharmony_ci return 1; 3350141cc406Sopenharmony_ci} 3351141cc406Sopenharmony_ci 3352141cc406Sopenharmony_cistatic int 3353141cc406Sopenharmony_ciEPPcmdSync610p (int cmd) 3354141cc406Sopenharmony_ci{ 3355141cc406Sopenharmony_ci int word[5]; 3356141cc406Sopenharmony_ci int status; 3357141cc406Sopenharmony_ci int i; 3358141cc406Sopenharmony_ci 3359141cc406Sopenharmony_ci word[0] = 0; 3360141cc406Sopenharmony_ci word[1] = 0; 3361141cc406Sopenharmony_ci word[2] = 0; 3362141cc406Sopenharmony_ci word[3] = cmd; 3363141cc406Sopenharmony_ci 3364141cc406Sopenharmony_ci connect610p (); 3365141cc406Sopenharmony_ci sync610p (); 3366141cc406Sopenharmony_ci 3367141cc406Sopenharmony_ci /* sends magic seal 55 AA */ 3368141cc406Sopenharmony_ci status = EPPputByte610p (0x55); 3369141cc406Sopenharmony_ci if ((status != 0xC8) && (status != 0xC0) && (status != 0xD0)) 3370141cc406Sopenharmony_ci { 3371141cc406Sopenharmony_ci DBG (1, 3372141cc406Sopenharmony_ci "EPPcmdSync610p: Found 0x%X expected 0xC8, 0xC0 or 0xD0 (%s:%d)\n", 3373141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3374141cc406Sopenharmony_ci return 0; 3375141cc406Sopenharmony_ci } 3376141cc406Sopenharmony_ci status = EPPputByte610p (0xAA); 3377141cc406Sopenharmony_ci if ((status != 0xC8) && (status != 0xC0) && (status != 0xD0)) 3378141cc406Sopenharmony_ci { 3379141cc406Sopenharmony_ci DBG (1, 3380141cc406Sopenharmony_ci "EPPcmdSync610p: Found 0x%X expected 0xC8, 0xC0 or 0xD0 (%s:%d)\n", 3381141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3382141cc406Sopenharmony_ci return 0; 3383141cc406Sopenharmony_ci } 3384141cc406Sopenharmony_ci 3385141cc406Sopenharmony_ci status = EPPgetStatus610p (); 3386141cc406Sopenharmony_ci if (status == 0xC0) 3387141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 3388141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3389141cc406Sopenharmony_ci if (status != 0xC8) 3390141cc406Sopenharmony_ci { 3391141cc406Sopenharmony_ci DBG (0, "EPPcmdSync610p: Found 0x%X expected 0xC8 (%s:%d)\n", status, 3392141cc406Sopenharmony_ci __FILE__, __LINE__); 3393141cc406Sopenharmony_ci /*return 0; */ 3394141cc406Sopenharmony_ci } 3395141cc406Sopenharmony_ci 3396141cc406Sopenharmony_ci /* sends 4 bytes of data */ 3397141cc406Sopenharmony_ci for (i = 0; i < 4; i++) 3398141cc406Sopenharmony_ci { 3399141cc406Sopenharmony_ci status = EPPputByte610p (word[i]); 3400141cc406Sopenharmony_ci } 3401141cc406Sopenharmony_ci if (status != 0xC8) 3402141cc406Sopenharmony_ci { 3403141cc406Sopenharmony_ci DBG (0, "EPPcmdSync610p: Found 0x%X expected 0xC8 (%s:%d)\n", status, 3404141cc406Sopenharmony_ci __FILE__, __LINE__); 3405141cc406Sopenharmony_ci /*return 0; */ 3406141cc406Sopenharmony_ci } 3407141cc406Sopenharmony_ci 3408141cc406Sopenharmony_ci /* tests status */ 3409141cc406Sopenharmony_ci Outb (DATA, 0xFF); 3410141cc406Sopenharmony_ci if (cmd == 0xC2) 3411141cc406Sopenharmony_ci { 3412141cc406Sopenharmony_ci status = EPPgetStatus610p (); 3413141cc406Sopenharmony_ci if (status != 0xC0) 3414141cc406Sopenharmony_ci { 3415141cc406Sopenharmony_ci DBG (0, "EPPcmdSync610p: Found 0x%X expected 0xC0 (%s:%d)\n", 3416141cc406Sopenharmony_ci status, __FILE__, __LINE__); 3417141cc406Sopenharmony_ci /*return 0; */ 3418141cc406Sopenharmony_ci } 3419141cc406Sopenharmony_ci } 3420141cc406Sopenharmony_ci status = EPPgetStatus610p (); 3421141cc406Sopenharmony_ci if (status != 0xC0) 3422141cc406Sopenharmony_ci { 3423141cc406Sopenharmony_ci DBG (0, "EPPcmdSync610p: Found 0x%X expected 0xC0 (%s:%d)\n", status, 3424141cc406Sopenharmony_ci __FILE__, __LINE__); 3425141cc406Sopenharmony_ci /*return 0; */ 3426141cc406Sopenharmony_ci } 3427141cc406Sopenharmony_ci disconnect610p (); 3428141cc406Sopenharmony_ci return 1; 3429141cc406Sopenharmony_ci} 3430141cc406Sopenharmony_ci 3431141cc406Sopenharmony_cistatic int 3432141cc406Sopenharmony_cicmdSync610p (int cmd) 3433141cc406Sopenharmony_ci{ 3434141cc406Sopenharmony_ci int word[5]; 3435141cc406Sopenharmony_ci int status; 3436141cc406Sopenharmony_ci 3437141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 3438141cc406Sopenharmony_ci return EPPcmdSync610p (cmd); 3439141cc406Sopenharmony_ci 3440141cc406Sopenharmony_ci word[0] = 0; 3441141cc406Sopenharmony_ci word[1] = 0; 3442141cc406Sopenharmony_ci word[2] = 0; 3443141cc406Sopenharmony_ci word[3] = cmd; 3444141cc406Sopenharmony_ci 3445141cc406Sopenharmony_ci connect610p (); 3446141cc406Sopenharmony_ci sync610p (); 3447141cc406Sopenharmony_ci if (sendLength610p (word) == 0) 3448141cc406Sopenharmony_ci { 3449141cc406Sopenharmony_ci DBG (0, "sendLength610p() failed... (%s:%d)\n", __FILE__, __LINE__); 3450141cc406Sopenharmony_ci return 0; 3451141cc406Sopenharmony_ci } 3452141cc406Sopenharmony_ci if (cmd == 0xC2) 3453141cc406Sopenharmony_ci { 3454141cc406Sopenharmony_ci status = getStatus610p (); 3455141cc406Sopenharmony_ci if (status != 0xC0) 3456141cc406Sopenharmony_ci { 3457141cc406Sopenharmony_ci DBG (1, "Found 0x%X expected 0xC0 (%s:%d)\n", status, __FILE__, 3458141cc406Sopenharmony_ci __LINE__); 3459141cc406Sopenharmony_ci return 0; 3460141cc406Sopenharmony_ci } 3461141cc406Sopenharmony_ci } 3462141cc406Sopenharmony_ci status = getStatus610p (); 3463141cc406Sopenharmony_ci if (status != 0xC0) 3464141cc406Sopenharmony_ci { 3465141cc406Sopenharmony_ci DBG (1, "Found 0x%X expected 0xC0 (%s:%d)\n", status, __FILE__, 3466141cc406Sopenharmony_ci __LINE__); 3467141cc406Sopenharmony_ci return 0; 3468141cc406Sopenharmony_ci } 3469141cc406Sopenharmony_ci disconnect610p (); 3470141cc406Sopenharmony_ci return 1; 3471141cc406Sopenharmony_ci} 3472141cc406Sopenharmony_ci 3473141cc406Sopenharmony_cistatic int 3474141cc406Sopenharmony_ciEPPgetStatus610p (void) 3475141cc406Sopenharmony_ci{ 3476141cc406Sopenharmony_ci int data, status, control, i; 3477141cc406Sopenharmony_ci 3478141cc406Sopenharmony_ci control = Inb (CONTROL) & 0xA4; 3479141cc406Sopenharmony_ci control = control | 0xE0; 3480141cc406Sopenharmony_ci Outb (CONTROL, control); 3481141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3482141cc406Sopenharmony_ci if (status & 0x08) 3483141cc406Sopenharmony_ci { 3484141cc406Sopenharmony_ci for (i = 1; i < 10; i++) 3485141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3486141cc406Sopenharmony_ci } 3487141cc406Sopenharmony_ci else 3488141cc406Sopenharmony_ci { 3489141cc406Sopenharmony_ci data = Inb (EPPDATA); 3490141cc406Sopenharmony_ci scannerStatus = data; 3491141cc406Sopenharmony_ci } 3492141cc406Sopenharmony_ci return status; 3493141cc406Sopenharmony_ci} 3494141cc406Sopenharmony_ci 3495141cc406Sopenharmony_cistatic int 3496141cc406Sopenharmony_cigetStatus610p (void) 3497141cc406Sopenharmony_ci{ 3498141cc406Sopenharmony_ci int data, status; 3499141cc406Sopenharmony_ci 3500141cc406Sopenharmony_ci byteMode (); 3501141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 3502141cc406Sopenharmony_ci Outb (CONTROL, 0x26); /* data reverse */ 3503141cc406Sopenharmony_ci data = Inb (DATA); 3504141cc406Sopenharmony_ci scannerStatus = data; 3505141cc406Sopenharmony_ci Outb (CONTROL, 0x24); 3506141cc406Sopenharmony_ci return status; 3507141cc406Sopenharmony_ci} 3508141cc406Sopenharmony_ci 3509141cc406Sopenharmony_ci 3510141cc406Sopenharmony_ciint 3511141cc406Sopenharmony_cisendLength610p (int *cmd) 3512141cc406Sopenharmony_ci{ 3513141cc406Sopenharmony_ci int ret, i, wait; 3514141cc406Sopenharmony_ci/* 55,AA,x,y,z,t */ 3515141cc406Sopenharmony_ci 3516141cc406Sopenharmony_ci byteMode (); 3517141cc406Sopenharmony_ci wait = putByte610p (0x55); 3518141cc406Sopenharmony_ci if ((wait != 0xC8) && (wait != 0xC0)) 3519141cc406Sopenharmony_ci { 3520141cc406Sopenharmony_ci DBG (0, 3521141cc406Sopenharmony_ci "sendLength610p failed, expected 0xC8 or 0xC0 got 0x%02X ! (%s:%d)\n", 3522141cc406Sopenharmony_ci wait, __FILE__, __LINE__); 3523141cc406Sopenharmony_ci return 0; 3524141cc406Sopenharmony_ci } 3525141cc406Sopenharmony_ci wait = putByte610p (0xAA); 3526141cc406Sopenharmony_ci if ((wait != 0xC8) && (wait != 0xC0)) 3527141cc406Sopenharmony_ci { 3528141cc406Sopenharmony_ci DBG (0, 3529141cc406Sopenharmony_ci "sendLength610p failed, expected 0xC8 or 0xC0 got 0x%02X ! (%s:%d)\n", 3530141cc406Sopenharmony_ci wait, __FILE__, __LINE__); 3531141cc406Sopenharmony_ci return 0; 3532141cc406Sopenharmony_ci } 3533141cc406Sopenharmony_ci 3534141cc406Sopenharmony_ci /* if wait=C0, we have to ... wait */ 3535141cc406Sopenharmony_ci if (wait == 0xC0) 3536141cc406Sopenharmony_ci { 3537141cc406Sopenharmony_ci byteMode (); 3538141cc406Sopenharmony_ci wait = Inb (STATUS); /* C0 expected */ 3539141cc406Sopenharmony_ci Outb (CONTROL, 0x26); 3540141cc406Sopenharmony_ci ret = Inb (DATA); /* 88 expected */ 3541141cc406Sopenharmony_ci Outb (CONTROL, 0x24); 3542141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 3543141cc406Sopenharmony_ci wait = Inb (STATUS); /* C8 expected */ 3544141cc406Sopenharmony_ci byteMode (); 3545141cc406Sopenharmony_ci } 3546141cc406Sopenharmony_ci 3547141cc406Sopenharmony_ci for (i = 0; i < 3; i++) 3548141cc406Sopenharmony_ci { 3549141cc406Sopenharmony_ci ret = putByte610p (cmd[i]); 3550141cc406Sopenharmony_ci if (ret != 0xC8) 3551141cc406Sopenharmony_ci { 3552141cc406Sopenharmony_ci DBG (0, 3553141cc406Sopenharmony_ci "sendLength610p failed, expected 0xC8 got 0x%02X ! (%s:%d)\n", 3554141cc406Sopenharmony_ci ret, __FILE__, __LINE__); 3555141cc406Sopenharmony_ci return 0; 3556141cc406Sopenharmony_ci } 3557141cc406Sopenharmony_ci } 3558141cc406Sopenharmony_ci ret = putByte610p (cmd[3]); 3559141cc406Sopenharmony_ci if ((ret != 0xC0) && (ret != 0xD0)) 3560141cc406Sopenharmony_ci { 3561141cc406Sopenharmony_ci DBG (0, 3562141cc406Sopenharmony_ci "sendLength610p failed, expected 0xC0 or 0xD0 got 0x%02X ! (%s:%d)\n", 3563141cc406Sopenharmony_ci ret, __FILE__, __LINE__); 3564141cc406Sopenharmony_ci return 0; 3565141cc406Sopenharmony_ci } 3566141cc406Sopenharmony_ci return 1; 3567141cc406Sopenharmony_ci} 3568141cc406Sopenharmony_ci 3569141cc406Sopenharmony_ci/* 1 OK, 0 failure */ 3570141cc406Sopenharmony_cistatic int 3571141cc406Sopenharmony_cidisconnect610p (void) 3572141cc406Sopenharmony_ci{ 3573141cc406Sopenharmony_ci int control, i; 3574141cc406Sopenharmony_ci 3575141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 3576141cc406Sopenharmony_ci for (i = 0; i < 41; i++) 3577141cc406Sopenharmony_ci { 3578141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 3579141cc406Sopenharmony_ci if (control != 0x04) 3580141cc406Sopenharmony_ci { 3581141cc406Sopenharmony_ci DBG (0, "disconnect610p failed (idx %d=%02X)! (%s:%d)\n", 3582141cc406Sopenharmony_ci i, control, __FILE__, __LINE__); 3583141cc406Sopenharmony_ci return 0; 3584141cc406Sopenharmony_ci } 3585141cc406Sopenharmony_ci } 3586141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 3587141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 3588141cc406Sopenharmony_ci if (control != 0x0C) 3589141cc406Sopenharmony_ci { 3590141cc406Sopenharmony_ci DBG (0, "disconnect610p failed expected 0x0C got %02X (%s:%d)\n", 3591141cc406Sopenharmony_ci control, __FILE__, __LINE__); 3592141cc406Sopenharmony_ci return 0; 3593141cc406Sopenharmony_ci } 3594141cc406Sopenharmony_ci /* XXX STEF XXX Outb (DATA, gData); */ 3595141cc406Sopenharmony_ci Outb (DATA, 0xFF); 3596141cc406Sopenharmony_ci return 1; 3597141cc406Sopenharmony_ci} 3598141cc406Sopenharmony_ci 3599141cc406Sopenharmony_ci/* 1 OK, 0 failure */ 3600141cc406Sopenharmony_ci/* 0: short connect, 1 long connect */ 3601141cc406Sopenharmony_cistatic int 3602141cc406Sopenharmony_ciconnect610p (void) 3603141cc406Sopenharmony_ci{ 3604141cc406Sopenharmony_ci int control; 3605141cc406Sopenharmony_ci 3606141cc406Sopenharmony_ci gData = Inb (DATA); /* to gDATA ? */ 3607141cc406Sopenharmony_ci 3608141cc406Sopenharmony_ci Outb (DATA, 0xAA); 3609141cc406Sopenharmony_ci Outb (CONTROL, 0x0E); 3610141cc406Sopenharmony_ci control = Inb (CONTROL); /* 0x0E expected */ 3611141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 3612141cc406Sopenharmony_ci if (control != 0x0E) 3613141cc406Sopenharmony_ci { 3614141cc406Sopenharmony_ci DBG (0, "connect610p control=%02X, expected 0x0E (%s:%d)\n", control, 3615141cc406Sopenharmony_ci __FILE__, __LINE__); 3616141cc406Sopenharmony_ci } 3617141cc406Sopenharmony_ci 3618141cc406Sopenharmony_ci Outb (DATA, 0x00); 3619141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 3620141cc406Sopenharmony_ci control = Inb (CONTROL); /* 0x0C expected */ 3621141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 3622141cc406Sopenharmony_ci if (control != 0x0C) 3623141cc406Sopenharmony_ci { 3624141cc406Sopenharmony_ci DBG (0, "connect610p control=%02X, expected 0x0C (%s:%d)\n", control, 3625141cc406Sopenharmony_ci __FILE__, __LINE__); 3626141cc406Sopenharmony_ci } 3627141cc406Sopenharmony_ci 3628141cc406Sopenharmony_ci Outb (DATA, 0x55); 3629141cc406Sopenharmony_ci Outb (CONTROL, 0x0E); 3630141cc406Sopenharmony_ci control = Inb (CONTROL); /* 0x0E expected */ 3631141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 3632141cc406Sopenharmony_ci if (control != 0x0E) 3633141cc406Sopenharmony_ci { 3634141cc406Sopenharmony_ci DBG (0, "connect610p control=%02X, expected 0x0E (%s:%d)\n", control, 3635141cc406Sopenharmony_ci __FILE__, __LINE__); 3636141cc406Sopenharmony_ci } 3637141cc406Sopenharmony_ci 3638141cc406Sopenharmony_ci Outb (DATA, 0xFF); 3639141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 3640141cc406Sopenharmony_ci control = Inb (CONTROL); /* 0x0C expected */ 3641141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 3642141cc406Sopenharmony_ci if (control != 0x0C) 3643141cc406Sopenharmony_ci { 3644141cc406Sopenharmony_ci DBG (0, "connect610p control=%02X, expected 0x0C (%s:%d)\n", control, 3645141cc406Sopenharmony_ci __FILE__, __LINE__); 3646141cc406Sopenharmony_ci } 3647141cc406Sopenharmony_ci 3648141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 3649141cc406Sopenharmony_ci control = Inb (CONTROL); /* 0x04 expected */ 3650141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 3651141cc406Sopenharmony_ci if (control != 0x04) 3652141cc406Sopenharmony_ci { 3653141cc406Sopenharmony_ci DBG (0, "connect610p control=%02X, expected 0x04 (%s:%d)\n", control, 3654141cc406Sopenharmony_ci __FILE__, __LINE__); 3655141cc406Sopenharmony_ci } 3656141cc406Sopenharmony_ci return 1; 3657141cc406Sopenharmony_ci} 3658141cc406Sopenharmony_ci 3659141cc406Sopenharmony_ci/* 1 OK, 0 failure */ 3660141cc406Sopenharmony_cistatic int 3661141cc406Sopenharmony_ciEPPconnect (void) 3662141cc406Sopenharmony_ci{ 3663141cc406Sopenharmony_ci int control; 3664141cc406Sopenharmony_ci 3665141cc406Sopenharmony_ci /* initial values, don't hardcode */ 3666141cc406Sopenharmony_ci Outb (DATA, 0x04); 3667141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 3668141cc406Sopenharmony_ci 3669141cc406Sopenharmony_ci Inb (DATA); 3670141cc406Sopenharmony_ci control = Inb (CONTROL); 3671141cc406Sopenharmony_ci Outb (CONTROL, control & 0x1F); 3672141cc406Sopenharmony_ci control = Inb (CONTROL); 3673141cc406Sopenharmony_ci Outb (CONTROL, control & 0x1F); 3674141cc406Sopenharmony_ci 3675141cc406Sopenharmony_ci if (sendCommand (0xE0) != 1) 3676141cc406Sopenharmony_ci { 3677141cc406Sopenharmony_ci DBG (0, "EPPconnect: sendCommand(0xE0) failed! (%s:%d)\n", __FILE__, 3678141cc406Sopenharmony_ci __LINE__); 3679141cc406Sopenharmony_ci return 0; 3680141cc406Sopenharmony_ci } 3681141cc406Sopenharmony_ci ClearRegister (0); 3682141cc406Sopenharmony_ci init001 (); 3683141cc406Sopenharmony_ci return 1; 3684141cc406Sopenharmony_ci} 3685141cc406Sopenharmony_ci 3686141cc406Sopenharmony_ci 3687141cc406Sopenharmony_ci 3688141cc406Sopenharmony_cistatic void 3689141cc406Sopenharmony_ciEPPRead32Buffer (int size, unsigned char *dest) 3690141cc406Sopenharmony_ci{ 3691141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 3692141cc406Sopenharmony_ci int fd, mode, rc, nb; 3693141cc406Sopenharmony_ci unsigned char bval; 3694141cc406Sopenharmony_ci#endif 3695141cc406Sopenharmony_ci int control; 3696141cc406Sopenharmony_ci 3697141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 3698141cc406Sopenharmony_ci /* check we have ppdev working */ 3699141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 3700141cc406Sopenharmony_ci if (fd > 0) 3701141cc406Sopenharmony_ci { 3702141cc406Sopenharmony_ci 3703141cc406Sopenharmony_ci bval = 0x80; 3704141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 3705141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 3706141cc406Sopenharmony_ci if (rc) 3707141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3708141cc406Sopenharmony_ci __FILE__, __LINE__); 3709141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 3710141cc406Sopenharmony_ci 3711141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 3712141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 3713141cc406Sopenharmony_ci if (rc) 3714141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3715141cc406Sopenharmony_ci __FILE__, __LINE__); 3716141cc406Sopenharmony_ci#ifdef PPSETFLAGS 3717141cc406Sopenharmony_ci mode = PP_FASTREAD; 3718141cc406Sopenharmony_ci rc = ioctl (fd, PPSETFLAGS, &mode); 3719141cc406Sopenharmony_ci if (rc) 3720141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3721141cc406Sopenharmony_ci __FILE__, __LINE__); 3722141cc406Sopenharmony_ci#endif 3723141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 3724141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 3725141cc406Sopenharmony_ci if (rc) 3726141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3727141cc406Sopenharmony_ci __FILE__, __LINE__); 3728141cc406Sopenharmony_ci nb = 0; 3729141cc406Sopenharmony_ci while (nb < size - 4) 3730141cc406Sopenharmony_ci { 3731141cc406Sopenharmony_ci rc = read (fd, dest + nb, size - 4 - nb); 3732141cc406Sopenharmony_ci nb += rc; 3733141cc406Sopenharmony_ci } 3734141cc406Sopenharmony_ci 3735141cc406Sopenharmony_ci rc = read (fd, dest + size - 4, 3); 3736141cc406Sopenharmony_ci 3737141cc406Sopenharmony_ci mode = 0; /* forward */ 3738141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 3739141cc406Sopenharmony_ci if (rc) 3740141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3741141cc406Sopenharmony_ci __FILE__, __LINE__); 3742141cc406Sopenharmony_ci bval = 0xA0; 3743141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 3744141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 3745141cc406Sopenharmony_ci if (rc) 3746141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3747141cc406Sopenharmony_ci __FILE__, __LINE__); 3748141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 3749141cc406Sopenharmony_ci 3750141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 3751141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 3752141cc406Sopenharmony_ci if (rc) 3753141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3754141cc406Sopenharmony_ci __FILE__, __LINE__); 3755141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 3756141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 3757141cc406Sopenharmony_ci if (rc) 3758141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3759141cc406Sopenharmony_ci __FILE__, __LINE__); 3760141cc406Sopenharmony_ci rc = read (fd, dest + size - 1, 1); 3761141cc406Sopenharmony_ci 3762141cc406Sopenharmony_ci mode = 0; /* forward */ 3763141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 3764141cc406Sopenharmony_ci if (rc) 3765141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3766141cc406Sopenharmony_ci __FILE__, __LINE__); 3767141cc406Sopenharmony_ci 3768141cc406Sopenharmony_ci return; 3769141cc406Sopenharmony_ci } 3770141cc406Sopenharmony_ci /* if not, direct hardware access */ 3771141cc406Sopenharmony_ci#endif 3772141cc406Sopenharmony_ci 3773141cc406Sopenharmony_ci EPPBlockMode (0x80); 3774141cc406Sopenharmony_ci 3775141cc406Sopenharmony_ci control = Inb (CONTROL); 3776141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F) | 0x20); 3777141cc406Sopenharmony_ci Insw (EPPDATA, dest, size / 4 - 1); 3778141cc406Sopenharmony_ci 3779141cc406Sopenharmony_ci Insb (EPPDATA, (unsigned char *) (dest + size - 4), 3); 3780141cc406Sopenharmony_ci control = Inb (CONTROL); 3781141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F)); 3782141cc406Sopenharmony_ci 3783141cc406Sopenharmony_ci EPPBlockMode (0xA0); 3784141cc406Sopenharmony_ci control = Inb (CONTROL); 3785141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F) | 0x20); 3786141cc406Sopenharmony_ci 3787141cc406Sopenharmony_ci Insb (EPPDATA, (unsigned char *) (dest + size - 1), 1); 3788141cc406Sopenharmony_ci control = Inb (CONTROL); 3789141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F)); 3790141cc406Sopenharmony_ci} 3791141cc406Sopenharmony_ci 3792141cc406Sopenharmony_cistatic void 3793141cc406Sopenharmony_ciEPPWrite32Buffer (int size, unsigned char *source) 3794141cc406Sopenharmony_ci{ 3795141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 3796141cc406Sopenharmony_ci int fd, mode, rc; 3797141cc406Sopenharmony_ci unsigned char bval; 3798141cc406Sopenharmony_ci#endif 3799141cc406Sopenharmony_ci 3800141cc406Sopenharmony_ci if ((size % 4) != 0) 3801141cc406Sopenharmony_ci { 3802141cc406Sopenharmony_ci DBG (0, "EPPWrite32Buffer: size %% 4 != 0!! (%s:%d)\n", __FILE__, 3803141cc406Sopenharmony_ci __LINE__); 3804141cc406Sopenharmony_ci } 3805141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 3806141cc406Sopenharmony_ci /* check we have ppdev working */ 3807141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 3808141cc406Sopenharmony_ci if (fd > 0) 3809141cc406Sopenharmony_ci { 3810141cc406Sopenharmony_ci 3811141cc406Sopenharmony_ci bval = 0xC0; 3812141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 3813141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 3814141cc406Sopenharmony_ci if (rc) 3815141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3816141cc406Sopenharmony_ci __FILE__, __LINE__); 3817141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 3818141cc406Sopenharmony_ci 3819141cc406Sopenharmony_ci#ifdef PPSETFLAGS 3820141cc406Sopenharmony_ci mode = PP_FASTWRITE; 3821141cc406Sopenharmony_ci rc = ioctl (fd, PPSETFLAGS, &mode); 3822141cc406Sopenharmony_ci if (rc) 3823141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3824141cc406Sopenharmony_ci __FILE__, __LINE__); 3825141cc406Sopenharmony_ci#endif 3826141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 3827141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 3828141cc406Sopenharmony_ci if (rc) 3829141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3830141cc406Sopenharmony_ci __FILE__, __LINE__); 3831141cc406Sopenharmony_ci rc = write (fd, source, size); 3832141cc406Sopenharmony_ci 3833141cc406Sopenharmony_ci return; 3834141cc406Sopenharmony_ci } 3835141cc406Sopenharmony_ci /* if not, direct hardware access */ 3836141cc406Sopenharmony_ci#endif 3837141cc406Sopenharmony_ci EPPBlockMode (0xC0); 3838141cc406Sopenharmony_ci Outsw (EPPDATA, source, size / 4); 3839141cc406Sopenharmony_ci} 3840141cc406Sopenharmony_ci 3841141cc406Sopenharmony_ci 3842141cc406Sopenharmony_ci 3843141cc406Sopenharmony_ci 3844141cc406Sopenharmony_ci 3845141cc406Sopenharmony_ci 3846141cc406Sopenharmony_ci/* returns 0 if ERROR cleared in STATUS within 1024 inb, else 1 */ 3847141cc406Sopenharmony_cistatic int 3848141cc406Sopenharmony_ciWaitOnError (void) 3849141cc406Sopenharmony_ci{ 3850141cc406Sopenharmony_ci int c = 0; 3851141cc406Sopenharmony_ci int count = 1024; 3852141cc406Sopenharmony_ci int status; 3853141cc406Sopenharmony_ci 3854141cc406Sopenharmony_ci do 3855141cc406Sopenharmony_ci { 3856141cc406Sopenharmony_ci do 3857141cc406Sopenharmony_ci { 3858141cc406Sopenharmony_ci status = Inb (STATUS) & 0x08; 3859141cc406Sopenharmony_ci if (status != 0) 3860141cc406Sopenharmony_ci { 3861141cc406Sopenharmony_ci count--; 3862141cc406Sopenharmony_ci if (count == 0) 3863141cc406Sopenharmony_ci c = 1; 3864141cc406Sopenharmony_ci } 3865141cc406Sopenharmony_ci } 3866141cc406Sopenharmony_ci while ((count > 0) && (status != 0)); 3867141cc406Sopenharmony_ci if (status == 0) 3868141cc406Sopenharmony_ci { 3869141cc406Sopenharmony_ci status = Inb (STATUS) & 0x08; 3870141cc406Sopenharmony_ci if (status == 0) 3871141cc406Sopenharmony_ci c = 0; 3872141cc406Sopenharmony_ci } 3873141cc406Sopenharmony_ci } 3874141cc406Sopenharmony_ci while ((status != 0) && (c == 0)); 3875141cc406Sopenharmony_ci return c; 3876141cc406Sopenharmony_ci} 3877141cc406Sopenharmony_ci 3878141cc406Sopenharmony_ci 3879141cc406Sopenharmony_ci 3880141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 3881141cc406Sopenharmony_ci/* read up to size bytes, returns bytes read */ 3882141cc406Sopenharmony_cistatic int 3883141cc406Sopenharmony_ciParportpausedBufferRead (int size, unsigned char *dest) 3884141cc406Sopenharmony_ci{ 3885141cc406Sopenharmony_ci unsigned char status, bval; 3886141cc406Sopenharmony_ci int error; 3887141cc406Sopenharmony_ci int word; 3888141cc406Sopenharmony_ci int bread; 3889141cc406Sopenharmony_ci int c; 3890141cc406Sopenharmony_ci int fd, rc, mode; 3891141cc406Sopenharmony_ci 3892141cc406Sopenharmony_ci /* WIP check */ 3893141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 3894141cc406Sopenharmony_ci { 3895141cc406Sopenharmony_ci DBG (0, "ECP access not implemented yet (WIP) ! (%s:%d)\n", 3896141cc406Sopenharmony_ci __FILE__, __LINE__); 3897141cc406Sopenharmony_ci } 3898141cc406Sopenharmony_ci 3899141cc406Sopenharmony_ci /* init */ 3900141cc406Sopenharmony_ci bread = 0; 3901141cc406Sopenharmony_ci error = 0; 3902141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 3903141cc406Sopenharmony_ci 3904141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 3905141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 3906141cc406Sopenharmony_ci if (rc) 3907141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3908141cc406Sopenharmony_ci __FILE__, __LINE__); 3909141cc406Sopenharmony_ci#ifdef PPSETFLAGS 3910141cc406Sopenharmony_ci mode = PP_FASTREAD; 3911141cc406Sopenharmony_ci rc = ioctl (fd, PPSETFLAGS, &mode); 3912141cc406Sopenharmony_ci if (rc) 3913141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3914141cc406Sopenharmony_ci __FILE__, __LINE__); 3915141cc406Sopenharmony_ci#endif 3916141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 3917141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 3918141cc406Sopenharmony_ci if (rc) 3919141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3920141cc406Sopenharmony_ci __FILE__, __LINE__); 3921141cc406Sopenharmony_ci 3922141cc406Sopenharmony_ci if ((size & 0x03) != 0) 3923141cc406Sopenharmony_ci { 3924141cc406Sopenharmony_ci while ((!error) && ((size & 0x03) != 0)) 3925141cc406Sopenharmony_ci { 3926141cc406Sopenharmony_ci rc = read (fd, dest, 1); 3927141cc406Sopenharmony_ci size--; 3928141cc406Sopenharmony_ci dest++; 3929141cc406Sopenharmony_ci bread++; 3930141cc406Sopenharmony_ci rc = ioctl (fd, PPRSTATUS, &status); 3931141cc406Sopenharmony_ci if (rc) 3932141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3933141cc406Sopenharmony_ci __FILE__, __LINE__); 3934141cc406Sopenharmony_ci error = status & 0x08; 3935141cc406Sopenharmony_ci } 3936141cc406Sopenharmony_ci if (error) 3937141cc406Sopenharmony_ci { 3938141cc406Sopenharmony_ci DBG (0, "Read error (%s:%d)\n", __FILE__, __LINE__); 3939141cc406Sopenharmony_ci return 0; 3940141cc406Sopenharmony_ci } 3941141cc406Sopenharmony_ci } 3942141cc406Sopenharmony_ci 3943141cc406Sopenharmony_ci /* from here, we read 1 byte, then size/4-1 32 bits words, and then 3944141cc406Sopenharmony_ci 3 bytes, pausing on ERROR bit of STATUS */ 3945141cc406Sopenharmony_ci size -= 4; 3946141cc406Sopenharmony_ci 3947141cc406Sopenharmony_ci /* sanity test, seems to be wrongly handled ... */ 3948141cc406Sopenharmony_ci if (size == 0) 3949141cc406Sopenharmony_ci { 3950141cc406Sopenharmony_ci DBG (0, "case not handled! (%s:%d)\n", __FILE__, __LINE__); 3951141cc406Sopenharmony_ci return 0; 3952141cc406Sopenharmony_ci } 3953141cc406Sopenharmony_ci 3954141cc406Sopenharmony_ci word = 0; 3955141cc406Sopenharmony_ci error = 0; 3956141cc406Sopenharmony_ci bread += size; 3957141cc406Sopenharmony_ci do 3958141cc406Sopenharmony_ci { 3959141cc406Sopenharmony_ci do 3960141cc406Sopenharmony_ci { 3961141cc406Sopenharmony_ci rc = read (fd, dest, 1); 3962141cc406Sopenharmony_ci size--; 3963141cc406Sopenharmony_ci dest++; 3964141cc406Sopenharmony_ci readstatus: 3965141cc406Sopenharmony_ci if (size > 0) 3966141cc406Sopenharmony_ci { 3967141cc406Sopenharmony_ci rc = ioctl (fd, PPRSTATUS, &status); 3968141cc406Sopenharmony_ci if (rc) 3969141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", 3970141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 3971141cc406Sopenharmony_ci word = status & 0x10; 3972141cc406Sopenharmony_ci error = status & 0x08; 3973141cc406Sopenharmony_ci } 3974141cc406Sopenharmony_ci } 3975141cc406Sopenharmony_ci while ((size > 0) && (!error) && (!word)); 3976141cc406Sopenharmony_ci } 3977141cc406Sopenharmony_ci while ((size < 4) && (!error) && (size > 0)); 3978141cc406Sopenharmony_ci 3979141cc406Sopenharmony_ci /* here size=0 or error=8 or word=0x10 */ 3980141cc406Sopenharmony_ci if ((word) && (!error) && (size)) 3981141cc406Sopenharmony_ci { 3982141cc406Sopenharmony_ci rc = read (fd, dest, 4); 3983141cc406Sopenharmony_ci dest += 4; 3984141cc406Sopenharmony_ci size -= 4; 3985141cc406Sopenharmony_ci if (size != 0) 3986141cc406Sopenharmony_ci error = 0x08; 3987141cc406Sopenharmony_ci } 3988141cc406Sopenharmony_ci if (!error) 3989141cc406Sopenharmony_ci { 3990141cc406Sopenharmony_ci c = 0; 3991141cc406Sopenharmony_ci rc = ioctl (fd, PPRSTATUS, &status); 3992141cc406Sopenharmony_ci if (rc) 3993141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 3994141cc406Sopenharmony_ci __FILE__, __LINE__); 3995141cc406Sopenharmony_ci error = status & 0x08; 3996141cc406Sopenharmony_ci if (error) 3997141cc406Sopenharmony_ci c = WaitOnError (); 3998141cc406Sopenharmony_ci } 3999141cc406Sopenharmony_ci else 4000141cc406Sopenharmony_ci { /* 8282 */ 4001141cc406Sopenharmony_ci c = WaitOnError (); 4002141cc406Sopenharmony_ci if (c == 0) 4003141cc406Sopenharmony_ci goto readstatus; 4004141cc406Sopenharmony_ci } 4005141cc406Sopenharmony_ci if (c == 1) 4006141cc406Sopenharmony_ci { 4007141cc406Sopenharmony_ci bread -= size; 4008141cc406Sopenharmony_ci } 4009141cc406Sopenharmony_ci else 4010141cc406Sopenharmony_ci { 4011141cc406Sopenharmony_ci bread += 3; 4012141cc406Sopenharmony_ci size = 3; 4013141cc406Sopenharmony_ci do 4014141cc406Sopenharmony_ci { 4015141cc406Sopenharmony_ci do 4016141cc406Sopenharmony_ci { 4017141cc406Sopenharmony_ci rc = read (fd, dest, 1); 4018141cc406Sopenharmony_ci dest++; 4019141cc406Sopenharmony_ci size--; 4020141cc406Sopenharmony_ci if (size) 4021141cc406Sopenharmony_ci { 4022141cc406Sopenharmony_ci rc = ioctl (fd, PPRSTATUS, &status); 4023141cc406Sopenharmony_ci if (rc) 4024141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", 4025141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 4026141cc406Sopenharmony_ci error = status & 0x08; 4027141cc406Sopenharmony_ci if (!error) 4028141cc406Sopenharmony_ci { 4029141cc406Sopenharmony_ci rc = ioctl (fd, PPRSTATUS, &status); 4030141cc406Sopenharmony_ci if (rc) 4031141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", 4032141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 4033141cc406Sopenharmony_ci error = status & 0x08; 4034141cc406Sopenharmony_ci } 4035141cc406Sopenharmony_ci } 4036141cc406Sopenharmony_ci } 4037141cc406Sopenharmony_ci while ((size > 0) && (!error)); 4038141cc406Sopenharmony_ci c = 0; 4039141cc406Sopenharmony_ci if (error) 4040141cc406Sopenharmony_ci c = WaitOnError (); 4041141cc406Sopenharmony_ci } 4042141cc406Sopenharmony_ci while ((size > 0) && (c == 0)); 4043141cc406Sopenharmony_ci } 4044141cc406Sopenharmony_ci 4045141cc406Sopenharmony_ci /* end reading */ 4046141cc406Sopenharmony_ci mode = 0; /* forward */ 4047141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 4048141cc406Sopenharmony_ci if (rc) 4049141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 4050141cc406Sopenharmony_ci __FILE__, __LINE__); 4051141cc406Sopenharmony_ci bval = 0xA0; 4052141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_ADDR; 4053141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 4054141cc406Sopenharmony_ci if (rc) 4055141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 4056141cc406Sopenharmony_ci __FILE__, __LINE__); 4057141cc406Sopenharmony_ci rc = write (fd, &bval, 1); 4058141cc406Sopenharmony_ci 4059141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 4060141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 4061141cc406Sopenharmony_ci if (rc) 4062141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 4063141cc406Sopenharmony_ci __FILE__, __LINE__); 4064141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 4065141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 4066141cc406Sopenharmony_ci if (rc) 4067141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 4068141cc406Sopenharmony_ci __FILE__, __LINE__); 4069141cc406Sopenharmony_ci rc = read (fd, dest, 1); 4070141cc406Sopenharmony_ci bread++; 4071141cc406Sopenharmony_ci 4072141cc406Sopenharmony_ci mode = 0; /* forward */ 4073141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 4074141cc406Sopenharmony_ci if (rc) 4075141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 4076141cc406Sopenharmony_ci __FILE__, __LINE__); 4077141cc406Sopenharmony_ci return bread; 4078141cc406Sopenharmony_ci} 4079141cc406Sopenharmony_ci#endif 4080141cc406Sopenharmony_ci 4081141cc406Sopenharmony_ci/* read up to size bytes, returns bytes read */ 4082141cc406Sopenharmony_cistatic int 4083141cc406Sopenharmony_ciDirectpausedBufferRead (int size, unsigned char *dest) 4084141cc406Sopenharmony_ci{ 4085141cc406Sopenharmony_ci int control; 4086141cc406Sopenharmony_ci int status; 4087141cc406Sopenharmony_ci int error; 4088141cc406Sopenharmony_ci int word; 4089141cc406Sopenharmony_ci int read; 4090141cc406Sopenharmony_ci int c; 4091141cc406Sopenharmony_ci 4092141cc406Sopenharmony_ci /* init */ 4093141cc406Sopenharmony_ci read = 0; 4094141cc406Sopenharmony_ci error = 0; 4095141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x1F; 4096141cc406Sopenharmony_ci Outb (CONTROL, control | 0x20); 4097141cc406Sopenharmony_ci if ((size & 0x03) != 0) 4098141cc406Sopenharmony_ci { 4099141cc406Sopenharmony_ci /* 8174 */ 4100141cc406Sopenharmony_ci while ((!error) && ((size & 0x03) != 0)) 4101141cc406Sopenharmony_ci { 4102141cc406Sopenharmony_ci Insb (EPPDATA, dest, 1); 4103141cc406Sopenharmony_ci size--; 4104141cc406Sopenharmony_ci dest++; 4105141cc406Sopenharmony_ci read++; 4106141cc406Sopenharmony_ci status = Inb (STATUS) & 0x1F; 4107141cc406Sopenharmony_ci error = status & 0x08; 4108141cc406Sopenharmony_ci } 4109141cc406Sopenharmony_ci if (error) 4110141cc406Sopenharmony_ci { 4111141cc406Sopenharmony_ci DBG (0, "Read error (%s:%d)\n", __FILE__, __LINE__); 4112141cc406Sopenharmony_ci return 0; 4113141cc406Sopenharmony_ci } 4114141cc406Sopenharmony_ci } 4115141cc406Sopenharmony_ci 4116141cc406Sopenharmony_ci /* from here, we read 1 byte, then size/4-1 32 bits words, and then 4117141cc406Sopenharmony_ci 3 bytes, pausing on ERROR bit of STATUS */ 4118141cc406Sopenharmony_ci size -= 4; 4119141cc406Sopenharmony_ci 4120141cc406Sopenharmony_ci /* sanity test, seems to be wrongly handled ... */ 4121141cc406Sopenharmony_ci if (size == 0) 4122141cc406Sopenharmony_ci { 4123141cc406Sopenharmony_ci DBG (0, "case not handled! (%s:%d)\n", __FILE__, __LINE__); 4124141cc406Sopenharmony_ci return 0; 4125141cc406Sopenharmony_ci } 4126141cc406Sopenharmony_ci 4127141cc406Sopenharmony_ci word = 0; 4128141cc406Sopenharmony_ci error = 0; 4129141cc406Sopenharmony_ci read += size; 4130141cc406Sopenharmony_ci do 4131141cc406Sopenharmony_ci { 4132141cc406Sopenharmony_ci do 4133141cc406Sopenharmony_ci { 4134141cc406Sopenharmony_ci Insb (EPPDATA, dest, 1); 4135141cc406Sopenharmony_ci size--; 4136141cc406Sopenharmony_ci dest++; 4137141cc406Sopenharmony_ci readstatus: 4138141cc406Sopenharmony_ci if (size > 0) 4139141cc406Sopenharmony_ci { 4140141cc406Sopenharmony_ci status = Inb (STATUS) & 0x1F; 4141141cc406Sopenharmony_ci word = status & 0x10; 4142141cc406Sopenharmony_ci error = status & 0x08; 4143141cc406Sopenharmony_ci } 4144141cc406Sopenharmony_ci } 4145141cc406Sopenharmony_ci while ((size > 0) && (!error) && (!word)); 4146141cc406Sopenharmony_ci } 4147141cc406Sopenharmony_ci while ((size < 4) && (!error) && (size > 0)); 4148141cc406Sopenharmony_ci 4149141cc406Sopenharmony_ci /* here size=0 or error=8 or word=0x10 */ 4150141cc406Sopenharmony_ci if ((word) && (!error) && (size)) 4151141cc406Sopenharmony_ci { 4152141cc406Sopenharmony_ci if (epp32) 4153141cc406Sopenharmony_ci Insw (EPPDATA, dest, 1); 4154141cc406Sopenharmony_ci else 4155141cc406Sopenharmony_ci Insb (EPPDATA, dest, 4); 4156141cc406Sopenharmony_ci dest += 4; 4157141cc406Sopenharmony_ci size -= 4; 4158141cc406Sopenharmony_ci if (size != 0) 4159141cc406Sopenharmony_ci error = 0x08; 4160141cc406Sopenharmony_ci } 4161141cc406Sopenharmony_ci if (!error) 4162141cc406Sopenharmony_ci { 4163141cc406Sopenharmony_ci c = 0; 4164141cc406Sopenharmony_ci error = Inb (STATUS) & 0x08; 4165141cc406Sopenharmony_ci if (error) 4166141cc406Sopenharmony_ci c = WaitOnError (); 4167141cc406Sopenharmony_ci } 4168141cc406Sopenharmony_ci else 4169141cc406Sopenharmony_ci { /* 8282 */ 4170141cc406Sopenharmony_ci c = WaitOnError (); 4171141cc406Sopenharmony_ci if (c == 0) 4172141cc406Sopenharmony_ci goto readstatus; 4173141cc406Sopenharmony_ci } 4174141cc406Sopenharmony_ci if (c == 1) 4175141cc406Sopenharmony_ci { 4176141cc406Sopenharmony_ci read -= size; 4177141cc406Sopenharmony_ci } 4178141cc406Sopenharmony_ci else 4179141cc406Sopenharmony_ci { 4180141cc406Sopenharmony_ci read += 3; 4181141cc406Sopenharmony_ci size = 3; 4182141cc406Sopenharmony_ci do 4183141cc406Sopenharmony_ci { 4184141cc406Sopenharmony_ci do 4185141cc406Sopenharmony_ci { 4186141cc406Sopenharmony_ci Insb (EPPDATA, dest, 1); 4187141cc406Sopenharmony_ci dest++; 4188141cc406Sopenharmony_ci size--; 4189141cc406Sopenharmony_ci if (size) 4190141cc406Sopenharmony_ci { 4191141cc406Sopenharmony_ci error = Inb (STATUS) & 0x08; 4192141cc406Sopenharmony_ci if (!error) 4193141cc406Sopenharmony_ci error = Inb (STATUS) & 0x08; 4194141cc406Sopenharmony_ci } 4195141cc406Sopenharmony_ci } 4196141cc406Sopenharmony_ci while ((size > 0) && (!error)); 4197141cc406Sopenharmony_ci c = 0; 4198141cc406Sopenharmony_ci if (error) 4199141cc406Sopenharmony_ci c = WaitOnError (); 4200141cc406Sopenharmony_ci } 4201141cc406Sopenharmony_ci while ((size > 0) && (c == 0)); 4202141cc406Sopenharmony_ci } 4203141cc406Sopenharmony_ci 4204141cc406Sopenharmony_ci /* end reading */ 4205141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x1F; 4206141cc406Sopenharmony_ci Outb (CONTROL, control); 4207141cc406Sopenharmony_ci EPPBlockMode (0xA0); 4208141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x1F; 4209141cc406Sopenharmony_ci Outb (CONTROL, control | 0x20); 4210141cc406Sopenharmony_ci Insb (EPPDATA, dest, 1); 4211141cc406Sopenharmony_ci read++; 4212141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x1F; 4213141cc406Sopenharmony_ci Outb (CONTROL, control); 4214141cc406Sopenharmony_ci return read; 4215141cc406Sopenharmony_ci} 4216141cc406Sopenharmony_ci 4217141cc406Sopenharmony_ci 4218141cc406Sopenharmony_ciint 4219141cc406Sopenharmony_cipausedBufferRead (int size, unsigned char *dest) 4220141cc406Sopenharmony_ci{ 4221141cc406Sopenharmony_ci EPPBlockMode (0x80); 4222141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 4223141cc406Sopenharmony_ci if (sanei_umax_pp_getparport () > 0) 4224141cc406Sopenharmony_ci return ParportpausedBufferRead (size, dest); 4225141cc406Sopenharmony_ci#endif 4226141cc406Sopenharmony_ci /* only EPP hardware access for now */ 4227141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 4228141cc406Sopenharmony_ci return DirectpausedBufferRead (size, dest); 4229141cc406Sopenharmony_ci return 0; 4230141cc406Sopenharmony_ci} 4231141cc406Sopenharmony_ci 4232141cc406Sopenharmony_ci 4233141cc406Sopenharmony_ci 4234141cc406Sopenharmony_ci 4235141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 4236141cc406Sopenharmony_cistatic int 4237141cc406Sopenharmony_cisendWord1220P (int *cmd) 4238141cc406Sopenharmony_ci{ 4239141cc406Sopenharmony_ci int i; 4240141cc406Sopenharmony_ci int reg; 4241141cc406Sopenharmony_ci int try = 0; 4242141cc406Sopenharmony_ci 4243141cc406Sopenharmony_ci /* send header */ 4244141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4245141cc406Sopenharmony_ciretry: 4246141cc406Sopenharmony_ci registerWrite (0x1C, 0x55); 4247141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4248141cc406Sopenharmony_ci 4249141cc406Sopenharmony_ci registerWrite (0x1C, 0xAA); 4250141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4251141cc406Sopenharmony_ci 4252141cc406Sopenharmony_ci /* sync when needed */ 4253141cc406Sopenharmony_ci if ((reg & 0x08) == 0x00) 4254141cc406Sopenharmony_ci { 4255141cc406Sopenharmony_ci reg = registerRead (0x1C); 4256141cc406Sopenharmony_ci DBG (16, "UTA: reg1C=0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 4257141cc406Sopenharmony_ci if (((reg & 0x10) != 0x10) && (reg != 0x6B) && (reg != 0xAB) 4258141cc406Sopenharmony_ci && (reg != 0x23)) 4259141cc406Sopenharmony_ci { 4260141cc406Sopenharmony_ci DBG (0, "sendWord failed (reg1C=0x%02X) (%s:%d)\n", reg, __FILE__, 4261141cc406Sopenharmony_ci __LINE__); 4262141cc406Sopenharmony_ci return 0; 4263141cc406Sopenharmony_ci } 4264141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 4265141cc406Sopenharmony_ci { 4266141cc406Sopenharmony_ci usleep (1000); 4267141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4268141cc406Sopenharmony_ci if (reg != 0xC8) 4269141cc406Sopenharmony_ci { 4270141cc406Sopenharmony_ci DBG (0, "Unexpected reg19=0x%2X (%s:%d)\n", reg, __FILE__, 4271141cc406Sopenharmony_ci __LINE__); 4272141cc406Sopenharmony_ci } 4273141cc406Sopenharmony_ci } 4274141cc406Sopenharmony_ci do 4275141cc406Sopenharmony_ci { 4276141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xC8)) 4277141cc406Sopenharmony_ci { 4278141cc406Sopenharmony_ci DBG (0, "Unexpected reg19=0x%2X (%s:%d)\n", reg, __FILE__, 4279141cc406Sopenharmony_ci __LINE__); 4280141cc406Sopenharmony_ci } 4281141cc406Sopenharmony_ci /* 0xF0 certainly means error */ 4282141cc406Sopenharmony_ci if ((reg == 0xC0) || (reg == 0xD0)) 4283141cc406Sopenharmony_ci { 4284141cc406Sopenharmony_ci try++; 4285141cc406Sopenharmony_ci goto retry; 4286141cc406Sopenharmony_ci } 4287141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4288141cc406Sopenharmony_ci } 4289141cc406Sopenharmony_ci while (reg != 0xC8); 4290141cc406Sopenharmony_ci } 4291141cc406Sopenharmony_ci 4292141cc406Sopenharmony_ci /* send word */ 4293141cc406Sopenharmony_ci i = 0; 4294141cc406Sopenharmony_ci while ((reg == 0xC8) && (cmd[i] != -1)) 4295141cc406Sopenharmony_ci { 4296141cc406Sopenharmony_ci registerWrite (0x1C, cmd[i]); 4297141cc406Sopenharmony_ci i++; 4298141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4299141cc406Sopenharmony_ci } 4300141cc406Sopenharmony_ci TRACE (16, "sendWord() passed "); 4301141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 4302141cc406Sopenharmony_ci { 4303141cc406Sopenharmony_ci DBG (0, "sendWord failed got 0x%02X instead of 0xC0 or 0xD0 (%s:%d)\n", 4304141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 4305141cc406Sopenharmony_ci DBG (0, "Blindly going on .....\n"); 4306141cc406Sopenharmony_ci } 4307141cc406Sopenharmony_ci if (((reg == 0xC0) || (reg == 0xD0)) && (cmd[i] != -1)) 4308141cc406Sopenharmony_ci { 4309141cc406Sopenharmony_ci DBG (0, "sendWord failed: short send (%s:%d)\n", __FILE__, __LINE__); 4310141cc406Sopenharmony_ci return 0; 4311141cc406Sopenharmony_ci } 4312141cc406Sopenharmony_ci reg = registerRead (0x1C); 4313141cc406Sopenharmony_ci DBG (16, "sendWord, reg1C=0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 4314141cc406Sopenharmony_ci /* model 0x07 has always the last bit set to 1, and even bit 1 */ 4315141cc406Sopenharmony_ci /* when UTA is present, we get 0x6B there */ 4316141cc406Sopenharmony_ci scannerStatus = reg & 0xFC; 4317141cc406Sopenharmony_ci if (scannerStatus == 0x68) 4318141cc406Sopenharmony_ci hasUTA = 1; 4319141cc406Sopenharmony_ci 4320141cc406Sopenharmony_ci reg = reg & 0x10; 4321141cc406Sopenharmony_ci if ((reg != 0x10) && (scannerStatus != 0x68) && (scannerStatus != 0xA8)) 4322141cc406Sopenharmony_ci { 4323141cc406Sopenharmony_ci DBG (0, "sendWord failed: acknowledge not received (%s:%d)\n", __FILE__, 4324141cc406Sopenharmony_ci __LINE__); 4325141cc406Sopenharmony_ci return 0; 4326141cc406Sopenharmony_ci } 4327141cc406Sopenharmony_ci if (try) 4328141cc406Sopenharmony_ci { 4329141cc406Sopenharmony_ci DBG (0, "sendWord retry success (retry %d time%s) ... (%s:%d)\n", try, 4330141cc406Sopenharmony_ci (try > 1) ? "s" : "", __FILE__, __LINE__); 4331141cc406Sopenharmony_ci } 4332141cc406Sopenharmony_ci return 1; 4333141cc406Sopenharmony_ci} 4334141cc406Sopenharmony_ci 4335141cc406Sopenharmony_ci 4336141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 4337141cc406Sopenharmony_cistatic int 4338141cc406Sopenharmony_ciSPPsendWord610p (int *cmd) 4339141cc406Sopenharmony_ci{ 4340141cc406Sopenharmony_ci int i, j; 4341141cc406Sopenharmony_ci int tmp, status; 4342141cc406Sopenharmony_ci 4343141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 4344141cc406Sopenharmony_ci int exmode, mode, rc, fd; 4345141cc406Sopenharmony_ci#endif 4346141cc406Sopenharmony_ci connect610p (); 4347141cc406Sopenharmony_ci 4348141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 4349141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 4350141cc406Sopenharmony_ci if (fd > 0) 4351141cc406Sopenharmony_ci { 4352141cc406Sopenharmony_ci rc = ioctl (fd, PPGETMODE, &exmode); 4353141cc406Sopenharmony_ci if (rc) 4354141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 4355141cc406Sopenharmony_ci __FILE__, __LINE__); 4356141cc406Sopenharmony_ci mode = IEEE1284_MODE_COMPAT; 4357141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 4358141cc406Sopenharmony_ci if (rc) 4359141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 4360141cc406Sopenharmony_ci __FILE__, __LINE__); 4361141cc406Sopenharmony_ci } 4362141cc406Sopenharmony_ci#endif 4363141cc406Sopenharmony_ci 4364141cc406Sopenharmony_ci Outb (DATA, 0x55); 4365141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 4366141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4367141cc406Sopenharmony_ci if (status != 0x88) 4368141cc406Sopenharmony_ci { 4369141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p found 0x%02X expected 0x88 (%s:%d)\n", status, 4370141cc406Sopenharmony_ci __FILE__, __LINE__); 4371141cc406Sopenharmony_ci return 0; 4372141cc406Sopenharmony_ci } 4373141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 4374141cc406Sopenharmony_ci 4375141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4376141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 4377141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4378141cc406Sopenharmony_ci if (status != 0x88) 4379141cc406Sopenharmony_ci { 4380141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p found 0x%02X expected 0x88 (%s:%d)\n", status, 4381141cc406Sopenharmony_ci __FILE__, __LINE__); 4382141cc406Sopenharmony_ci return 0; 4383141cc406Sopenharmony_ci } 4384141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 4385141cc406Sopenharmony_ci 4386141cc406Sopenharmony_ci for (i = 0; i < 4; i++) 4387141cc406Sopenharmony_ci { 4388141cc406Sopenharmony_ci Outb (DATA, cmd[i]); 4389141cc406Sopenharmony_ci Outb (CONTROL, 0x05); 4390141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4391141cc406Sopenharmony_ci if (status != 0x88) 4392141cc406Sopenharmony_ci { 4393141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p found 0x%02X expected 0x88 (%s:%d)\n", 4394141cc406Sopenharmony_ci status, __FILE__, __LINE__); 4395141cc406Sopenharmony_ci return 0; 4396141cc406Sopenharmony_ci } 4397141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 4398141cc406Sopenharmony_ci } 4399141cc406Sopenharmony_ci 4400141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 4401141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4402141cc406Sopenharmony_ci tmp = Inb (DATA); 4403141cc406Sopenharmony_ci if (tmp != 0xFF) 4404141cc406Sopenharmony_ci { 4405141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p found 0x%X expected 0xFF (%s:%d)\n", tmp, 4406141cc406Sopenharmony_ci __FILE__, __LINE__); 4407141cc406Sopenharmony_ci return 0; 4408141cc406Sopenharmony_ci } 4409141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4410141cc406Sopenharmony_ci j = 0; 4411141cc406Sopenharmony_ci while ((j < 256) && (status & 0x08)) 4412141cc406Sopenharmony_ci { 4413141cc406Sopenharmony_ci j++; 4414141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4415141cc406Sopenharmony_ci } 4416141cc406Sopenharmony_ci if ((status != 0x80) && (status != 0xA0)) 4417141cc406Sopenharmony_ci { 4418141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p found 0x%X expected 0x80 or 0xA0 (%s:%d)\n", 4419141cc406Sopenharmony_ci status, __FILE__, __LINE__); 4420141cc406Sopenharmony_ci return 0; 4421141cc406Sopenharmony_ci } 4422141cc406Sopenharmony_ci Outb (DATA, 0x7F); 4423141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4424141cc406Sopenharmony_ci if (status != 0xC0) 4425141cc406Sopenharmony_ci { 4426141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p found 0x%X expected 0xC0 (%s:%d)\n", status, 4427141cc406Sopenharmony_ci __FILE__, __LINE__); 4428141cc406Sopenharmony_ci return 0; 4429141cc406Sopenharmony_ci } 4430141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4431141cc406Sopenharmony_ci if (cmd[3] == 0xC2) 4432141cc406Sopenharmony_ci { 4433141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 4434141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4435141cc406Sopenharmony_ci tmp = Inb (DATA); 4436141cc406Sopenharmony_ci if (tmp != 0xFF) 4437141cc406Sopenharmony_ci { 4438141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p found 0x%X expected 0xFF (%s:%d)\n", tmp, 4439141cc406Sopenharmony_ci __FILE__, __LINE__); 4440141cc406Sopenharmony_ci return 0; 4441141cc406Sopenharmony_ci } 4442141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4443141cc406Sopenharmony_ci if ((status != 0x80) && (status != 0xA0)) 4444141cc406Sopenharmony_ci { 4445141cc406Sopenharmony_ci DBG (0, 4446141cc406Sopenharmony_ci "SPPsendWord610p found 0x%X expected 0x80 or 0xA0 (%s:%d)\n", 4447141cc406Sopenharmony_ci status, __FILE__, __LINE__); 4448141cc406Sopenharmony_ci return 0; 4449141cc406Sopenharmony_ci } 4450141cc406Sopenharmony_ci Outb (DATA, 0x7F); 4451141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4452141cc406Sopenharmony_ci if (status != 0xC0) 4453141cc406Sopenharmony_ci { 4454141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p found 0x%X expected 0xC0 (%s:%d)\n", 4455141cc406Sopenharmony_ci status, __FILE__, __LINE__); 4456141cc406Sopenharmony_ci return 0; 4457141cc406Sopenharmony_ci } 4458141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4459141cc406Sopenharmony_ci } 4460141cc406Sopenharmony_ci 4461141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 4462141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 4463141cc406Sopenharmony_ci if (fd > 0) 4464141cc406Sopenharmony_ci { 4465141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &exmode); 4466141cc406Sopenharmony_ci if (rc) 4467141cc406Sopenharmony_ci DBG (0, "ppdev ioctl returned <%s> (%s:%d)\n", strerror (errno), 4468141cc406Sopenharmony_ci __FILE__, __LINE__); 4469141cc406Sopenharmony_ci } 4470141cc406Sopenharmony_ci#endif 4471141cc406Sopenharmony_ci disconnect610p (); 4472141cc406Sopenharmony_ci 4473141cc406Sopenharmony_ci return 1; 4474141cc406Sopenharmony_ci} 4475141cc406Sopenharmony_ci 4476141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 4477141cc406Sopenharmony_cistatic int 4478141cc406Sopenharmony_ciEPPsendWord610p (int *cmd) 4479141cc406Sopenharmony_ci{ 4480141cc406Sopenharmony_ci int i; 4481141cc406Sopenharmony_ci int tmp, control; 4482141cc406Sopenharmony_ci 4483141cc406Sopenharmony_ci /* send magic tag */ 4484141cc406Sopenharmony_ci tmp = Inb (STATUS) & 0xF8; 4485141cc406Sopenharmony_ci if (tmp != 0xC8) 4486141cc406Sopenharmony_ci { 4487141cc406Sopenharmony_ci DBG (0, 4488141cc406Sopenharmony_ci "EPPsendWord610p failed, expected tmp=0xC8 , found 0x%02X (%s:%d)\n", 4489141cc406Sopenharmony_ci tmp, __FILE__, __LINE__); 4490141cc406Sopenharmony_ci return 0; 4491141cc406Sopenharmony_ci } 4492141cc406Sopenharmony_ci 4493141cc406Sopenharmony_ci /* sets to EPP, and get sure that data direction is forward */ 4494141cc406Sopenharmony_ci tmp = (Inb (CONTROL) & 0x44) | 0x44; /* !! */ 4495141cc406Sopenharmony_ci Outb (CONTROL, tmp); 4496141cc406Sopenharmony_ci Outb (EPPDATA, 0x55); 4497141cc406Sopenharmony_ci 4498141cc406Sopenharmony_ci /* bit0 is timeout bit in EPP mode, should we take care of it ? */ 4499141cc406Sopenharmony_ci tmp = Inb (STATUS) & 0xF8; 4500141cc406Sopenharmony_ci if (tmp != 0xC8) 4501141cc406Sopenharmony_ci { 4502141cc406Sopenharmony_ci DBG (0, 4503141cc406Sopenharmony_ci "EPPsendWord610p failed, expected tmp=0xC8 , found 0x%02X (%s:%d)\n", 4504141cc406Sopenharmony_ci tmp, __FILE__, __LINE__); 4505141cc406Sopenharmony_ci return 0; 4506141cc406Sopenharmony_ci } 4507141cc406Sopenharmony_ci tmp = (Inb (CONTROL) & 0x44) | 0x44; 4508141cc406Sopenharmony_ci Outb (CONTROL, tmp); 4509141cc406Sopenharmony_ci Outb (EPPDATA, 0xAA); 4510141cc406Sopenharmony_ci 4511141cc406Sopenharmony_ci control = (Inb (CONTROL) & 0xE0) | 0xE4; 4512141cc406Sopenharmony_ci Outb (CONTROL, control); /* bit 7 + data reverse + reset */ 4513141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 4514141cc406Sopenharmony_ci { 4515141cc406Sopenharmony_ci tmp = Inb (STATUS) & 0xF8; 4516141cc406Sopenharmony_ci if (tmp != 0xC8) 4517141cc406Sopenharmony_ci { 4518141cc406Sopenharmony_ci DBG (0, 4519141cc406Sopenharmony_ci "EPPsendWord610p failed, expected tmp=0xC8 , found 0x%02X (%s:%d)\n", 4520141cc406Sopenharmony_ci tmp, __FILE__, __LINE__); 4521141cc406Sopenharmony_ci return 0; 4522141cc406Sopenharmony_ci } 4523141cc406Sopenharmony_ci } 4524141cc406Sopenharmony_ci 4525141cc406Sopenharmony_ci i = 0; 4526141cc406Sopenharmony_ci while ((tmp == 0xC8) && (cmd[i] != -1)) 4527141cc406Sopenharmony_ci { 4528141cc406Sopenharmony_ci tmp = Inb (STATUS) & 0xF8; 4529141cc406Sopenharmony_ci control = (Inb (CONTROL) & 0x44) | 0x44; /* !! */ 4530141cc406Sopenharmony_ci Outb (CONTROL, control); 4531141cc406Sopenharmony_ci Outb (EPPDATA, cmd[i]); 4532141cc406Sopenharmony_ci i++; 4533141cc406Sopenharmony_ci } 4534141cc406Sopenharmony_ci 4535141cc406Sopenharmony_ci /* end */ 4536141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4537141cc406Sopenharmony_ci control = (Inb (CONTROL) & 0x44) | 0xE4; 4538141cc406Sopenharmony_ci Outb (CONTROL, control); /* data reverse + ????? */ 4539141cc406Sopenharmony_ci tmp = Inb (STATUS) & 0xF8; 4540141cc406Sopenharmony_ci if (tmp == 0xC8) 4541141cc406Sopenharmony_ci { 4542141cc406Sopenharmony_ci for (i = 0; i < 9; i++) 4543141cc406Sopenharmony_ci tmp = Inb (STATUS) & 0xF8; 4544141cc406Sopenharmony_ci scannerStatus = tmp; 4545141cc406Sopenharmony_ci } 4546141cc406Sopenharmony_ci else 4547141cc406Sopenharmony_ci { 4548141cc406Sopenharmony_ci scannerStatus = Inb (EPPDATA); 4549141cc406Sopenharmony_ci } 4550141cc406Sopenharmony_ci if ((tmp != 0xC0) && (tmp != 0xD0)) 4551141cc406Sopenharmony_ci { 4552141cc406Sopenharmony_ci DBG (0, 4553141cc406Sopenharmony_ci "EPPsendWord610p failed got 0x%02X instead of 0xC0 or 0xD0 (%s:%d)\n", 4554141cc406Sopenharmony_ci tmp, __FILE__, __LINE__); 4555141cc406Sopenharmony_ci return 0; 4556141cc406Sopenharmony_ci } 4557141cc406Sopenharmony_ci return 1; 4558141cc406Sopenharmony_ci} 4559141cc406Sopenharmony_ci 4560141cc406Sopenharmony_ci/* 4561141cc406Sopenharmony_ci * 0: failure 4562141cc406Sopenharmony_ci * 1: success 4563141cc406Sopenharmony_ci */ 4564141cc406Sopenharmony_cistatic int 4565141cc406Sopenharmony_cisendWord (int *cmd) 4566141cc406Sopenharmony_ci{ 4567141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 4568141cc406Sopenharmony_ci { 4569141cc406Sopenharmony_ci case 610: 4570141cc406Sopenharmony_ci return sendLength610p (cmd); 4571141cc406Sopenharmony_ci case 1220: 4572141cc406Sopenharmony_ci case 1600: 4573141cc406Sopenharmony_ci case 2000: 4574141cc406Sopenharmony_ci default: 4575141cc406Sopenharmony_ci return sendWord1220P (cmd); 4576141cc406Sopenharmony_ci } 4577141cc406Sopenharmony_ci} 4578141cc406Sopenharmony_ci 4579141cc406Sopenharmony_ci 4580141cc406Sopenharmony_ci 4581141cc406Sopenharmony_ci/******************************************************************************/ 4582141cc406Sopenharmony_ci/* ringScanner: returns 1 if scanner present, else 0 */ 4583141cc406Sopenharmony_ci/******************************************************************************/ 4584141cc406Sopenharmony_ci/* 4585141cc406Sopenharmony_ci * in fact this function is really close to CPP macro in 4586141cc406Sopenharmony_ci * /usr/src/linux/drivers/block/paride/epat.c ..... 4587141cc406Sopenharmony_ci * we have almost CPP(8) 4588141cc406Sopenharmony_ci */ 4589141cc406Sopenharmony_ci 4590141cc406Sopenharmony_cistatic int 4591141cc406Sopenharmony_ciringScanner (int count, unsigned long delay) 4592141cc406Sopenharmony_ci{ 4593141cc406Sopenharmony_ci int status; 4594141cc406Sopenharmony_ci int data; 4595141cc406Sopenharmony_ci int control; 4596141cc406Sopenharmony_ci int ret = 1; 4597141cc406Sopenharmony_ci 4598141cc406Sopenharmony_ci /* save state */ 4599141cc406Sopenharmony_ci data = Inb (DATA); 4600141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x1F; 4601141cc406Sopenharmony_ci 4602141cc406Sopenharmony_ci /* send -irq,+reset */ 4603141cc406Sopenharmony_ci Outb (CONTROL, (control & 0xF) | 0x4); 4604141cc406Sopenharmony_ci 4605141cc406Sopenharmony_ci /* unhandled case */ 4606141cc406Sopenharmony_ci if (g674 == 1) 4607141cc406Sopenharmony_ci { 4608141cc406Sopenharmony_ci DBG (1, "OUCH! %s:%d\n", __FILE__, __LINE__); 4609141cc406Sopenharmony_ci return 0; 4610141cc406Sopenharmony_ci } 4611141cc406Sopenharmony_ci 4612141cc406Sopenharmony_ci /* send ring string */ 4613141cc406Sopenharmony_ci Outb (DATA, 0x22); 4614141cc406Sopenharmony_ci usleep (delay); 4615141cc406Sopenharmony_ci Outb (DATA, 0x22); 4616141cc406Sopenharmony_ci usleep (delay); 4617141cc406Sopenharmony_ci if (count == 5) 4618141cc406Sopenharmony_ci { 4619141cc406Sopenharmony_ci Outb (DATA, 0x22); 4620141cc406Sopenharmony_ci usleep (delay); 4621141cc406Sopenharmony_ci Outb (DATA, 0x22); 4622141cc406Sopenharmony_ci usleep (delay); 4623141cc406Sopenharmony_ci Outb (DATA, 0x22); 4624141cc406Sopenharmony_ci usleep (delay); 4625141cc406Sopenharmony_ci } 4626141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4627141cc406Sopenharmony_ci usleep (delay); 4628141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4629141cc406Sopenharmony_ci usleep (delay); 4630141cc406Sopenharmony_ci if (count == 5) 4631141cc406Sopenharmony_ci { 4632141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4633141cc406Sopenharmony_ci usleep (delay); 4634141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4635141cc406Sopenharmony_ci usleep (delay); 4636141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4637141cc406Sopenharmony_ci usleep (delay); 4638141cc406Sopenharmony_ci } 4639141cc406Sopenharmony_ci Outb (DATA, 0x55); 4640141cc406Sopenharmony_ci usleep (delay); 4641141cc406Sopenharmony_ci Outb (DATA, 0x55); 4642141cc406Sopenharmony_ci usleep (delay); 4643141cc406Sopenharmony_ci if (count == 5) 4644141cc406Sopenharmony_ci { 4645141cc406Sopenharmony_ci Outb (DATA, 0x55); 4646141cc406Sopenharmony_ci usleep (delay); 4647141cc406Sopenharmony_ci Outb (DATA, 0x55); 4648141cc406Sopenharmony_ci usleep (delay); 4649141cc406Sopenharmony_ci Outb (DATA, 0x55); 4650141cc406Sopenharmony_ci usleep (delay); 4651141cc406Sopenharmony_ci } 4652141cc406Sopenharmony_ci Outb (DATA, 0x00); 4653141cc406Sopenharmony_ci usleep (delay); 4654141cc406Sopenharmony_ci Outb (DATA, 0x00); 4655141cc406Sopenharmony_ci usleep (delay); 4656141cc406Sopenharmony_ci if (count == 5) 4657141cc406Sopenharmony_ci { 4658141cc406Sopenharmony_ci Outb (DATA, 0x00); 4659141cc406Sopenharmony_ci usleep (delay); 4660141cc406Sopenharmony_ci Outb (DATA, 0x00); 4661141cc406Sopenharmony_ci usleep (delay); 4662141cc406Sopenharmony_ci Outb (DATA, 0x00); 4663141cc406Sopenharmony_ci usleep (delay); 4664141cc406Sopenharmony_ci } 4665141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4666141cc406Sopenharmony_ci usleep (delay); 4667141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4668141cc406Sopenharmony_ci usleep (delay); 4669141cc406Sopenharmony_ci if (count == 5) 4670141cc406Sopenharmony_ci { 4671141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4672141cc406Sopenharmony_ci usleep (delay); 4673141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4674141cc406Sopenharmony_ci usleep (delay); 4675141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4676141cc406Sopenharmony_ci usleep (delay); 4677141cc406Sopenharmony_ci } 4678141cc406Sopenharmony_ci 4679141cc406Sopenharmony_ci /* OK ? */ 4680141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 4681141cc406Sopenharmony_ci usleep (delay); 4682141cc406Sopenharmony_ci if ((status & 0xB8) != 0xB8) 4683141cc406Sopenharmony_ci { 4684141cc406Sopenharmony_ci DBG (1, "status %d doesn't match! %s:%d\n", status, __FILE__, __LINE__); 4685141cc406Sopenharmony_ci ret = 0; 4686141cc406Sopenharmony_ci } 4687141cc406Sopenharmony_ci 4688141cc406Sopenharmony_ci /* if OK send 0x87 */ 4689141cc406Sopenharmony_ci if (ret) 4690141cc406Sopenharmony_ci { 4691141cc406Sopenharmony_ci Outb (DATA, 0x87); 4692141cc406Sopenharmony_ci usleep (delay); 4693141cc406Sopenharmony_ci Outb (DATA, 0x87); 4694141cc406Sopenharmony_ci usleep (delay); 4695141cc406Sopenharmony_ci if (count == 5) 4696141cc406Sopenharmony_ci { 4697141cc406Sopenharmony_ci Outb (DATA, 0x87); 4698141cc406Sopenharmony_ci usleep (delay); 4699141cc406Sopenharmony_ci Outb (DATA, 0x87); 4700141cc406Sopenharmony_ci usleep (delay); 4701141cc406Sopenharmony_ci Outb (DATA, 0x87); 4702141cc406Sopenharmony_ci usleep (delay); 4703141cc406Sopenharmony_ci } 4704141cc406Sopenharmony_ci status = Inb (STATUS); 4705141cc406Sopenharmony_ci /* status = 126 when scanner not connected .... */ 4706141cc406Sopenharmony_ci if ((status & 0xB8) != 0x18) 4707141cc406Sopenharmony_ci { 4708141cc406Sopenharmony_ci DBG (1, "status %d doesn't match! %s:%d\n", status, __FILE__, 4709141cc406Sopenharmony_ci __LINE__); 4710141cc406Sopenharmony_ci ret = 0; 4711141cc406Sopenharmony_ci } 4712141cc406Sopenharmony_ci } 4713141cc406Sopenharmony_ci 4714141cc406Sopenharmony_ci /* if OK send 0x78 */ 4715141cc406Sopenharmony_ci if (ret) 4716141cc406Sopenharmony_ci { 4717141cc406Sopenharmony_ci Outb (DATA, 0x78); 4718141cc406Sopenharmony_ci usleep (delay); 4719141cc406Sopenharmony_ci Outb (DATA, 0x78); 4720141cc406Sopenharmony_ci usleep (delay); 4721141cc406Sopenharmony_ci if (count == 5) 4722141cc406Sopenharmony_ci { 4723141cc406Sopenharmony_ci Outb (DATA, 0x78); 4724141cc406Sopenharmony_ci usleep (delay); 4725141cc406Sopenharmony_ci Outb (DATA, 0x78); 4726141cc406Sopenharmony_ci usleep (delay); 4727141cc406Sopenharmony_ci Outb (DATA, 0x78); 4728141cc406Sopenharmony_ci usleep (delay); 4729141cc406Sopenharmony_ci } 4730141cc406Sopenharmony_ci status = Inb (STATUS); 4731141cc406Sopenharmony_ci if ((status & 0x30) != 0x30) 4732141cc406Sopenharmony_ci { 4733141cc406Sopenharmony_ci DBG (1, "status %d doesn't match! %s:%d\n", status, __FILE__, 4734141cc406Sopenharmony_ci __LINE__); 4735141cc406Sopenharmony_ci ret = 0; 4736141cc406Sopenharmony_ci } 4737141cc406Sopenharmony_ci } 4738141cc406Sopenharmony_ci 4739141cc406Sopenharmony_ci /* ring OK, send termination */ 4740141cc406Sopenharmony_ci if (ret) 4741141cc406Sopenharmony_ci { 4742141cc406Sopenharmony_ci Outb (DATA, 0x08); 4743141cc406Sopenharmony_ci usleep (delay); 4744141cc406Sopenharmony_ci Outb (DATA, 0x08); 4745141cc406Sopenharmony_ci usleep (delay); 4746141cc406Sopenharmony_ci if (count == 5) 4747141cc406Sopenharmony_ci { 4748141cc406Sopenharmony_ci Outb (DATA, 0x08); 4749141cc406Sopenharmony_ci usleep (delay); 4750141cc406Sopenharmony_ci Outb (DATA, 0x08); 4751141cc406Sopenharmony_ci usleep (delay); 4752141cc406Sopenharmony_ci Outb (DATA, 0x08); 4753141cc406Sopenharmony_ci usleep (delay); 4754141cc406Sopenharmony_ci } 4755141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4756141cc406Sopenharmony_ci usleep (delay); 4757141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4758141cc406Sopenharmony_ci usleep (delay); 4759141cc406Sopenharmony_ci if (count == 5) 4760141cc406Sopenharmony_ci { 4761141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4762141cc406Sopenharmony_ci usleep (delay); 4763141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4764141cc406Sopenharmony_ci usleep (delay); 4765141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4766141cc406Sopenharmony_ci usleep (delay); 4767141cc406Sopenharmony_ci } 4768141cc406Sopenharmony_ci } 4769141cc406Sopenharmony_ci 4770141cc406Sopenharmony_ci /* restore state */ 4771141cc406Sopenharmony_ci Outb (CONTROL, control); 4772141cc406Sopenharmony_ci Outb (DATA, data); 4773141cc406Sopenharmony_ci return ret; 4774141cc406Sopenharmony_ci} 4775141cc406Sopenharmony_ci 4776141cc406Sopenharmony_ci/*****************************************************************************/ 4777141cc406Sopenharmony_ci/* test some version : returns 1 on success, 0 otherwise */ 4778141cc406Sopenharmony_ci/*****************************************************************************/ 4779141cc406Sopenharmony_ci 4780141cc406Sopenharmony_ci 4781141cc406Sopenharmony_cistatic int 4782141cc406Sopenharmony_citestVersion (int no) 4783141cc406Sopenharmony_ci{ 4784141cc406Sopenharmony_ci int data; 4785141cc406Sopenharmony_ci int status; 4786141cc406Sopenharmony_ci int control; 4787141cc406Sopenharmony_ci int count; 4788141cc406Sopenharmony_ci int tmp; 4789141cc406Sopenharmony_ci 4790141cc406Sopenharmony_ci data = Inb (DATA); 4791141cc406Sopenharmony_ci control = Inb (CONTROL) & 0x3F; 4792141cc406Sopenharmony_ci Outb (CONTROL, (control & 0x1F) | 0x04); 4793141cc406Sopenharmony_ci 4794141cc406Sopenharmony_ci /* send magic sequence */ 4795141cc406Sopenharmony_ci Outb (DATA, 0x22); 4796141cc406Sopenharmony_ci Outb (DATA, 0x22); 4797141cc406Sopenharmony_ci Outb (DATA, 0x22); 4798141cc406Sopenharmony_ci Outb (DATA, 0x22); 4799141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4800141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4801141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4802141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4803141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4804141cc406Sopenharmony_ci Outb (DATA, 0xAA); 4805141cc406Sopenharmony_ci Outb (DATA, 0x55); 4806141cc406Sopenharmony_ci Outb (DATA, 0x55); 4807141cc406Sopenharmony_ci Outb (DATA, 0x55); 4808141cc406Sopenharmony_ci Outb (DATA, 0x55); 4809141cc406Sopenharmony_ci Outb (DATA, 0x55); 4810141cc406Sopenharmony_ci Outb (DATA, 0x55); 4811141cc406Sopenharmony_ci Outb (DATA, 0x00); 4812141cc406Sopenharmony_ci Outb (DATA, 0x00); 4813141cc406Sopenharmony_ci Outb (DATA, 0x00); 4814141cc406Sopenharmony_ci Outb (DATA, 0x00); 4815141cc406Sopenharmony_ci Outb (DATA, 0x00); 4816141cc406Sopenharmony_ci Outb (DATA, 0x00); 4817141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4818141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4819141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4820141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4821141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4822141cc406Sopenharmony_ci Outb (DATA, 0xFF); 4823141cc406Sopenharmony_ci Outb (DATA, 0x87); 4824141cc406Sopenharmony_ci Outb (DATA, 0x87); 4825141cc406Sopenharmony_ci Outb (DATA, 0x87); 4826141cc406Sopenharmony_ci Outb (DATA, 0x87); 4827141cc406Sopenharmony_ci Outb (DATA, 0x87); 4828141cc406Sopenharmony_ci Outb (DATA, 0x87); 4829141cc406Sopenharmony_ci Outb (DATA, 0x78); 4830141cc406Sopenharmony_ci Outb (DATA, 0x78); 4831141cc406Sopenharmony_ci Outb (DATA, 0x78); 4832141cc406Sopenharmony_ci Outb (DATA, 0x78); 4833141cc406Sopenharmony_ci Outb (DATA, 0x78); 4834141cc406Sopenharmony_ci Outb (DATA, 0x78); 4835141cc406Sopenharmony_ci tmp = no | 0x88; 4836141cc406Sopenharmony_ci Outb (DATA, tmp); 4837141cc406Sopenharmony_ci Outb (DATA, tmp); 4838141cc406Sopenharmony_ci Outb (DATA, tmp); 4839141cc406Sopenharmony_ci Outb (DATA, tmp); 4840141cc406Sopenharmony_ci Outb (DATA, tmp); 4841141cc406Sopenharmony_ci Outb (DATA, tmp); 4842141cc406Sopenharmony_ci 4843141cc406Sopenharmony_ci /* test status */ 4844141cc406Sopenharmony_ci status = Inb (STATUS); 4845141cc406Sopenharmony_ci status = Inb (STATUS); 4846141cc406Sopenharmony_ci if ((status & 0xB8) != 0) 4847141cc406Sopenharmony_ci { 4848141cc406Sopenharmony_ci /* 1600P fails here */ 4849141cc406Sopenharmony_ci DBG (64, "status %d doesn't match! %s:%d\n", status, __FILE__, 4850141cc406Sopenharmony_ci __LINE__); 4851141cc406Sopenharmony_ci Outb (CONTROL, control); 4852141cc406Sopenharmony_ci Outb (DATA, data); 4853141cc406Sopenharmony_ci return 0; 4854141cc406Sopenharmony_ci } 4855141cc406Sopenharmony_ci 4856141cc406Sopenharmony_ci count = 0xF0; 4857141cc406Sopenharmony_ci do 4858141cc406Sopenharmony_ci { 4859141cc406Sopenharmony_ci tmp = no | 0x80; 4860141cc406Sopenharmony_ci Outb (DATA, tmp); 4861141cc406Sopenharmony_ci Outb (DATA, tmp); 4862141cc406Sopenharmony_ci Outb (DATA, tmp); 4863141cc406Sopenharmony_ci Outb (DATA, tmp); 4864141cc406Sopenharmony_ci Outb (DATA, tmp); 4865141cc406Sopenharmony_ci Outb (DATA, tmp); 4866141cc406Sopenharmony_ci tmp = no | 0x88; 4867141cc406Sopenharmony_ci Outb (DATA, tmp); 4868141cc406Sopenharmony_ci Outb (DATA, tmp); 4869141cc406Sopenharmony_ci Outb (DATA, tmp); 4870141cc406Sopenharmony_ci Outb (DATA, tmp); 4871141cc406Sopenharmony_ci Outb (DATA, tmp); 4872141cc406Sopenharmony_ci Outb (DATA, tmp); 4873141cc406Sopenharmony_ci 4874141cc406Sopenharmony_ci /* command received ? */ 4875141cc406Sopenharmony_ci status = Inb (STATUS); 4876141cc406Sopenharmony_ci status = ((status << 1) & 0x70) | (status & 0x80); 4877141cc406Sopenharmony_ci if (status != count) 4878141cc406Sopenharmony_ci { 4879141cc406Sopenharmony_ci /* since failure is expected, we don't alaways print */ 4880141cc406Sopenharmony_ci /* this message ... */ 4881141cc406Sopenharmony_ci DBG (2, "status %d doesn't match count 0x%X! %s:%d\n", status, 4882141cc406Sopenharmony_ci count, __FILE__, __LINE__); 4883141cc406Sopenharmony_ci Outb (CONTROL, control); 4884141cc406Sopenharmony_ci Outb (DATA, data); 4885141cc406Sopenharmony_ci return 0; 4886141cc406Sopenharmony_ci } 4887141cc406Sopenharmony_ci 4888141cc406Sopenharmony_ci /* next */ 4889141cc406Sopenharmony_ci count -= 0x10; 4890141cc406Sopenharmony_ci } 4891141cc406Sopenharmony_ci while (count > 0); 4892141cc406Sopenharmony_ci 4893141cc406Sopenharmony_ci /* restore port , successful exit */ 4894141cc406Sopenharmony_ci Outb (CONTROL, control); 4895141cc406Sopenharmony_ci Outb (DATA, data); 4896141cc406Sopenharmony_ci return 1; 4897141cc406Sopenharmony_ci} 4898141cc406Sopenharmony_ci 4899141cc406Sopenharmony_ci 4900141cc406Sopenharmony_ci/* sends len bytes to scanner */ 4901141cc406Sopenharmony_ci/* needs data channel to be set up */ 4902141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 4903141cc406Sopenharmony_cistatic int 4904141cc406Sopenharmony_cisendLength (int *cmd, int len) 4905141cc406Sopenharmony_ci{ 4906141cc406Sopenharmony_ci int i; 4907141cc406Sopenharmony_ci int reg, wait; 4908141cc406Sopenharmony_ci int try = 0; 4909141cc406Sopenharmony_ci 4910141cc406Sopenharmony_ci /* send header */ 4911141cc406Sopenharmony_ciretry: 4912141cc406Sopenharmony_ci wait = registerRead (0x19) & 0xF8; 4913141cc406Sopenharmony_ci 4914141cc406Sopenharmony_ci registerWrite (0x1C, 0x55); 4915141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4916141cc406Sopenharmony_ci 4917141cc406Sopenharmony_ci registerWrite (0x1C, 0xAA); 4918141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4919141cc406Sopenharmony_ci 4920141cc406Sopenharmony_ci /* sync when needed */ 4921141cc406Sopenharmony_ci if ((wait & 0x08) == 0x00) 4922141cc406Sopenharmony_ci { 4923141cc406Sopenharmony_ci reg = registerRead (0x1C); 4924141cc406Sopenharmony_ci while (((reg & 0x10) != 0x10) && (reg != 0x6B) && (reg != 0xAB) 4925141cc406Sopenharmony_ci && (reg != 0x23)) 4926141cc406Sopenharmony_ci { 4927141cc406Sopenharmony_ci DBG (0, 4928141cc406Sopenharmony_ci "sendLength failed, expected reg & 0x10=0x10 , found 0x%02X (%s:%d)\n", 4929141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 4930141cc406Sopenharmony_ci if (try > 10) 4931141cc406Sopenharmony_ci { 4932141cc406Sopenharmony_ci DBG (0, "Aborting...\n"); 4933141cc406Sopenharmony_ci return 0; 4934141cc406Sopenharmony_ci } 4935141cc406Sopenharmony_ci else 4936141cc406Sopenharmony_ci { 4937141cc406Sopenharmony_ci DBG (0, "Retrying ...\n"); 4938141cc406Sopenharmony_ci } 4939141cc406Sopenharmony_ci /* resend */ 4940141cc406Sopenharmony_ci epilogue (); 4941141cc406Sopenharmony_ci prologue (0x10); 4942141cc406Sopenharmony_ci try++; 4943141cc406Sopenharmony_ci goto retry; 4944141cc406Sopenharmony_ci } 4945141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 4946141cc406Sopenharmony_ci { 4947141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 4948141cc406Sopenharmony_ci if (reg != 0xC8) 4949141cc406Sopenharmony_ci { 4950141cc406Sopenharmony_ci DBG (0, "Unexpected reg19=0x%2X (%s:%d)\n", reg, __FILE__, 4951141cc406Sopenharmony_ci __LINE__); 4952141cc406Sopenharmony_ci /* 0xF0 certainly means error */ 4953141cc406Sopenharmony_ci if ((reg == 0xC0) || (reg == 0xD0) || (reg == 0x80)) 4954141cc406Sopenharmony_ci { 4955141cc406Sopenharmony_ci /* resend */ 4956141cc406Sopenharmony_ci try++; 4957141cc406Sopenharmony_ci if (try > 20) 4958141cc406Sopenharmony_ci { 4959141cc406Sopenharmony_ci DBG (0, "sendLength retry failed (%s:%d)\n", __FILE__, 4960141cc406Sopenharmony_ci __LINE__); 4961141cc406Sopenharmony_ci return 0; 4962141cc406Sopenharmony_ci } 4963141cc406Sopenharmony_ci 4964141cc406Sopenharmony_ci epilogue (); 4965141cc406Sopenharmony_ci sendCommand (0x00); 4966141cc406Sopenharmony_ci sendCommand (0xE0); 4967141cc406Sopenharmony_ci Outb (DATA, 0x00); 4968141cc406Sopenharmony_ci Outb (CONTROL, 0x01); 4969141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 4970141cc406Sopenharmony_ci sendCommand (0x30); 4971141cc406Sopenharmony_ci 4972141cc406Sopenharmony_ci prologue (0x10); 4973141cc406Sopenharmony_ci goto retry; 4974141cc406Sopenharmony_ci } 4975141cc406Sopenharmony_ci } 4976141cc406Sopenharmony_ci } 4977141cc406Sopenharmony_ci do 4978141cc406Sopenharmony_ci { 4979141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0) && (reg != 0xC8)) 4980141cc406Sopenharmony_ci { 4981141cc406Sopenharmony_ci /* status has changed while waiting */ 4982141cc406Sopenharmony_ci /* but it's too early */ 4983141cc406Sopenharmony_ci DBG (0, "Unexpected reg19=0x%2X (%s:%d)\n", reg, __FILE__, 4984141cc406Sopenharmony_ci __LINE__); 4985141cc406Sopenharmony_ci } 4986141cc406Sopenharmony_ci /* 0xF0 certainly means error */ 4987141cc406Sopenharmony_ci if ((reg == 0xC0) || (reg == 0xD0) || (reg == 0x80)) 4988141cc406Sopenharmony_ci { 4989141cc406Sopenharmony_ci /* resend */ 4990141cc406Sopenharmony_ci try++; 4991141cc406Sopenharmony_ci epilogue (); 4992141cc406Sopenharmony_ci 4993141cc406Sopenharmony_ci sendCommand (0x00); 4994141cc406Sopenharmony_ci sendCommand (0xE0); 4995141cc406Sopenharmony_ci Outb (DATA, 0x00); 4996141cc406Sopenharmony_ci Outb (CONTROL, 0x01); 4997141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 4998141cc406Sopenharmony_ci sendCommand (0x30); 4999141cc406Sopenharmony_ci 5000141cc406Sopenharmony_ci prologue (0x10); 5001141cc406Sopenharmony_ci goto retry; 5002141cc406Sopenharmony_ci } 5003141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5004141cc406Sopenharmony_ci } 5005141cc406Sopenharmony_ci while (reg != 0xC8); 5006141cc406Sopenharmony_ci } 5007141cc406Sopenharmony_ci 5008141cc406Sopenharmony_ci /* send bytes */ 5009141cc406Sopenharmony_ci i = 0; 5010141cc406Sopenharmony_ci while ((reg == 0xC8) && (i < len)) 5011141cc406Sopenharmony_ci { 5012141cc406Sopenharmony_ci /* write byte */ 5013141cc406Sopenharmony_ci registerWrite (0x1C, cmd[i]); 5014141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5015141cc406Sopenharmony_ci 5016141cc406Sopenharmony_ci /* 1B handling: escape it to confirm value */ 5017141cc406Sopenharmony_ci if (cmd[i] == 0x1B) 5018141cc406Sopenharmony_ci { 5019141cc406Sopenharmony_ci registerWrite (0x1C, cmd[i]); 5020141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5021141cc406Sopenharmony_ci } 5022141cc406Sopenharmony_ci i++; 5023141cc406Sopenharmony_ci } 5024141cc406Sopenharmony_ci DBG (16, "sendLength, reg19=0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 5025141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 5026141cc406Sopenharmony_ci { 5027141cc406Sopenharmony_ci DBG (0, 5028141cc406Sopenharmony_ci "sendLength failed got 0x%02X instead of 0xC0 or 0xD0 (%s:%d)\n", 5029141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 5030141cc406Sopenharmony_ci DBG (0, "Blindly going on .....\n"); 5031141cc406Sopenharmony_ci } 5032141cc406Sopenharmony_ci 5033141cc406Sopenharmony_ci /* check if 'finished status' received too early */ 5034141cc406Sopenharmony_ci if (((reg == 0xC0) || (reg == 0xD0)) && (i != len)) 5035141cc406Sopenharmony_ci { 5036141cc406Sopenharmony_ci DBG (0, "sendLength failed: sent only %d bytes out of %d (%s:%d)\n", i, 5037141cc406Sopenharmony_ci len, __FILE__, __LINE__); 5038141cc406Sopenharmony_ci return 0; 5039141cc406Sopenharmony_ci } 5040141cc406Sopenharmony_ci 5041141cc406Sopenharmony_ci 5042141cc406Sopenharmony_ci reg = registerRead (0x1C); 5043141cc406Sopenharmony_ci DBG (16, "sendLength, reg1C=0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 5044141cc406Sopenharmony_ci 5045141cc406Sopenharmony_ci /* model 0x07 has always the last bit set to 1 */ 5046141cc406Sopenharmony_ci scannerStatus = reg & 0xFC; 5047141cc406Sopenharmony_ci reg = reg & 0x10; 5048141cc406Sopenharmony_ci if ((reg != 0x10) && (scannerStatus != 0x68) && (scannerStatus != 0xA8)) 5049141cc406Sopenharmony_ci { 5050141cc406Sopenharmony_ci DBG (0, "sendLength failed: acknowledge not received (%s:%d)\n", 5051141cc406Sopenharmony_ci __FILE__, __LINE__); 5052141cc406Sopenharmony_ci return 0; 5053141cc406Sopenharmony_ci } 5054141cc406Sopenharmony_ci if (try) 5055141cc406Sopenharmony_ci { 5056141cc406Sopenharmony_ci DBG (0, "sendLength retry success (retry %d time%s) ... (%s:%d)\n", try, 5057141cc406Sopenharmony_ci (try > 1) ? "s" : "", __FILE__, __LINE__); 5058141cc406Sopenharmony_ci } 5059141cc406Sopenharmony_ci return 1; 5060141cc406Sopenharmony_ci} 5061141cc406Sopenharmony_ci 5062141cc406Sopenharmony_ci 5063141cc406Sopenharmony_ci/* sends data bytes to scanner */ 5064141cc406Sopenharmony_ci/* needs data channel to be set up */ 5065141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 5066141cc406Sopenharmony_cistatic int 5067141cc406Sopenharmony_cisendData610p (int *cmd, int len) 5068141cc406Sopenharmony_ci{ 5069141cc406Sopenharmony_ci int i, status, j; 5070141cc406Sopenharmony_ci 5071141cc406Sopenharmony_ci i = 0; 5072141cc406Sopenharmony_ci status = 0xC8; 5073141cc406Sopenharmony_ci /* while ((i < len) && ((status & 0x08) == 0x08)) XXX STEF XXX */ 5074141cc406Sopenharmony_ci while (i < len) 5075141cc406Sopenharmony_ci { 5076141cc406Sopenharmony_ci /* escape special values */ 5077141cc406Sopenharmony_ci if (cmd[i] == 0x1B) 5078141cc406Sopenharmony_ci status = putByte610p (0x1B); 5079141cc406Sopenharmony_ci if (i > 0) 5080141cc406Sopenharmony_ci { 5081141cc406Sopenharmony_ci if ((cmd[i] == 0xAA) && (cmd[i - 1] == 0x55)) 5082141cc406Sopenharmony_ci status = putByte610p (0x1B); 5083141cc406Sopenharmony_ci } 5084141cc406Sopenharmony_ci /* regular values */ 5085141cc406Sopenharmony_ci status = putByte610p (cmd[i]); 5086141cc406Sopenharmony_ci i++; 5087141cc406Sopenharmony_ci } 5088141cc406Sopenharmony_ci j = 0; 5089141cc406Sopenharmony_ci while ((status & 0x08) && (j < 256)) 5090141cc406Sopenharmony_ci { 5091141cc406Sopenharmony_ci status = getStatus610p (); 5092141cc406Sopenharmony_ci j++; 5093141cc406Sopenharmony_ci } 5094141cc406Sopenharmony_ci if ((status != 0xC0) && (status != 0xD0)) 5095141cc406Sopenharmony_ci { 5096141cc406Sopenharmony_ci DBG (0, 5097141cc406Sopenharmony_ci "sendData610p() failed, status=0x%02X, expected 0xC0 or 0xD0 (%s:%d)\n", 5098141cc406Sopenharmony_ci status, __FILE__, __LINE__); 5099141cc406Sopenharmony_ci return 0; 5100141cc406Sopenharmony_ci } 5101141cc406Sopenharmony_ci 5102141cc406Sopenharmony_ci /* check if 'finished status' received too early */ 5103141cc406Sopenharmony_ci if (i < len) 5104141cc406Sopenharmony_ci { 5105141cc406Sopenharmony_ci DBG (0, "sendData610p failed: sent only %d bytes out of %d (%s:%d)\n", 5106141cc406Sopenharmony_ci i, len, __FILE__, __LINE__); 5107141cc406Sopenharmony_ci return 0; 5108141cc406Sopenharmony_ci } 5109141cc406Sopenharmony_ci return 1; 5110141cc406Sopenharmony_ci} 5111141cc406Sopenharmony_ci 5112141cc406Sopenharmony_ci 5113141cc406Sopenharmony_ci/* sends data bytes to scanner */ 5114141cc406Sopenharmony_ci/* needs data channel to be set up */ 5115141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 5116141cc406Sopenharmony_cistatic int 5117141cc406Sopenharmony_cisendData (int *cmd, int len) 5118141cc406Sopenharmony_ci{ 5119141cc406Sopenharmony_ci int i; 5120141cc406Sopenharmony_ci int reg; 5121141cc406Sopenharmony_ci 5122141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 5123141cc406Sopenharmony_ci return sendData610p (cmd, len); 5124141cc406Sopenharmony_ci 5125141cc406Sopenharmony_ci /* send header */ 5126141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5127141cc406Sopenharmony_ci 5128141cc406Sopenharmony_ci /* send bytes */ 5129141cc406Sopenharmony_ci i = 0; 5130141cc406Sopenharmony_ci while ((reg == 0xC8) && (i < len)) 5131141cc406Sopenharmony_ci { 5132141cc406Sopenharmony_ci /* write byte */ 5133141cc406Sopenharmony_ci registerWrite (0x1C, cmd[i]); 5134141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5135141cc406Sopenharmony_ci 5136141cc406Sopenharmony_ci /* 1B handling: escape it to confirm value */ 5137141cc406Sopenharmony_ci if (cmd[i] == 0x1B) 5138141cc406Sopenharmony_ci { 5139141cc406Sopenharmony_ci registerWrite (0x1C, 0x1B); 5140141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5141141cc406Sopenharmony_ci } 5142141cc406Sopenharmony_ci 5143141cc406Sopenharmony_ci /* escape 55 AA pattern by adding 1B */ 5144141cc406Sopenharmony_ci if ((i < len - 1) && (cmd[i] == 0x55) && (cmd[i + 1] == 0xAA)) 5145141cc406Sopenharmony_ci { 5146141cc406Sopenharmony_ci registerWrite (0x1C, 0x1B); 5147141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5148141cc406Sopenharmony_ci } 5149141cc406Sopenharmony_ci 5150141cc406Sopenharmony_ci /* next value */ 5151141cc406Sopenharmony_ci i++; 5152141cc406Sopenharmony_ci } 5153141cc406Sopenharmony_ci DBG (16, "sendData, reg19=0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 5154141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 5155141cc406Sopenharmony_ci { 5156141cc406Sopenharmony_ci DBG (0, "sendData failed got 0x%02X instead of 0xC0 or 0xD0 (%s:%d)\n", 5157141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 5158141cc406Sopenharmony_ci DBG (0, "Blindly going on .....\n"); 5159141cc406Sopenharmony_ci } 5160141cc406Sopenharmony_ci 5161141cc406Sopenharmony_ci /* check if 'finished status' received too early */ 5162141cc406Sopenharmony_ci if (((reg == 0xC0) || (reg == 0xD0)) && (i < len)) 5163141cc406Sopenharmony_ci { 5164141cc406Sopenharmony_ci DBG (0, "sendData failed: sent only %d bytes out of %d (%s:%d)\n", i, 5165141cc406Sopenharmony_ci len, __FILE__, __LINE__); 5166141cc406Sopenharmony_ci return 0; 5167141cc406Sopenharmony_ci } 5168141cc406Sopenharmony_ci 5169141cc406Sopenharmony_ci 5170141cc406Sopenharmony_ci reg = registerRead (0x1C); 5171141cc406Sopenharmony_ci DBG (16, "sendData, reg1C=0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 5172141cc406Sopenharmony_ci 5173141cc406Sopenharmony_ci /* model 0x07 has always the last bit set to 1 */ 5174141cc406Sopenharmony_ci scannerStatus = reg & 0xFC; 5175141cc406Sopenharmony_ci reg = reg & 0x10; 5176141cc406Sopenharmony_ci if ((reg != 0x10) && (scannerStatus != 0x68) && (scannerStatus != 0xA8) 5177141cc406Sopenharmony_ci && (scannerStatus != 0x20)) 5178141cc406Sopenharmony_ci { 5179141cc406Sopenharmony_ci DBG (0, "sendData failed: acknowledge not received (%s:%d)\n", __FILE__, 5180141cc406Sopenharmony_ci __LINE__); 5181141cc406Sopenharmony_ci return 0; 5182141cc406Sopenharmony_ci } 5183141cc406Sopenharmony_ci return 1; 5184141cc406Sopenharmony_ci} 5185141cc406Sopenharmony_ci 5186141cc406Sopenharmony_ci 5187141cc406Sopenharmony_ci/* receive data bytes from scanner */ 5188141cc406Sopenharmony_ci/* needs data channel to be set up */ 5189141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 5190141cc406Sopenharmony_ci/* uses pausedBufferRead */ 5191141cc406Sopenharmony_cistatic int 5192141cc406Sopenharmony_cipausedReadData (int size, unsigned char *dest) 5193141cc406Sopenharmony_ci{ 5194141cc406Sopenharmony_ci int reg; 5195141cc406Sopenharmony_ci int tmp; 5196141cc406Sopenharmony_ci int read; 5197141cc406Sopenharmony_ci 5198141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0D); 5199141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 5200141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5201141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 5202141cc406Sopenharmony_ci { 5203141cc406Sopenharmony_ci DBG (0, "Unexpected reg19: 0x%02X instead of 0xC0 or 0xD0 (%s:%d)\n", 5204141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 5205141cc406Sopenharmony_ci return 0; 5206141cc406Sopenharmony_ci } 5207141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 5208141cc406Sopenharmony_ci { 5209141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x44); 5210141cc406Sopenharmony_ci } 5211141cc406Sopenharmony_ci REGISTERREAD (0x0C, 0x04); 5212141cc406Sopenharmony_ci REGISTERWRITE (0x0C, 0x44); /* sets data direction ? */ 5213141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 5214141cc406Sopenharmony_ci { 5215141cc406Sopenharmony_ci compatMode (); 5216141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset ? */ 5217141cc406Sopenharmony_ci ECPSetBuffer (size); 5218141cc406Sopenharmony_ci read = ECPbufferRead (size, dest); 5219141cc406Sopenharmony_ci DBG (16, "ECPbufferRead(%d,dest) passed (%s:%d)\n", size, __FILE__, 5220141cc406Sopenharmony_ci __LINE__); 5221141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x84); 5222141cc406Sopenharmony_ci } 5223141cc406Sopenharmony_ci else 5224141cc406Sopenharmony_ci { 5225141cc406Sopenharmony_ci read = pausedBufferRead (size, dest); 5226141cc406Sopenharmony_ci } 5227141cc406Sopenharmony_ci if (read < size) 5228141cc406Sopenharmony_ci { 5229141cc406Sopenharmony_ci DBG (16, 5230141cc406Sopenharmony_ci "pausedBufferRead(%d,dest) failed, only got %d bytes (%s:%d)\n", 5231141cc406Sopenharmony_ci size, read, __FILE__, __LINE__); 5232141cc406Sopenharmony_ci return 0; 5233141cc406Sopenharmony_ci } 5234141cc406Sopenharmony_ci DBG (16, "pausedBufferRead(%d,dest) passed (%s:%d)\n", size, __FILE__, 5235141cc406Sopenharmony_ci __LINE__); 5236141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0D); 5237141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 5238141cc406Sopenharmony_ci return 1; 5239141cc406Sopenharmony_ci} 5240141cc406Sopenharmony_ci 5241141cc406Sopenharmony_ci 5242141cc406Sopenharmony_ci 5243141cc406Sopenharmony_ci/* receive data bytes from scanner */ 5244141cc406Sopenharmony_ci/* needs data channel to be set up */ 5245141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 5246141cc406Sopenharmony_cistatic int 5247141cc406Sopenharmony_cireceiveData610p (int *cmd, int len) 5248141cc406Sopenharmony_ci{ 5249141cc406Sopenharmony_ci int i; 5250141cc406Sopenharmony_ci int status; 5251141cc406Sopenharmony_ci 5252141cc406Sopenharmony_ci i = 0; 5253141cc406Sopenharmony_ci status = 0xD0; 5254141cc406Sopenharmony_ci byteMode (); 5255141cc406Sopenharmony_ci while (i < len) 5256141cc406Sopenharmony_ci { 5257141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 5258141cc406Sopenharmony_ci Outb (CONTROL, 0x26); /* data reverse+ 'reg' */ 5259141cc406Sopenharmony_ci cmd[i] = Inb (DATA); 5260141cc406Sopenharmony_ci Outb (CONTROL, 0x24); /* data reverse+ 'reg' */ 5261141cc406Sopenharmony_ci i++; 5262141cc406Sopenharmony_ci } 5263141cc406Sopenharmony_ci if (status != 0xC0) 5264141cc406Sopenharmony_ci { 5265141cc406Sopenharmony_ci DBG (0, "receiveData610p failed got 0x%02X instead of 0xC0 (%s:%d)\n", 5266141cc406Sopenharmony_ci status, __FILE__, __LINE__); 5267141cc406Sopenharmony_ci DBG (0, "Blindly going on .....\n"); 5268141cc406Sopenharmony_ci } 5269141cc406Sopenharmony_ci 5270141cc406Sopenharmony_ci /* check if 'finished status' received to early */ 5271141cc406Sopenharmony_ci if ((status == 0xC0) && (i != len)) 5272141cc406Sopenharmony_ci { 5273141cc406Sopenharmony_ci DBG (0, 5274141cc406Sopenharmony_ci "receiveData610p failed: received only %d bytes out of %d (%s:%d)\n", 5275141cc406Sopenharmony_ci i, len, __FILE__, __LINE__); 5276141cc406Sopenharmony_ci return 0; 5277141cc406Sopenharmony_ci } 5278141cc406Sopenharmony_ci return 1; 5279141cc406Sopenharmony_ci} 5280141cc406Sopenharmony_ci 5281141cc406Sopenharmony_ci/* receive data bytes from scanner */ 5282141cc406Sopenharmony_ci/* needs data channel to be set up */ 5283141cc406Sopenharmony_ci/* returns 1 on success, 0 otherwise */ 5284141cc406Sopenharmony_cistatic int 5285141cc406Sopenharmony_cireceiveData (int *cmd, int len) 5286141cc406Sopenharmony_ci{ 5287141cc406Sopenharmony_ci int i; 5288141cc406Sopenharmony_ci int reg; 5289141cc406Sopenharmony_ci 5290141cc406Sopenharmony_ci /* send header */ 5291141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5292141cc406Sopenharmony_ci 5293141cc406Sopenharmony_ci /* send bytes */ 5294141cc406Sopenharmony_ci i = 0; 5295141cc406Sopenharmony_ci while (((reg == 0xD0) || (reg == 0xC0)) && (i < len)) 5296141cc406Sopenharmony_ci { 5297141cc406Sopenharmony_ci /* write byte */ 5298141cc406Sopenharmony_ci cmd[i] = registerRead (0x1C); 5299141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5300141cc406Sopenharmony_ci i++; 5301141cc406Sopenharmony_ci } 5302141cc406Sopenharmony_ci DBG (16, "receiveData, reg19=0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 5303141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 5304141cc406Sopenharmony_ci { 5305141cc406Sopenharmony_ci DBG (0, "sendData failed got 0x%02X instead of 0xC0 or 0xD0 (%s:%d)\n", 5306141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 5307141cc406Sopenharmony_ci DBG (0, "Blindly going on .....\n"); 5308141cc406Sopenharmony_ci } 5309141cc406Sopenharmony_ci 5310141cc406Sopenharmony_ci /* check if 'finished status' received to early */ 5311141cc406Sopenharmony_ci if (((reg == 0xC0) || (reg == 0xD0)) && (i != len)) 5312141cc406Sopenharmony_ci { 5313141cc406Sopenharmony_ci DBG (0, 5314141cc406Sopenharmony_ci "receiveData failed: received only %d bytes out of %d (%s:%d)\n", 5315141cc406Sopenharmony_ci i, len, __FILE__, __LINE__); 5316141cc406Sopenharmony_ci return 0; 5317141cc406Sopenharmony_ci } 5318141cc406Sopenharmony_ci 5319141cc406Sopenharmony_ci 5320141cc406Sopenharmony_ci reg = registerRead (0x1C); 5321141cc406Sopenharmony_ci DBG (16, "receiveData, reg1C=0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 5322141cc406Sopenharmony_ci 5323141cc406Sopenharmony_ci /* model 0x07 has always the last bit set to 1 */ 5324141cc406Sopenharmony_ci scannerStatus = reg & 0xF8; 5325141cc406Sopenharmony_ci reg = reg & 0x10; 5326141cc406Sopenharmony_ci if ((reg != 0x10) && (scannerStatus != 0x68) && (scannerStatus != 0xA8)) 5327141cc406Sopenharmony_ci { 5328141cc406Sopenharmony_ci DBG (0, "receiveData failed: acknowledge not received (%s:%d)\n", 5329141cc406Sopenharmony_ci __FILE__, __LINE__); 5330141cc406Sopenharmony_ci return 0; 5331141cc406Sopenharmony_ci } 5332141cc406Sopenharmony_ci return 1; 5333141cc406Sopenharmony_ci} 5334141cc406Sopenharmony_ci 5335141cc406Sopenharmony_ci 5336141cc406Sopenharmony_ci/* 1=success, 0 failed */ 5337141cc406Sopenharmony_cistatic int 5338141cc406Sopenharmony_cifonc001 (void) 5339141cc406Sopenharmony_ci{ 5340141cc406Sopenharmony_ci int i; 5341141cc406Sopenharmony_ci int res; 5342141cc406Sopenharmony_ci int reg; 5343141cc406Sopenharmony_ci 5344141cc406Sopenharmony_ci res = 1; 5345141cc406Sopenharmony_ci while (res == 1) 5346141cc406Sopenharmony_ci { 5347141cc406Sopenharmony_ci registerWrite (0x1A, 0x0C); 5348141cc406Sopenharmony_ci registerWrite (0x18, 0x40); 5349141cc406Sopenharmony_ci 5350141cc406Sopenharmony_ci /* send 0x06 */ 5351141cc406Sopenharmony_ci registerWrite (0x1A, 0x06); 5352141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 5353141cc406Sopenharmony_ci { 5354141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5355141cc406Sopenharmony_ci if ((reg & 0x78) == 0x38) 5356141cc406Sopenharmony_ci { 5357141cc406Sopenharmony_ci res = 0; 5358141cc406Sopenharmony_ci break; 5359141cc406Sopenharmony_ci } 5360141cc406Sopenharmony_ci } 5361141cc406Sopenharmony_ci if (res == 1) 5362141cc406Sopenharmony_ci { 5363141cc406Sopenharmony_ci registerWrite (0x1A, 0x00); 5364141cc406Sopenharmony_ci registerWrite (0x1A, 0x0C); 5365141cc406Sopenharmony_ci } 5366141cc406Sopenharmony_ci } 5367141cc406Sopenharmony_ci 5368141cc406Sopenharmony_ci /* send 0x07 */ 5369141cc406Sopenharmony_ci registerWrite (0x1A, 0x07); 5370141cc406Sopenharmony_ci res = 1; 5371141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 5372141cc406Sopenharmony_ci { 5373141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5374141cc406Sopenharmony_ci if ((reg & 0x78) == 0x38) 5375141cc406Sopenharmony_ci { 5376141cc406Sopenharmony_ci res = 0; 5377141cc406Sopenharmony_ci break; 5378141cc406Sopenharmony_ci } 5379141cc406Sopenharmony_ci } 5380141cc406Sopenharmony_ci if (res != 0) 5381141cc406Sopenharmony_ci return 0; 5382141cc406Sopenharmony_ci 5383141cc406Sopenharmony_ci /* send 0x04 */ 5384141cc406Sopenharmony_ci registerWrite (0x1A, 0x04); 5385141cc406Sopenharmony_ci res = 1; 5386141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 5387141cc406Sopenharmony_ci { 5388141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 5389141cc406Sopenharmony_ci if ((reg & 0xF8) == 0xF8) 5390141cc406Sopenharmony_ci { 5391141cc406Sopenharmony_ci res = 0; 5392141cc406Sopenharmony_ci break; 5393141cc406Sopenharmony_ci } 5394141cc406Sopenharmony_ci } 5395141cc406Sopenharmony_ci if (res != 0) 5396141cc406Sopenharmony_ci return 0; 5397141cc406Sopenharmony_ci 5398141cc406Sopenharmony_ci /* send 0x05 */ 5399141cc406Sopenharmony_ci registerWrite (0x1A, 0x05); 5400141cc406Sopenharmony_ci res = 1; 5401141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 5402141cc406Sopenharmony_ci { 5403141cc406Sopenharmony_ci reg = registerRead (0x1A); 5404141cc406Sopenharmony_ci if (reg == 0x05) 5405141cc406Sopenharmony_ci { 5406141cc406Sopenharmony_ci res = 0; 5407141cc406Sopenharmony_ci break; 5408141cc406Sopenharmony_ci } 5409141cc406Sopenharmony_ci } 5410141cc406Sopenharmony_ci if (res != 0) 5411141cc406Sopenharmony_ci return 0; 5412141cc406Sopenharmony_ci 5413141cc406Sopenharmony_ci /* end */ 5414141cc406Sopenharmony_ci registerWrite (0x1A, 0x84); 5415141cc406Sopenharmony_ci return 1; 5416141cc406Sopenharmony_ci} 5417141cc406Sopenharmony_ci 5418141cc406Sopenharmony_ci 5419141cc406Sopenharmony_ci 5420141cc406Sopenharmony_ci 5421141cc406Sopenharmony_ci 5422141cc406Sopenharmony_ci 5423141cc406Sopenharmony_ci 5424141cc406Sopenharmony_ci/* 1 OK, 0 failed */ 5425141cc406Sopenharmony_cistatic int 5426141cc406Sopenharmony_cifoncSendWord (int *cmd) 5427141cc406Sopenharmony_ci{ 5428141cc406Sopenharmony_ci prologue (0x10); 5429141cc406Sopenharmony_ci if (sendWord (cmd) == 0) 5430141cc406Sopenharmony_ci { 5431141cc406Sopenharmony_ci DBG (0, "sendWord(cmd) failed (%s:%d)\n", __FILE__, __LINE__); 5432141cc406Sopenharmony_ci return 0; 5433141cc406Sopenharmony_ci } 5434141cc406Sopenharmony_ci epilogue (); 5435141cc406Sopenharmony_ci 5436141cc406Sopenharmony_ci return 1; 5437141cc406Sopenharmony_ci} 5438141cc406Sopenharmony_ci 5439141cc406Sopenharmony_ci 5440141cc406Sopenharmony_cistatic int 5441141cc406Sopenharmony_cicmdSetDataBuffer (int *data) 5442141cc406Sopenharmony_ci{ 5443141cc406Sopenharmony_ci int cmd1[] = { 0x00, 0x00, 0x22, 0x88, -1 }; /* 34 bytes write on channel 8 */ 5444141cc406Sopenharmony_ci int cmd2[] = 5445141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x03, 0xC1, 0x80, 5446141cc406Sopenharmony_ci 0x00, 0x20, 0x02, 0x00, 0x16, 0x41, 0xE0, 0xAC, 0x03, 0x03, 0x00, 0x00, 5447141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, -1 5448141cc406Sopenharmony_ci }; 5449141cc406Sopenharmony_ci int cmd3[] = { 0x00, 0x08, 0x00, 0x84, -1 }; /* 2048 bytes size write on channel 4 (data) */ 5450141cc406Sopenharmony_ci int cmd4[] = { 0x00, 0x08, 0x00, 0xC4, -1 }; /* 2048 bytes size read on channel 4 (data) */ 5451141cc406Sopenharmony_ci int i; 5452141cc406Sopenharmony_ci unsigned char dest[2048]; 5453141cc406Sopenharmony_ci 5454141cc406Sopenharmony_ci /* cmdSet(8,34,cmd2), but without prologue/epilogue */ 5455141cc406Sopenharmony_ci /* set block length to 34 bytes on 'channel 8' */ 5456141cc406Sopenharmony_ci sendWord (cmd1); 5457141cc406Sopenharmony_ci DBG (16, "sendWord(cmd1) passed (%s:%d) \n", __FILE__, __LINE__); 5458141cc406Sopenharmony_ci 5459141cc406Sopenharmony_ci /* sendData */ 5460141cc406Sopenharmony_ci sendData (cmd2, 0x22); 5461141cc406Sopenharmony_ci DBG (16, "sendData(cmd2) passed (%s:%d) \n", __FILE__, __LINE__); 5462141cc406Sopenharmony_ci 5463141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 5464141cc406Sopenharmony_ci { 5465141cc406Sopenharmony_ci bloc8Decode (cmd2); 5466141cc406Sopenharmony_ci } 5467141cc406Sopenharmony_ci 5468141cc406Sopenharmony_ci /* set block length to 2048, write on 'channel 4' */ 5469141cc406Sopenharmony_ci sendWord (cmd3); 5470141cc406Sopenharmony_ci DBG (16, "sendWord(cmd3) passed (%s:%d) \n", __FILE__, __LINE__); 5471141cc406Sopenharmony_ci 5472141cc406Sopenharmony_ci if (sendData (data, 2048) == 0) 5473141cc406Sopenharmony_ci { 5474141cc406Sopenharmony_ci DBG (0, "sendData(data,%d) failed (%s:%d)\n", 2048, __FILE__, __LINE__); 5475141cc406Sopenharmony_ci return 0; 5476141cc406Sopenharmony_ci } 5477141cc406Sopenharmony_ci TRACE (16, "sendData(data,2048) passed ..."); 5478141cc406Sopenharmony_ci 5479141cc406Sopenharmony_ci /* read back all data sent to 'channel 4' */ 5480141cc406Sopenharmony_ci sendWord (cmd4); 5481141cc406Sopenharmony_ci DBG (16, "sendWord(cmd4) passed (%s:%d) \n", __FILE__, __LINE__); 5482141cc406Sopenharmony_ci 5483141cc406Sopenharmony_ci if (pausedReadData (2048, dest) == 0) 5484141cc406Sopenharmony_ci { 5485141cc406Sopenharmony_ci DBG (16, "pausedReadData(2048,dest) failed (%s:%d)\n", __FILE__, 5486141cc406Sopenharmony_ci __LINE__); 5487141cc406Sopenharmony_ci return 0; 5488141cc406Sopenharmony_ci } 5489141cc406Sopenharmony_ci DBG (16, "pausedReadData(2048,dest) passed (%s:%d)\n", __FILE__, __LINE__); 5490141cc406Sopenharmony_ci 5491141cc406Sopenharmony_ci /* dest should hold the same data than donnees */ 5492141cc406Sopenharmony_ci for (i = 0; i < 2047; i++) 5493141cc406Sopenharmony_ci { 5494141cc406Sopenharmony_ci if (data[i] != (int) (dest[i])) 5495141cc406Sopenharmony_ci { 5496141cc406Sopenharmony_ci DBG 5497141cc406Sopenharmony_ci (0, 5498141cc406Sopenharmony_ci "Warning data read back differs: expected %02X found dest[%d]=%02X ! (%s:%d)\n", 5499141cc406Sopenharmony_ci data[i], i, dest[i], __FILE__, __LINE__); 5500141cc406Sopenharmony_ci } 5501141cc406Sopenharmony_ci } 5502141cc406Sopenharmony_ci return 1; 5503141cc406Sopenharmony_ci} 5504141cc406Sopenharmony_ci 5505141cc406Sopenharmony_ci 5506141cc406Sopenharmony_ci/* 1: OK 5507141cc406Sopenharmony_ci 0: end session failed */ 5508141cc406Sopenharmony_ci 5509141cc406Sopenharmony_ciint 5510141cc406Sopenharmony_cisanei_umax_pp_endSession (void) 5511141cc406Sopenharmony_ci{ 5512141cc406Sopenharmony_ci int zero[5] = { 0, 0, 0, 0, -1 }; 5513141cc406Sopenharmony_ci 5514141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () != 610) 5515141cc406Sopenharmony_ci { 5516141cc406Sopenharmony_ci prologue (0x00); 5517141cc406Sopenharmony_ci sendWord (zero); 5518141cc406Sopenharmony_ci epilogue (); 5519141cc406Sopenharmony_ci sanei_umax_pp_cmdSync (0xC2); 5520141cc406Sopenharmony_ci sanei_umax_pp_cmdSync (0x00); /* cancels any pending operation */ 5521141cc406Sopenharmony_ci sanei_umax_pp_cmdSync (0x00); /* cancels any pending operation */ 5522141cc406Sopenharmony_ci } 5523141cc406Sopenharmony_ci else 5524141cc406Sopenharmony_ci { 5525141cc406Sopenharmony_ci CMDSYNC (0x00); 5526141cc406Sopenharmony_ci CMDSYNC (0xC2); 5527141cc406Sopenharmony_ci CMDSYNC (0x00); 5528141cc406Sopenharmony_ci CMDSYNC (0x00); 5529141cc406Sopenharmony_ci } 5530141cc406Sopenharmony_ci compatMode (); 5531141cc406Sopenharmony_ci 5532141cc406Sopenharmony_ci /* restore port state */ 5533141cc406Sopenharmony_ci Outb (DATA, gData); 5534141cc406Sopenharmony_ci Outb (CONTROL, gControl); 5535141cc406Sopenharmony_ci 5536141cc406Sopenharmony_ci /* OUF */ 5537141cc406Sopenharmony_ci DBG (1, "End session done ...\n"); 5538141cc406Sopenharmony_ci return 1; 5539141cc406Sopenharmony_ci} 5540141cc406Sopenharmony_ci 5541141cc406Sopenharmony_ci 5542141cc406Sopenharmony_ci/* initialize scanner with default values 5543141cc406Sopenharmony_ci * and do head re-homing if needed */ 5544141cc406Sopenharmony_ciint 5545141cc406Sopenharmony_ciinitScanner610p (int recover) 5546141cc406Sopenharmony_ci{ 5547141cc406Sopenharmony_ci int first, rc, x; 5548141cc406Sopenharmony_ci int cmd55AA[9] = { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, -1 }; 5549141cc406Sopenharmony_ci int cmd02[17] = { 0x02, 0x80, 0x00, 0x40, 0x30, 0x00, 0xC0, 0x2F, 5550141cc406Sopenharmony_ci 0x2F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xF0, 0x00, -1 5551141cc406Sopenharmony_ci }; 5552141cc406Sopenharmony_ci int op01[17] = 5553141cc406Sopenharmony_ci { 0x01, 0x00, 0x32, 0x70, 0x00, 0x00, 0xC0, 0x2F, 0x17, 0x05, 0x00, 0x00, 5554141cc406Sopenharmony_ci 0x00, 0x80, 0xA4, 0x00, -1 5555141cc406Sopenharmony_ci }; 5556141cc406Sopenharmony_ci int op11[17] = 5557141cc406Sopenharmony_ci { 0x01, 0x80, 0x0C, 0x70, 0x00, 0x00, 0xC0, 0x2F, 0x17, 0x01, 0x00, 0x00, 5558141cc406Sopenharmony_ci 0x00, 0x80, 0xA4, 0x00, -1 5559141cc406Sopenharmony_ci }; 5560141cc406Sopenharmony_ci int op21[17] = 5561141cc406Sopenharmony_ci { 0x01, 0x00, 0x01, 0x40, 0x30, 0x00, 0xC0, 0x2F, 0x17, 0x05, 0x00, 0x00, 5562141cc406Sopenharmony_ci 0x00, 0x80, 0xF4, 0x00, -1 5563141cc406Sopenharmony_ci }; 5564141cc406Sopenharmony_ci int op31[17] = 5565141cc406Sopenharmony_ci { 0x01, 0x00, 0x39, 0x73, 0x00, 0x00, 0xC0, 0x2F, 0x17, 0x05, 0x00, 0x00, 5566141cc406Sopenharmony_ci 0x00, 0x80, 0xB4, 0x00, -1 5567141cc406Sopenharmony_ci }; 5568141cc406Sopenharmony_ci 5569141cc406Sopenharmony_ci int op02[35] = { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 5570141cc406Sopenharmony_ci 0x00, 0x04, 0x40, 0x01, 0x00, 0x20, 0x02, 0x00, 5571141cc406Sopenharmony_ci 0x76, 0x00, 0x75, 0xEF, 0x06, 0x00, 0x00, 0xF6, 5572141cc406Sopenharmony_ci 0x4D, 0xA0, 0x00, 0x8B, 0x4D, 0x4B, 0xD0, 0x68, 5573141cc406Sopenharmony_ci 0xDF, 0x1B, -1 5574141cc406Sopenharmony_ci }; 5575141cc406Sopenharmony_ci int op22[35] = { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 5576141cc406Sopenharmony_ci 0x00, 0x03, 0xC1, 0x80, 0x00, 0x20, 0x02, 0x00, 5577141cc406Sopenharmony_ci 0x16, 0x80, 0x15, 0x78, 0x03, 0x03, 0x00, 0x00, 5578141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x4D, 0x4B, 0xD0, 0x68, 5579141cc406Sopenharmony_ci 0xDF, 0x1B, -1 5580141cc406Sopenharmony_ci }; 5581141cc406Sopenharmony_ci 5582141cc406Sopenharmony_ci int op03[9] = { 0x00, 0x00, 0x00, 0xAA, 0xCC, 0xEE, 0xFF, 0xFF, -1 }; 5583141cc406Sopenharmony_ci struct timeval tv; 5584141cc406Sopenharmony_ci 5585141cc406Sopenharmony_ci byteMode (); /* just to get sure */ 5586141cc406Sopenharmony_ci first = 0; 5587141cc406Sopenharmony_ci rc = inquire (); 5588141cc406Sopenharmony_ci 5589141cc406Sopenharmony_ci /* get time to handle settle time delay */ 5590141cc406Sopenharmony_ci gettimeofday (&tv, NULL); 5591141cc406Sopenharmony_ci gTime = tv.tv_sec; 5592141cc406Sopenharmony_ci /* default delay */ 5593141cc406Sopenharmony_ci gDelay = 5; 5594141cc406Sopenharmony_ci 5595141cc406Sopenharmony_ci if (rc == 0) 5596141cc406Sopenharmony_ci { 5597141cc406Sopenharmony_ci DBG (0, "inquire() failed ! (%s:%d) \n", __FILE__, __LINE__); 5598141cc406Sopenharmony_ci return 0; 5599141cc406Sopenharmony_ci } 5600141cc406Sopenharmony_ci if (rc == 2) 5601141cc406Sopenharmony_ci { 5602141cc406Sopenharmony_ci /* same value used by windows driver */ 5603141cc406Sopenharmony_ci gDelay = 45; 5604141cc406Sopenharmony_ci DBG (1, "inquire() signals re-homing needed ... (%s:%d) \n", 5605141cc406Sopenharmony_ci __FILE__, __LINE__); 5606141cc406Sopenharmony_ci first = 1; 5607141cc406Sopenharmony_ci } 5608141cc406Sopenharmony_ci DBG (1, "inquire() passed ... (%s:%d) \n", __FILE__, __LINE__); 5609141cc406Sopenharmony_ci 5610141cc406Sopenharmony_ci rc = loadDefaultTables (); 5611141cc406Sopenharmony_ci if (rc == 0) 5612141cc406Sopenharmony_ci { 5613141cc406Sopenharmony_ci DBG (0, "loadDefaultTables() failed ! (%s:%d) \n", __FILE__, __LINE__); 5614141cc406Sopenharmony_ci return 0; 5615141cc406Sopenharmony_ci } 5616141cc406Sopenharmony_ci DBG (1, "loadDefaultTables() passed ... (%s:%d) \n", __FILE__, __LINE__); 5617141cc406Sopenharmony_ci if (recover) 5618141cc406Sopenharmony_ci first = 1; 5619141cc406Sopenharmony_ci 5620141cc406Sopenharmony_ci CMDSETGET (2, 0x10, cmd02); 5621141cc406Sopenharmony_ci CMDSETGET (1, 0x08, cmd55AA); 5622141cc406Sopenharmony_ci 5623141cc406Sopenharmony_ci if (!first) 5624141cc406Sopenharmony_ci { 5625141cc406Sopenharmony_ci CMDSYNC (0x00); 5626141cc406Sopenharmony_ci CMDSYNC (0xC2); 5627141cc406Sopenharmony_ci CMDSYNC (0x00); 5628141cc406Sopenharmony_ci DBG (1, "initScanner610p done ...\n"); 5629141cc406Sopenharmony_ci return 1; 5630141cc406Sopenharmony_ci } 5631141cc406Sopenharmony_ci 5632141cc406Sopenharmony_ci /* here we do re-homing 5633141cc406Sopenharmony_ci * since it is first probe or recover */ 5634141cc406Sopenharmony_ci /* move forward */ 5635141cc406Sopenharmony_ci CMDSYNC (0xC2); 5636141cc406Sopenharmony_ci if (!recover) 5637141cc406Sopenharmony_ci { 5638141cc406Sopenharmony_ci CMDSETGET (2, 0x10, op01); 5639141cc406Sopenharmony_ci CMDSETGET (8, 0x22, op02); 5640141cc406Sopenharmony_ci CMDSYNC (0xC2); 5641141cc406Sopenharmony_ci CMDSYNC (0x00); 5642141cc406Sopenharmony_ci CMDSETGET (4, 0x08, op03); 5643141cc406Sopenharmony_ci CMDSYNC (0x40); 5644141cc406Sopenharmony_ci CMDSYNC (0xC2); 5645141cc406Sopenharmony_ci sleep (2); 5646141cc406Sopenharmony_ci } 5647141cc406Sopenharmony_ci 5648141cc406Sopenharmony_ci /* move backward */ 5649141cc406Sopenharmony_ci CMDSETGET (2, 0x10, op11); 5650141cc406Sopenharmony_ci CMDSETGET (8, 0x22, op02); 5651141cc406Sopenharmony_ci CMDSYNC (0xC2); 5652141cc406Sopenharmony_ci CMDSYNC (0x00); 5653141cc406Sopenharmony_ci CMDSYNC (0x00); 5654141cc406Sopenharmony_ci CMDSETGET (4, 0x08, op03); 5655141cc406Sopenharmony_ci CMDSYNC (0x40); 5656141cc406Sopenharmony_ci CMDSYNC (0xC2); 5657141cc406Sopenharmony_ci sleep (2); 5658141cc406Sopenharmony_ci 5659141cc406Sopenharmony_ci /* means 'CONTINUE MOVE' */ 5660141cc406Sopenharmony_ci CMDSYNC (0x00); 5661141cc406Sopenharmony_ci while ((scannerStatus & MOTOR_BIT) == 0) 5662141cc406Sopenharmony_ci { 5663141cc406Sopenharmony_ci CMDSYNC (0xC2); 5664141cc406Sopenharmony_ci CMDSETGET (2, 0x10, op21); 5665141cc406Sopenharmony_ci CMDSETGET (8, 0x22, op22); 5666141cc406Sopenharmony_ci CMDSYNC (0x40); 5667141cc406Sopenharmony_ci usleep (20000); 5668141cc406Sopenharmony_ci } 5669141cc406Sopenharmony_ci CMDSYNC (0xC2); 5670141cc406Sopenharmony_ci CMDSYNC (0x00); 5671141cc406Sopenharmony_ci 5672141cc406Sopenharmony_ci /* send head away */ 5673141cc406Sopenharmony_ci if (!recover) 5674141cc406Sopenharmony_ci { 5675141cc406Sopenharmony_ci CMDSETGET (2, 0x10, op31); 5676141cc406Sopenharmony_ci CMDSETGET (8, 0x22, op02); 5677141cc406Sopenharmony_ci if (DBG_LEVEL > 8) 5678141cc406Sopenharmony_ci { 5679141cc406Sopenharmony_ci bloc2Decode (op31); 5680141cc406Sopenharmony_ci bloc8Decode (op02); 5681141cc406Sopenharmony_ci } 5682141cc406Sopenharmony_ci CMDSYNC (0xC2); 5683141cc406Sopenharmony_ci CMDSYNC (0x00); 5684141cc406Sopenharmony_ci CMDSETGET (4, 0x08, op03); 5685141cc406Sopenharmony_ci CMDSYNC (0x40); 5686141cc406Sopenharmony_ci CMDSYNC (0xC2); 5687141cc406Sopenharmony_ci sleep (9); 5688141cc406Sopenharmony_ci } 5689141cc406Sopenharmony_ci 5690141cc406Sopenharmony_ci CMDSYNC (0x00); 5691141cc406Sopenharmony_ci 5692141cc406Sopenharmony_ci /* this code has been added, without corresponding logs/ 5693141cc406Sopenharmony_ci * it seem I just can't found 'real' parking command ... 5694141cc406Sopenharmony_ci */ 5695141cc406Sopenharmony_ci /* send park command */ 5696141cc406Sopenharmony_ci if (sanei_umax_pp_park () == 0) 5697141cc406Sopenharmony_ci { 5698141cc406Sopenharmony_ci TRACE (0, "sanei_umax_pp_park failed! "); 5699141cc406Sopenharmony_ci return 0; 5700141cc406Sopenharmony_ci } 5701141cc406Sopenharmony_ci /* and wait it to succeed */ 5702141cc406Sopenharmony_ci if (sanei_umax_pp_parkWait () == 0) 5703141cc406Sopenharmony_ci { 5704141cc406Sopenharmony_ci TRACE (0, "sanei_umax_pp_parkWait failed! "); 5705141cc406Sopenharmony_ci return 0; 5706141cc406Sopenharmony_ci } 5707141cc406Sopenharmony_ci 5708141cc406Sopenharmony_ci /* override gamma table with 610P defaults */ 5709141cc406Sopenharmony_ci for (x = 0; x < 256; x++) 5710141cc406Sopenharmony_ci { 5711141cc406Sopenharmony_ci ggRed[x] = x; 5712141cc406Sopenharmony_ci ggGreen[x] = x; 5713141cc406Sopenharmony_ci ggBlue[x] = x; 5714141cc406Sopenharmony_ci } 5715141cc406Sopenharmony_ci 5716141cc406Sopenharmony_ci DBG (1, "initScanner610p done ...\n"); 5717141cc406Sopenharmony_ci return 1; 5718141cc406Sopenharmony_ci} 5719141cc406Sopenharmony_ci 5720141cc406Sopenharmony_ci/* 1: OK 5721141cc406Sopenharmony_ci 2: homing happened 5722141cc406Sopenharmony_ci 3: scanner busy 5723141cc406Sopenharmony_ci 0: init failed 5724141cc406Sopenharmony_ci 5725141cc406Sopenharmony_ci init transport layer 5726141cc406Sopenharmony_ci init scanner 5727141cc406Sopenharmony_ci*/ 5728141cc406Sopenharmony_ci 5729141cc406Sopenharmony_ciint 5730141cc406Sopenharmony_cisanei_umax_pp_initScanner (int recover) 5731141cc406Sopenharmony_ci{ 5732141cc406Sopenharmony_ci int i; 5733141cc406Sopenharmony_ci int status; 5734141cc406Sopenharmony_ci int readcmd[64]; 5735141cc406Sopenharmony_ci /* in umax1220u, this buffer is opc[16] */ 5736141cc406Sopenharmony_ci int sentcmd[17] = 5737141cc406Sopenharmony_ci { 0x02, 0x80, 0x00, 0x70, 0x00, 0x00, 0x00, 0x2F, 0x2F, 0x07, 0x00, 5738141cc406Sopenharmony_ci 0x00, 0x00, 0x80, 0xF0, 0x00, -1 5739141cc406Sopenharmony_ci }; 5740141cc406Sopenharmony_ci int cmdA7[9] = { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, -1 }; 5741141cc406Sopenharmony_ci 5742141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 5743141cc406Sopenharmony_ci return initScanner610p (recover); 5744141cc406Sopenharmony_ci 5745141cc406Sopenharmony_ci if (getModel () == 0x07) 5746141cc406Sopenharmony_ci sentcmd[15] = 0x00; 5747141cc406Sopenharmony_ci else 5748141cc406Sopenharmony_ci sentcmd[15] = 0x18; 5749141cc406Sopenharmony_ci 5750141cc406Sopenharmony_ci /* fails here if there is an unfinished previous scan */ 5751141cc406Sopenharmony_ci CMDSETGET (0x02, 16, sentcmd); 5752141cc406Sopenharmony_ci 5753141cc406Sopenharmony_ci /* needs some init */ 5754141cc406Sopenharmony_ci if (sentcmd[15] == 0x18) 5755141cc406Sopenharmony_ci { 5756141cc406Sopenharmony_ci sentcmd[15] = 0x00; /* was 0x18 */ 5757141cc406Sopenharmony_ci CMDSETGET (0x02, 16, sentcmd); 5758141cc406Sopenharmony_ci 5759141cc406Sopenharmony_ci /* in umax1220u, this buffer does not exist */ 5760141cc406Sopenharmony_ci CMDSETGET (0x01, 8, cmdA7); 5761141cc406Sopenharmony_ci } 5762141cc406Sopenharmony_ci 5763141cc406Sopenharmony_ci 5764141cc406Sopenharmony_ci /* ~ opb3: inquire status */ 5765141cc406Sopenharmony_ci CMDGET (0x08, 36, readcmd); 5766141cc406Sopenharmony_ci if (DBG_LEVEL >= 32) 5767141cc406Sopenharmony_ci { 5768141cc406Sopenharmony_ci bloc8Decode (readcmd); 5769141cc406Sopenharmony_ci } 5770141cc406Sopenharmony_ci DBG (16, "cmdGet(0x08,36,readcmd) passed (%s:%d)\n", __FILE__, __LINE__); 5771141cc406Sopenharmony_ci 5772141cc406Sopenharmony_ci /* is the scanner busy parking ? */ 5773141cc406Sopenharmony_ci status = sanei_umax_pp_scannerStatus (); 5774141cc406Sopenharmony_ci DBG (8, "INQUIRE SCANNER STATUS IS 0x%02X (%s:%d)\n", status, __FILE__, 5775141cc406Sopenharmony_ci __LINE__); 5776141cc406Sopenharmony_ci if ((!recover) && (status & MOTOR_BIT) == 0x00) 5777141cc406Sopenharmony_ci { 5778141cc406Sopenharmony_ci DBG (1, "Warning: scanner motor on, giving up ... (%s:%d)\n", __FILE__, 5779141cc406Sopenharmony_ci __LINE__); 5780141cc406Sopenharmony_ci return 3; 5781141cc406Sopenharmony_ci } 5782141cc406Sopenharmony_ci 5783141cc406Sopenharmony_ci /* head homing needed ? */ 5784141cc406Sopenharmony_ci if ((readcmd[34] != 0x1A) || (recover == 1)) 5785141cc406Sopenharmony_ci { /* homing needed, readcmd[34] should be 0x48 */ 5786141cc406Sopenharmony_ci int op01[17] = 5787141cc406Sopenharmony_ci { 0x01, 0x00, 0x32, 0x70, 0x00, 0x00, 0x60, 0x2F, 0x17, 0x05, 0x00, 5788141cc406Sopenharmony_ci 0x00, 0x00, 0x80, 0xE4, 0x00, -1 5789141cc406Sopenharmony_ci }; 5790141cc406Sopenharmony_ci int op05[17] = 5791141cc406Sopenharmony_ci { 0x01, 0x00, 0x01, 0x70, 0x00, 0x00, 0x60, 0x2F, 0x13, 0x05, 0x00, 5792141cc406Sopenharmony_ci 0x00, 0x00, 0x80, 0xF0, 0x00, -1 5793141cc406Sopenharmony_ci }; 5794141cc406Sopenharmony_ci int op02[37] = 5795141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x40, 5796141cc406Sopenharmony_ci 0x01, 0x00, 0x20, 0x02, 0x00, 0x16, 0x00, 0x70, 0x9F, 0x06, 0x00, 5797141cc406Sopenharmony_ci 0x00, 0xF6, 0x4D, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 5798141cc406Sopenharmony_ci 0x0B, 0x1A, 0x00, -1 5799141cc406Sopenharmony_ci }; 5800141cc406Sopenharmony_ci int op04[37] = 5801141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x03, 0xC1, 5802141cc406Sopenharmony_ci 0x80, 0x00, 0x20, 0x02, 0x00, 0x16, 0x80, 0x15, 0x78, 0x03, 0x03, 5803141cc406Sopenharmony_ci 0x00, 0x00, 0x46, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 5804141cc406Sopenharmony_ci 0x0B, 0x1A, 0x00, -1 5805141cc406Sopenharmony_ci }; 5806141cc406Sopenharmony_ci int op03[9] = { 0x00, 0x00, 0x00, 0xAA, 0xCC, 0xEE, 0xFF, 0xFF, -1 }; 5807141cc406Sopenharmony_ci 5808141cc406Sopenharmony_ci CMDSYNC (0xC2); 5809141cc406Sopenharmony_ci CMDSETGET (0x02, 16, op01); 5810141cc406Sopenharmony_ci CMDSETGET (0x08, 36, op02); 5811141cc406Sopenharmony_ci 5812141cc406Sopenharmony_ci if (!recover) 5813141cc406Sopenharmony_ci { 5814141cc406Sopenharmony_ci CMDSYNC (0xC2); 5815141cc406Sopenharmony_ci CMDSYNC (0x00); 5816141cc406Sopenharmony_ci CMDSETGET (0x04, 8, op03); 5817141cc406Sopenharmony_ci CMDSYNC (0x40); 5818141cc406Sopenharmony_ci do 5819141cc406Sopenharmony_ci { 5820141cc406Sopenharmony_ci sleep (1); 5821141cc406Sopenharmony_ci CMDSYNC (0xC2); 5822141cc406Sopenharmony_ci } 5823141cc406Sopenharmony_ci while ((sanei_umax_pp_scannerStatus () & 0x90) != 0x90); 5824141cc406Sopenharmony_ci 5825141cc406Sopenharmony_ci op01[2] = 0x1E; 5826141cc406Sopenharmony_ci op01[9] = 0x01; 5827141cc406Sopenharmony_ci CMDSETGET (0x02, 16, op01); 5828141cc406Sopenharmony_ci CMDSETGET (0x08, 36, op02); 5829141cc406Sopenharmony_ci CMDSYNC (0x00); 5830141cc406Sopenharmony_ci CMDSYNC (0x00); 5831141cc406Sopenharmony_ci CMDSETGET (0x04, 8, op03); 5832141cc406Sopenharmony_ci 5833141cc406Sopenharmony_ci CMDSYNC (0x40); 5834141cc406Sopenharmony_ci do 5835141cc406Sopenharmony_ci { 5836141cc406Sopenharmony_ci sleep (1); 5837141cc406Sopenharmony_ci CMDSYNC (0xC2); 5838141cc406Sopenharmony_ci } 5839141cc406Sopenharmony_ci while ((sanei_umax_pp_scannerStatus () & 0x90) != 0x90); 5840141cc406Sopenharmony_ci CMDSYNC (0x00); 5841141cc406Sopenharmony_ci } 5842141cc406Sopenharmony_ci 5843141cc406Sopenharmony_ci for (i = 0; i < 4; i++) 5844141cc406Sopenharmony_ci { 5845141cc406Sopenharmony_ci 5846141cc406Sopenharmony_ci do 5847141cc406Sopenharmony_ci { 5848141cc406Sopenharmony_ci usleep (500000); 5849141cc406Sopenharmony_ci CMDSYNC (0xC2); 5850141cc406Sopenharmony_ci status = sanei_umax_pp_scannerStatus (); 5851141cc406Sopenharmony_ci status = status & 0x10; 5852141cc406Sopenharmony_ci } 5853141cc406Sopenharmony_ci while (status != 0x10); /* was 0x90 */ 5854141cc406Sopenharmony_ci CMDSETGET (0x02, 16, op05); 5855141cc406Sopenharmony_ci CMDSETGET (0x08, 36, op04); 5856141cc406Sopenharmony_ci CMDSYNC (0x40); 5857141cc406Sopenharmony_ci status = sanei_umax_pp_scannerStatus (); 5858141cc406Sopenharmony_ci DBG (16, "loop %d passed, status=0x%02X (%s:%d)\n", i, status, 5859141cc406Sopenharmony_ci __FILE__, __LINE__); 5860141cc406Sopenharmony_ci } 5861141cc406Sopenharmony_ci 5862141cc406Sopenharmony_ci 5863141cc406Sopenharmony_ci 5864141cc406Sopenharmony_ci /* get head back home ... */ 5865141cc406Sopenharmony_ci do 5866141cc406Sopenharmony_ci { 5867141cc406Sopenharmony_ci i++; 5868141cc406Sopenharmony_ci do 5869141cc406Sopenharmony_ci { 5870141cc406Sopenharmony_ci usleep (500000); 5871141cc406Sopenharmony_ci CMDSYNC (0xC2); 5872141cc406Sopenharmony_ci status = sanei_umax_pp_scannerStatus (); 5873141cc406Sopenharmony_ci status = status & 0x10; 5874141cc406Sopenharmony_ci } 5875141cc406Sopenharmony_ci while (status != 0x10); /* was 0x90 */ 5876141cc406Sopenharmony_ci CMDSETGET (0x02, 16, op05); 5877141cc406Sopenharmony_ci CMDSETGET (0x08, 36, op04); 5878141cc406Sopenharmony_ci CMDSYNC (0x40); 5879141cc406Sopenharmony_ci status = sanei_umax_pp_scannerStatus (); 5880141cc406Sopenharmony_ci DBG (16, "loop %d passed, status=0x%02X (%s:%d)\n", i, status, 5881141cc406Sopenharmony_ci __FILE__, __LINE__); 5882141cc406Sopenharmony_ci } 5883141cc406Sopenharmony_ci while ((status & MOTOR_BIT) == 0x00); /* 0xD0 when head is back home */ 5884141cc406Sopenharmony_ci 5885141cc406Sopenharmony_ci do 5886141cc406Sopenharmony_ci { 5887141cc406Sopenharmony_ci usleep (500000); 5888141cc406Sopenharmony_ci CMDSYNC (0xC2); 5889141cc406Sopenharmony_ci } 5890141cc406Sopenharmony_ci while ((sanei_umax_pp_scannerStatus () & 0x90) != 0x90); 5891141cc406Sopenharmony_ci 5892141cc406Sopenharmony_ci 5893141cc406Sopenharmony_ci /* don't do automatic home sequence on recovery */ 5894141cc406Sopenharmony_ci if (!recover) 5895141cc406Sopenharmony_ci { 5896141cc406Sopenharmony_ci CMDSYNC (0x00); 5897141cc406Sopenharmony_ci op01[2] = 0x1A; 5898141cc406Sopenharmony_ci op01[3] = 0x74; /* was 0x70 */ 5899141cc406Sopenharmony_ci op01[9] = 0x05; /* initial value */ 5900141cc406Sopenharmony_ci op01[14] = 0xF4; /* was 0xE4 */ 5901141cc406Sopenharmony_ci CMDSETGET (0x02, 16, op01); 5902141cc406Sopenharmony_ci CMDSETGET (0x08, 36, op02); 5903141cc406Sopenharmony_ci CMDSYNC (0xC2); 5904141cc406Sopenharmony_ci CMDSYNC (0x00); 5905141cc406Sopenharmony_ci CMDSETGET (0x04, 8, op03); 5906141cc406Sopenharmony_ci CMDSYNC (0x40); 5907141cc406Sopenharmony_ci 5908141cc406Sopenharmony_ci /* wait for automatic homing sequence */ 5909141cc406Sopenharmony_ci /* to complete, thus avoiding */ 5910141cc406Sopenharmony_ci /* scanning too early */ 5911141cc406Sopenharmony_ci do 5912141cc406Sopenharmony_ci { 5913141cc406Sopenharmony_ci /* the sleep is here to prevent */ 5914141cc406Sopenharmony_ci /* excessive CPU usage, can be */ 5915141cc406Sopenharmony_ci /* removed, if we don't care */ 5916141cc406Sopenharmony_ci sleep (3); 5917141cc406Sopenharmony_ci CMDSYNC (0xC2); 5918141cc406Sopenharmony_ci DBG (16, "PARKING polling status is 0x%02X (%s:%d)\n", 5919141cc406Sopenharmony_ci sanei_umax_pp_scannerStatus (), __FILE__, __LINE__); 5920141cc406Sopenharmony_ci } 5921141cc406Sopenharmony_ci while (sanei_umax_pp_scannerStatus () == 0x90); 5922141cc406Sopenharmony_ci } 5923141cc406Sopenharmony_ci 5924141cc406Sopenharmony_ci /* signal homing */ 5925141cc406Sopenharmony_ci return 2; 5926141cc406Sopenharmony_ci } 5927141cc406Sopenharmony_ci 5928141cc406Sopenharmony_ci 5929141cc406Sopenharmony_ci /* end ... */ 5930141cc406Sopenharmony_ci DBG (1, "Scanner init done ...\n"); 5931141cc406Sopenharmony_ci return 1; 5932141cc406Sopenharmony_ci} 5933141cc406Sopenharmony_ci 5934141cc406Sopenharmony_ci 5935141cc406Sopenharmony_ci/* 5936141cc406Sopenharmony_ci 1: OK 5937141cc406Sopenharmony_ci 2: failed, try again 5938141cc406Sopenharmony_ci 0: init failed 5939141cc406Sopenharmony_ci 5940141cc406Sopenharmony_ci initialize the transport layer 5941141cc406Sopenharmony_ci 5942141cc406Sopenharmony_ci */ 5943141cc406Sopenharmony_ci 5944141cc406Sopenharmony_cistatic int 5945141cc406Sopenharmony_ciinitTransport610p (void) 5946141cc406Sopenharmony_ci{ 5947141cc406Sopenharmony_ci int tmp, i; 5948141cc406Sopenharmony_ci int zero[5] = { 0, 0, 0, 0, -1 }; 5949141cc406Sopenharmony_ci 5950141cc406Sopenharmony_ci /* test EPP availability */ 5951141cc406Sopenharmony_ci connect610p (); 5952141cc406Sopenharmony_ci if (sync610p () == 0) 5953141cc406Sopenharmony_ci { 5954141cc406Sopenharmony_ci DBG (0, 5955141cc406Sopenharmony_ci "sync610p failed! Scanner not present or powered off ... (%s:%d)\n", 5956141cc406Sopenharmony_ci __FILE__, __LINE__); 5957141cc406Sopenharmony_ci return 0; 5958141cc406Sopenharmony_ci } 5959141cc406Sopenharmony_ci if (EPPsendWord610p (zero) == 0) 5960141cc406Sopenharmony_ci { 5961141cc406Sopenharmony_ci DBG (1, "No EPP mode detected\n"); 5962141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_BYTE; 5963141cc406Sopenharmony_ci } 5964141cc406Sopenharmony_ci else 5965141cc406Sopenharmony_ci { 5966141cc406Sopenharmony_ci DBG (1, "EPP mode detected\n"); 5967141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_EPP; 5968141cc406Sopenharmony_ci } 5969141cc406Sopenharmony_ci disconnect610p (); 5970141cc406Sopenharmony_ci 5971141cc406Sopenharmony_ci /* set up to bidirectionnal */ 5972141cc406Sopenharmony_ci /* in fact we could add support for EPP */ 5973141cc406Sopenharmony_ci /* but let's make 610 work first */ 5974141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_BYTE) 5975141cc406Sopenharmony_ci { 5976141cc406Sopenharmony_ci byteMode (); 5977141cc406Sopenharmony_ci 5978141cc406Sopenharmony_ci /* reset after failure */ 5979141cc406Sopenharmony_ci /* set to data reverse */ 5980141cc406Sopenharmony_ci Outb (CONTROL, 0x2C); 5981141cc406Sopenharmony_ci Inb (CONTROL); 5982141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 5983141cc406Sopenharmony_ci Outb (DATA, 0xAA); 5984141cc406Sopenharmony_ci tmp = Inb (DATA); 5985141cc406Sopenharmony_ci tmp = Inb (DATA); 5986141cc406Sopenharmony_ci if (tmp != 0xFF) 5987141cc406Sopenharmony_ci { 5988141cc406Sopenharmony_ci DBG (1, "Found 0x%X expected 0xFF (%s:%d)\n", tmp, __FILE__, 5989141cc406Sopenharmony_ci __LINE__); 5990141cc406Sopenharmony_ci } 5991141cc406Sopenharmony_ci for (i = 0; i < 4; i++) 5992141cc406Sopenharmony_ci { 5993141cc406Sopenharmony_ci Outb (DATA, 0x00); 5994141cc406Sopenharmony_ci tmp = Inb (DATA); 5995141cc406Sopenharmony_ci if (tmp != 0xFF) 5996141cc406Sopenharmony_ci { 5997141cc406Sopenharmony_ci DBG (1, "Found 0x%X expected 0xFF (%s:%d)\n", tmp, __FILE__, 5998141cc406Sopenharmony_ci __LINE__); 5999141cc406Sopenharmony_ci return 0; 6000141cc406Sopenharmony_ci } 6001141cc406Sopenharmony_ci Outb (DATA, 0xFF); 6002141cc406Sopenharmony_ci tmp = Inb (DATA); 6003141cc406Sopenharmony_ci if (tmp != 0xFF) 6004141cc406Sopenharmony_ci { 6005141cc406Sopenharmony_ci DBG (1, "Found 0x%X expected 0xFF (%s:%d)\n", tmp, __FILE__, 6006141cc406Sopenharmony_ci __LINE__); 6007141cc406Sopenharmony_ci return 0; 6008141cc406Sopenharmony_ci } 6009141cc406Sopenharmony_ci } 6010141cc406Sopenharmony_ci TRACE (16, "RESET done... "); 6011141cc406Sopenharmony_ci byteMode (); 6012141cc406Sopenharmony_ci 6013141cc406Sopenharmony_ci if (SPPsendWord610p (zero) == 0) 6014141cc406Sopenharmony_ci { 6015141cc406Sopenharmony_ci DBG (0, "SPPsendWord610p(zero) failed! (%s:%d)\n", __FILE__, 6016141cc406Sopenharmony_ci __LINE__); 6017141cc406Sopenharmony_ci return 0; 6018141cc406Sopenharmony_ci } 6019141cc406Sopenharmony_ci TRACE (16, "SPPsendWord610p(zero) passed... "); 6020141cc406Sopenharmony_ci } 6021141cc406Sopenharmony_ci 6022141cc406Sopenharmony_ci /* OK ! */ 6023141cc406Sopenharmony_ci TRACE (1, "initTransport610p done... "); 6024141cc406Sopenharmony_ci return 1; 6025141cc406Sopenharmony_ci} 6026141cc406Sopenharmony_ci 6027141cc406Sopenharmony_ci/* 6028141cc406Sopenharmony_ci 1: OK 6029141cc406Sopenharmony_ci 2: failed, try again 6030141cc406Sopenharmony_ci 0: init failed 6031141cc406Sopenharmony_ci 6032141cc406Sopenharmony_ci initialize the transport layer 6033141cc406Sopenharmony_ci 6034141cc406Sopenharmony_ci */ 6035141cc406Sopenharmony_ci 6036141cc406Sopenharmony_cistatic int 6037141cc406Sopenharmony_ciinitTransport1220P (int recover) /* ECP OK !! */ 6038141cc406Sopenharmony_ci{ 6039141cc406Sopenharmony_ci int i, j; 6040141cc406Sopenharmony_ci int reg, tmp; 6041141cc406Sopenharmony_ci unsigned char *dest = NULL; 6042141cc406Sopenharmony_ci int zero[5] = { 0, 0, 0, 0, -1 }; 6043141cc406Sopenharmony_ci int model, nb; 6044141cc406Sopenharmony_ci 6045141cc406Sopenharmony_ci connect (); 6046141cc406Sopenharmony_ci DBG (16, "connect() passed... (%s:%d)\n", __FILE__, __LINE__); 6047141cc406Sopenharmony_ci gEPAT = 0xC7; 6048141cc406Sopenharmony_ci reg = registerRead (0x0B); 6049141cc406Sopenharmony_ci if (reg != gEPAT) 6050141cc406Sopenharmony_ci { 6051141cc406Sopenharmony_ci DBG (16, "Error! expected reg0B=0x%02X, found 0x%02X! (%s:%d) \n", 6052141cc406Sopenharmony_ci gEPAT, reg, __FILE__, __LINE__); 6053141cc406Sopenharmony_ci DBG (16, "Scanner needs probing ... \n"); 6054141cc406Sopenharmony_ci if (sanei_umax_pp_probeScanner (recover) != 1) 6055141cc406Sopenharmony_ci { 6056141cc406Sopenharmony_ci return 0; 6057141cc406Sopenharmony_ci } 6058141cc406Sopenharmony_ci else 6059141cc406Sopenharmony_ci { 6060141cc406Sopenharmony_ci return 2; /* signals retry initTransport() */ 6061141cc406Sopenharmony_ci } 6062141cc406Sopenharmony_ci } 6063141cc406Sopenharmony_ci 6064141cc406Sopenharmony_ci reg = registerRead (0x0D); 6065141cc406Sopenharmony_ci reg = (reg & 0xE8) | 0x43; 6066141cc406Sopenharmony_ci registerWrite (0x0D, reg); 6067141cc406Sopenharmony_ci REGISTERWRITE (0x0C, 0x04); 6068141cc406Sopenharmony_ci reg = registerRead (0x0A); 6069141cc406Sopenharmony_ci if (reg != 0x00) 6070141cc406Sopenharmony_ci { 6071141cc406Sopenharmony_ci if (reg != 0x1C) 6072141cc406Sopenharmony_ci { 6073141cc406Sopenharmony_ci DBG (0, "Warning! expected reg0A=0x00, found 0x%02X! (%s:%d) \n", 6074141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 6075141cc406Sopenharmony_ci } 6076141cc406Sopenharmony_ci else 6077141cc406Sopenharmony_ci { 6078141cc406Sopenharmony_ci DBG (16, "Scanner in idle state .... (%s:%d)\n", __FILE__, 6079141cc406Sopenharmony_ci __LINE__); 6080141cc406Sopenharmony_ci } 6081141cc406Sopenharmony_ci } 6082141cc406Sopenharmony_ci 6083141cc406Sopenharmony_ci /* model detection: redone since we might not be probing each time ... */ 6084141cc406Sopenharmony_ci /* write addr in 0x0E, read value at 0x0F */ 6085141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x01); 6086141cc406Sopenharmony_ci model = registerRead (0x0F); 6087141cc406Sopenharmony_ci setModel (model); 6088141cc406Sopenharmony_ci 6089141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x1C); 6090141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 6091141cc406Sopenharmony_ci { 6092141cc406Sopenharmony_ci REGISTERWRITE (0x08, 0x10); 6093141cc406Sopenharmony_ci } 6094141cc406Sopenharmony_ci else 6095141cc406Sopenharmony_ci { 6096141cc406Sopenharmony_ci REGISTERWRITE (0x08, 0x21); 6097141cc406Sopenharmony_ci } 6098141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0F); 6099141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x0C); 6100141cc406Sopenharmony_ci 6101141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x1C); 6102141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x10); 6103141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x1C); 6104141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 6105141cc406Sopenharmony_ci { 6106141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 6107141cc406Sopenharmony_ci } 6108141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x11); 6109141cc406Sopenharmony_ci 6110141cc406Sopenharmony_ci dest = (unsigned char *) (malloc (65536)); 6111141cc406Sopenharmony_ci if (dest == NULL) 6112141cc406Sopenharmony_ci { 6113141cc406Sopenharmony_ci DBG (0, "Failed to allocate 64 Ko !\n"); 6114141cc406Sopenharmony_ci return 0; 6115141cc406Sopenharmony_ci } 6116141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 6117141cc406Sopenharmony_ci { 6118141cc406Sopenharmony_ci dest[i * 2] = i; 6119141cc406Sopenharmony_ci dest[i * 2 + 1] = 0xFF - i; 6120141cc406Sopenharmony_ci dest[512 + i * 2] = i; 6121141cc406Sopenharmony_ci dest[512 + i * 2 + 1] = 0xFF - i; 6122141cc406Sopenharmony_ci } 6123141cc406Sopenharmony_ci nb = 150; 6124141cc406Sopenharmony_ci for (i = 0; i < nb; i++) 6125141cc406Sopenharmony_ci { 6126141cc406Sopenharmony_ci bufferWrite (0x400, dest); 6127141cc406Sopenharmony_ci DBG (16, 6128141cc406Sopenharmony_ci "Loop %d: bufferWrite(0x400,dest) passed... (%s:%d)\n", i, 6129141cc406Sopenharmony_ci __FILE__, __LINE__); 6130141cc406Sopenharmony_ci } 6131141cc406Sopenharmony_ci 6132141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); 6133141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x11); 6134141cc406Sopenharmony_ci 6135141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 6136141cc406Sopenharmony_ci { 6137141cc406Sopenharmony_ci ECPSetBuffer (0x400); 6138141cc406Sopenharmony_ci } 6139141cc406Sopenharmony_ci for (i = 0; i < nb; i++) 6140141cc406Sopenharmony_ci { 6141141cc406Sopenharmony_ci /* XXX Compat/Byte ??? XXX */ 6142141cc406Sopenharmony_ci bufferRead (0x400, dest); 6143141cc406Sopenharmony_ci for (j = 0; j < 256; j++) 6144141cc406Sopenharmony_ci { 6145141cc406Sopenharmony_ci if (dest[j * 2] != j) 6146141cc406Sopenharmony_ci { 6147141cc406Sopenharmony_ci DBG (0, 6148141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6149141cc406Sopenharmony_ci j * 2, j, dest[j * 2]); 6150141cc406Sopenharmony_ci return 0; 6151141cc406Sopenharmony_ci } 6152141cc406Sopenharmony_ci if (dest[j * 2 + 1] != 0xFF - j) 6153141cc406Sopenharmony_ci { 6154141cc406Sopenharmony_ci DBG 6155141cc406Sopenharmony_ci (0, 6156141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6157141cc406Sopenharmony_ci j * 2 + 1, 0xFF - j, dest[j * 2 + 1]); 6158141cc406Sopenharmony_ci return 0; 6159141cc406Sopenharmony_ci } 6160141cc406Sopenharmony_ci if (dest[512 + j * 2] != j) 6161141cc406Sopenharmony_ci { 6162141cc406Sopenharmony_ci DBG (0, 6163141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6164141cc406Sopenharmony_ci 512 + j * 2, j, dest[512 + j * 2]); 6165141cc406Sopenharmony_ci return 0; 6166141cc406Sopenharmony_ci } 6167141cc406Sopenharmony_ci if (dest[512 + j * 2 + 1] != 0xFF - j) 6168141cc406Sopenharmony_ci { 6169141cc406Sopenharmony_ci DBG 6170141cc406Sopenharmony_ci (0, 6171141cc406Sopenharmony_ci "Altered buffer value at %03X, expected 0x%02X, found 0x%02X\n", 6172141cc406Sopenharmony_ci 512 + j * 2 + 1, 0xFF - j, dest[512 + j * 2 + 1]); 6173141cc406Sopenharmony_ci return 0; 6174141cc406Sopenharmony_ci } 6175141cc406Sopenharmony_ci } 6176141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferRead(0x400,dest) passed... (%s:%d)\n", 6177141cc406Sopenharmony_ci i, __FILE__, __LINE__); 6178141cc406Sopenharmony_ci } 6179141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); 6180141cc406Sopenharmony_ci /* ECP: "HEAVY" reconnect here */ 6181141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 6182141cc406Sopenharmony_ci { 6183141cc406Sopenharmony_ci epilogue (); 6184141cc406Sopenharmony_ci /* 3 line: set to initial parport state ? */ 6185141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); */ 6186141cc406Sopenharmony_ci Outb (DATA, 0x04); 6187141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 6188141cc406Sopenharmony_ci 6189141cc406Sopenharmony_ci /* the following is a variant of connect(); */ 6190141cc406Sopenharmony_ci Inb (ECR); 6191141cc406Sopenharmony_ci Inb (ECR); 6192141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); */ 6193141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); */ 6194141cc406Sopenharmony_ci Inb (CONTROL); 6195141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 6196141cc406Sopenharmony_ci Inb (DATA); 6197141cc406Sopenharmony_ci sendCommand (0xE0); 6198141cc406Sopenharmony_ci Outb (DATA, 0XFF); 6199141cc406Sopenharmony_ci Outb (DATA, 0XFF); 6200141cc406Sopenharmony_ci ClearRegister (0); 6201141cc406Sopenharmony_ci WRITESLOW (0x0E, 0x0A); 6202141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0F, 0x08); 6203141cc406Sopenharmony_ci /* resend value OR'ed 0x08 ? */ 6204141cc406Sopenharmony_ci WRITESLOW (0x0F, 0x08); 6205141cc406Sopenharmony_ci WRITESLOW (0x08, 0x10); 6206141cc406Sopenharmony_ci disconnect (); 6207141cc406Sopenharmony_ci prologue (0x10); 6208141cc406Sopenharmony_ci } 6209141cc406Sopenharmony_ci 6210141cc406Sopenharmony_ci if (fonc001 () != 1) 6211141cc406Sopenharmony_ci { 6212141cc406Sopenharmony_ci DBG (0, "fonc001() failed ! (%s:%d) \n", __FILE__, __LINE__); 6213141cc406Sopenharmony_ci return 0; 6214141cc406Sopenharmony_ci } 6215141cc406Sopenharmony_ci DBG (16, "fonc001() passed ... (%s:%d) \n", __FILE__, __LINE__); 6216141cc406Sopenharmony_ci 6217141cc406Sopenharmony_ci /* sync */ 6218141cc406Sopenharmony_ci if (sendWord (zero) == 0) 6219141cc406Sopenharmony_ci { 6220141cc406Sopenharmony_ci DBG (0, "sendWord(zero) failed (%s:%d)\n", __FILE__, __LINE__); 6221141cc406Sopenharmony_ci return 0; 6222141cc406Sopenharmony_ci } 6223141cc406Sopenharmony_ci DBG (16, "sendWord(zero) passed (%s:%d)\n", __FILE__, __LINE__); 6224141cc406Sopenharmony_ci epilogue (); 6225141cc406Sopenharmony_ci 6226141cc406Sopenharmony_ci /* OK ! */ 6227141cc406Sopenharmony_ci free (dest); 6228141cc406Sopenharmony_ci DBG (1, "initTransport1220P done ...\n"); 6229141cc406Sopenharmony_ci return 1; 6230141cc406Sopenharmony_ci} 6231141cc406Sopenharmony_ci 6232141cc406Sopenharmony_ci/* 6233141cc406Sopenharmony_ci 1: OK 6234141cc406Sopenharmony_ci 2: failed, try again 6235141cc406Sopenharmony_ci 0: init failed 6236141cc406Sopenharmony_ci 6237141cc406Sopenharmony_ci initialize the transport layer 6238141cc406Sopenharmony_ci 6239141cc406Sopenharmony_ci */ 6240141cc406Sopenharmony_ci 6241141cc406Sopenharmony_ciint 6242141cc406Sopenharmony_cisanei_umax_pp_initTransport (int recover) 6243141cc406Sopenharmony_ci{ 6244141cc406Sopenharmony_ci TRACE (16, "sanei_umax_pp_initTransport"); 6245141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 6246141cc406Sopenharmony_ci { 6247141cc406Sopenharmony_ci case 610: 6248141cc406Sopenharmony_ci return initTransport610p (); 6249141cc406Sopenharmony_ci case 1220: 6250141cc406Sopenharmony_ci case 1600: 6251141cc406Sopenharmony_ci case 2000: 6252141cc406Sopenharmony_ci default: 6253141cc406Sopenharmony_ci return initTransport1220P (recover); 6254141cc406Sopenharmony_ci } 6255141cc406Sopenharmony_ci} 6256141cc406Sopenharmony_ci 6257141cc406Sopenharmony_ci 6258141cc406Sopenharmony_ci/* 1: OK 6259141cc406Sopenharmony_ci 0: probe failed */ 6260141cc406Sopenharmony_ci 6261141cc406Sopenharmony_cistatic int 6262141cc406Sopenharmony_ciprobe610p (int recover) 6263141cc406Sopenharmony_ci{ 6264141cc406Sopenharmony_ci if (initTransport610p () == 0) 6265141cc406Sopenharmony_ci { 6266141cc406Sopenharmony_ci DBG (0, "initTransport610p() failed (%s:%d)\n", __FILE__, __LINE__); 6267141cc406Sopenharmony_ci return 0; 6268141cc406Sopenharmony_ci } 6269141cc406Sopenharmony_ci 6270141cc406Sopenharmony_ci /* make sure we won't try 1220/200P later 6271141cc406Sopenharmony_ci * since we got here, we have a 610, and in any case 6272141cc406Sopenharmony_ci * NOT a 1220P/2000P, since no EPAT present */ 6273141cc406Sopenharmony_ci sanei_umax_pp_setastra (610); 6274141cc406Sopenharmony_ci 6275141cc406Sopenharmony_ci if (initScanner610p (recover) == 0) 6276141cc406Sopenharmony_ci { 6277141cc406Sopenharmony_ci DBG (0, "initScanner610p() failed (%s:%d)\n", __FILE__, __LINE__); 6278141cc406Sopenharmony_ci return 0; 6279141cc406Sopenharmony_ci } 6280141cc406Sopenharmony_ci /* successful end ... */ 6281141cc406Sopenharmony_ci DBG (1, "UMAX Astra 610p detected\n"); 6282141cc406Sopenharmony_ci DBG (1, "probe610p done ...\n"); 6283141cc406Sopenharmony_ci return 1; 6284141cc406Sopenharmony_ci} 6285141cc406Sopenharmony_ci 6286141cc406Sopenharmony_ci 6287141cc406Sopenharmony_ci /* 6288141cc406Sopenharmony_ci * try PS2 mode 6289141cc406Sopenharmony_ci * returns 1 on success, 0 on failure 6290141cc406Sopenharmony_ci */ 6291141cc406Sopenharmony_ciint 6292141cc406Sopenharmony_ciprobePS2 (unsigned char *dest) 6293141cc406Sopenharmony_ci{ 6294141cc406Sopenharmony_ci int i, tmp; 6295141cc406Sopenharmony_ci 6296141cc406Sopenharmony_ci /* write/read full buffer */ 6297141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 6298141cc406Sopenharmony_ci { 6299141cc406Sopenharmony_ci WRITESLOW (0x0A, i); 6300141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0A, i); 6301141cc406Sopenharmony_ci WRITESLOW (0x0A, 0xFF - i); 6302141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0A, 0xFF - i); 6303141cc406Sopenharmony_ci } 6304141cc406Sopenharmony_ci 6305141cc406Sopenharmony_ci /* end test for nibble byte/byte mode */ 6306141cc406Sopenharmony_ci 6307141cc406Sopenharmony_ci /* now we try nibble buffered mode */ 6308141cc406Sopenharmony_ci WRITESLOW (0x13, 0x01); 6309141cc406Sopenharmony_ci WRITESLOW (0x13, 0x00); /*reset something */ 6310141cc406Sopenharmony_ci WRITESLOW (0x0A, 0x11); 6311141cc406Sopenharmony_ci for (i = 0; i < 10; i++) /* 10 ~ 11 ? */ 6312141cc406Sopenharmony_ci { 6313141cc406Sopenharmony_ci PS2bufferRead (0x400, dest); 6314141cc406Sopenharmony_ci DBG (16, "Loop %d: PS2bufferRead passed ... (%s:%d)\n", i, __FILE__, 6315141cc406Sopenharmony_ci __LINE__); 6316141cc406Sopenharmony_ci } 6317141cc406Sopenharmony_ci 6318141cc406Sopenharmony_ci /* write buffer */ 6319141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6320141cc406Sopenharmony_ci { 6321141cc406Sopenharmony_ci PS2bufferWrite (0x400, dest); 6322141cc406Sopenharmony_ci DBG (16, "Loop %d: PS2bufferWrite passed ... (%s:%d)\n", i, __FILE__, 6323141cc406Sopenharmony_ci __LINE__); 6324141cc406Sopenharmony_ci } 6325141cc406Sopenharmony_ci 6326141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0C, 0x04); 6327141cc406Sopenharmony_ci WRITESLOW (0x13, 0x01); 6328141cc406Sopenharmony_ci WRITESLOW (0x13, 0x00); 6329141cc406Sopenharmony_ci WRITESLOW (0x0A, 0x18); 6330141cc406Sopenharmony_ci 6331141cc406Sopenharmony_ci return 1; 6332141cc406Sopenharmony_ci} 6333141cc406Sopenharmony_ci 6334141cc406Sopenharmony_ci /* 6335141cc406Sopenharmony_ci * try EPP 8 then 32 bits 6336141cc406Sopenharmony_ci * returns 1 on success, 0 on failure 6337141cc406Sopenharmony_ci */ 6338141cc406Sopenharmony_ciint 6339141cc406Sopenharmony_ciprobeEPP (unsigned char *dest) 6340141cc406Sopenharmony_ci{ 6341141cc406Sopenharmony_ci int tmp, i, j; 6342141cc406Sopenharmony_ci int reg; 6343141cc406Sopenharmony_ci 6344141cc406Sopenharmony_ci /* test EPP MODE */ 6345141cc406Sopenharmony_ci setEPPMode (8); 6346141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_EPP; 6347141cc406Sopenharmony_ci ClearRegister (0); 6348141cc406Sopenharmony_ci DBG (16, "ClearRegister(0) passed... (%s:%d)\n", __FILE__, __LINE__); 6349141cc406Sopenharmony_ci WRITESLOW (0x08, 0x22); 6350141cc406Sopenharmony_ci init001 (); 6351141cc406Sopenharmony_ci DBG (16, "init001() passed... (%s:%d)\n", __FILE__, __LINE__); 6352141cc406Sopenharmony_ci gEPAT = 0xC7; 6353141cc406Sopenharmony_ci init002 (0); 6354141cc406Sopenharmony_ci DBG (16, "init002(0) passed... (%s:%d)\n", __FILE__, __LINE__); 6355141cc406Sopenharmony_ci 6356141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0); 6357141cc406Sopenharmony_ci 6358141cc406Sopenharmony_ci /* catch any failure to read back data in EPP mode */ 6359141cc406Sopenharmony_ci reg = registerRead (0x0A); 6360141cc406Sopenharmony_ci if (reg != 0) 6361141cc406Sopenharmony_ci { 6362141cc406Sopenharmony_ci DBG (0, "registerRead, found 0x%X expected 0x00 (%s:%d)\n", reg, 6363141cc406Sopenharmony_ci __FILE__, __LINE__); 6364141cc406Sopenharmony_ci if (reg == 0xFF) 6365141cc406Sopenharmony_ci { 6366141cc406Sopenharmony_ci DBG (0, 6367141cc406Sopenharmony_ci "*** It appears that EPP data transfer doesn't work ***\n"); 6368141cc406Sopenharmony_ci DBG (0, 6369141cc406Sopenharmony_ci "*** Please read SETTING EPP section in sane-umax_pp.5 ***\n"); 6370141cc406Sopenharmony_ci } 6371141cc406Sopenharmony_ci return 0; 6372141cc406Sopenharmony_ci } 6373141cc406Sopenharmony_ci else 6374141cc406Sopenharmony_ci { 6375141cc406Sopenharmony_ci DBG (16, "registerRead(0x0A)=0x00 passed... (%s:%d)\n", __FILE__, 6376141cc406Sopenharmony_ci __LINE__); 6377141cc406Sopenharmony_ci } 6378141cc406Sopenharmony_ci registerWrite (0x0A, 0xFF); 6379141cc406Sopenharmony_ci DBG (16, "registerWrite(0x%X,0x%X) passed... (%s:%d)\n", 0x0A, 0xFF, 6380141cc406Sopenharmony_ci __FILE__, __LINE__); 6381141cc406Sopenharmony_ci REGISTERREAD (0x0A, 0xFF); 6382141cc406Sopenharmony_ci for (i = 1; i < 256; i++) 6383141cc406Sopenharmony_ci { 6384141cc406Sopenharmony_ci REGISTERWRITE (0x0A, i); 6385141cc406Sopenharmony_ci REGISTERREAD (0x0A, i); 6386141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0xFF - i); 6387141cc406Sopenharmony_ci REGISTERREAD (0x0A, 0xFF - i); 6388141cc406Sopenharmony_ci } 6389141cc406Sopenharmony_ci 6390141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x01); 6391141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 6392141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x11); 6393141cc406Sopenharmony_ci 6394141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6395141cc406Sopenharmony_ci { 6396141cc406Sopenharmony_ci bufferRead (0x400, dest); 6397141cc406Sopenharmony_ci for (j = 0; j < 512; j++) 6398141cc406Sopenharmony_ci { 6399141cc406Sopenharmony_ci if (dest[2 * j] != (j % 256)) 6400141cc406Sopenharmony_ci { 6401141cc406Sopenharmony_ci DBG (0, "Loop %d, char %d bufferRead failed! (%s:%d)\n", i, 6402141cc406Sopenharmony_ci j * 2, __FILE__, __LINE__); 6403141cc406Sopenharmony_ci return 0; 6404141cc406Sopenharmony_ci } 6405141cc406Sopenharmony_ci if (dest[2 * j + 1] != (0xFF - (j % 256))) 6406141cc406Sopenharmony_ci { 6407141cc406Sopenharmony_ci DBG (0, "Loop %d, char %d bufferRead failed! (%s:%d)\n", i, 6408141cc406Sopenharmony_ci j * 2 + 1, __FILE__, __LINE__); 6409141cc406Sopenharmony_ci return 0; 6410141cc406Sopenharmony_ci } 6411141cc406Sopenharmony_ci } 6412141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferRead(0x400,dest) passed... (%s:%d)\n", i, 6413141cc406Sopenharmony_ci __FILE__, __LINE__); 6414141cc406Sopenharmony_ci } 6415141cc406Sopenharmony_ci 6416141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6417141cc406Sopenharmony_ci { 6418141cc406Sopenharmony_ci bufferWrite (0x400, dest); 6419141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferWrite(0x400,dest) passed... (%s:%d)\n", i, 6420141cc406Sopenharmony_ci __FILE__, __LINE__); 6421141cc406Sopenharmony_ci } 6422141cc406Sopenharmony_ci 6423141cc406Sopenharmony_ci 6424141cc406Sopenharmony_ci REGISTERREAD (0x0C, 4); 6425141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x01); 6426141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 6427141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); 6428141cc406Sopenharmony_ci 6429141cc406Sopenharmony_ci Outb (DATA, 0x0); 6430141cc406Sopenharmony_ci ClearRegister (0); 6431141cc406Sopenharmony_ci init001 (); 6432141cc406Sopenharmony_ci 6433141cc406Sopenharmony_ci if (checkEPAT () != 0) 6434141cc406Sopenharmony_ci return 0; 6435141cc406Sopenharmony_ci DBG (16, "checkEPAT() passed... (%s:%d)\n", __FILE__, __LINE__); 6436141cc406Sopenharmony_ci 6437141cc406Sopenharmony_ci tmp = Inb (CONTROL) & 0x1F; 6438141cc406Sopenharmony_ci Outb (CONTROL, tmp); 6439141cc406Sopenharmony_ci Outb (CONTROL, tmp); 6440141cc406Sopenharmony_ci 6441141cc406Sopenharmony_ci WRITESLOW (0x08, 0x21); 6442141cc406Sopenharmony_ci init001 (); 6443141cc406Sopenharmony_ci DBG (16, "init001() passed... (%s:%d)\n", __FILE__, __LINE__); 6444141cc406Sopenharmony_ci WRITESLOW (0x08, 0x21); 6445141cc406Sopenharmony_ci init001 (); 6446141cc406Sopenharmony_ci DBG (16, "init001() passed... (%s:%d)\n", __FILE__, __LINE__); 6447141cc406Sopenharmony_ci SPPResetLPT (); 6448141cc406Sopenharmony_ci 6449141cc406Sopenharmony_ci 6450141cc406Sopenharmony_ci if (init005 (0x80)) 6451141cc406Sopenharmony_ci { 6452141cc406Sopenharmony_ci DBG (0, "init005(0x80) failed... (%s:%d)\n", __FILE__, __LINE__); 6453141cc406Sopenharmony_ci } 6454141cc406Sopenharmony_ci DBG (16, "init005(0x80) passed... (%s:%d)\n", __FILE__, __LINE__); 6455141cc406Sopenharmony_ci if (init005 (0xEC)) 6456141cc406Sopenharmony_ci { 6457141cc406Sopenharmony_ci DBG (0, "init005(0xEC) failed... (%s:%d)\n", __FILE__, __LINE__); 6458141cc406Sopenharmony_ci } 6459141cc406Sopenharmony_ci DBG (16, "init005(0xEC) passed... (%s:%d)\n", __FILE__, __LINE__); 6460141cc406Sopenharmony_ci 6461141cc406Sopenharmony_ci 6462141cc406Sopenharmony_ci /* write/read buffer loop */ 6463141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 6464141cc406Sopenharmony_ci { 6465141cc406Sopenharmony_ci REGISTERWRITE (0x0A, i); 6466141cc406Sopenharmony_ci REGISTERREAD (0x0A, i); 6467141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0xFF - i); 6468141cc406Sopenharmony_ci REGISTERREAD (0x0A, 0xFF - i); 6469141cc406Sopenharmony_ci } 6470141cc406Sopenharmony_ci DBG (16, "EPP write/read buffer loop passed... (%s:%d)\n", __FILE__, 6471141cc406Sopenharmony_ci __LINE__); 6472141cc406Sopenharmony_ci 6473141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x01); 6474141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 6475141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x11); 6476141cc406Sopenharmony_ci 6477141cc406Sopenharmony_ci /* test EPP32 mode */ 6478141cc406Sopenharmony_ci /* we set 32 bits I/O mode first, then step back to */ 6479141cc406Sopenharmony_ci /* 8bits if tests fail */ 6480141cc406Sopenharmony_ci setEPPMode (32); 6481141cc406Sopenharmony_ci for (i = 0; (i < 10) && (getEPPMode () == 32); i++) 6482141cc406Sopenharmony_ci { 6483141cc406Sopenharmony_ci bufferRead (0x400, dest); 6484141cc406Sopenharmony_ci /* if 32 bit I/O work, we should have a buffer */ 6485141cc406Sopenharmony_ci /* filled by 00 FF 01 FE 02 FD 03 FC ..... */ 6486141cc406Sopenharmony_ci for (j = 0; j < 0x200; j++) 6487141cc406Sopenharmony_ci { 6488141cc406Sopenharmony_ci if ((dest[j * 2] != j % 256) 6489141cc406Sopenharmony_ci || (dest[j * 2 + 1] != 0xFF - (j % 256))) 6490141cc406Sopenharmony_ci { 6491141cc406Sopenharmony_ci DBG (1, "Setting EPP I/O to 8 bits ... (%s:%d)\n", __FILE__, 6492141cc406Sopenharmony_ci __LINE__); 6493141cc406Sopenharmony_ci setEPPMode (8); 6494141cc406Sopenharmony_ci /* leave out current loop since an error was detected */ 6495141cc406Sopenharmony_ci break; 6496141cc406Sopenharmony_ci } 6497141cc406Sopenharmony_ci } 6498141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferRead(0x400) passed... (%s:%d)\n", i, 6499141cc406Sopenharmony_ci __FILE__, __LINE__); 6500141cc406Sopenharmony_ci } 6501141cc406Sopenharmony_ci DBG (1, "%d bits EPP data transfer\n", getEPPMode ()); 6502141cc406Sopenharmony_ci 6503141cc406Sopenharmony_ci 6504141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6505141cc406Sopenharmony_ci { 6506141cc406Sopenharmony_ci bufferWrite (0x400, dest); 6507141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferWrite(0x400,dest) passed... (%s:%d)\n", i, 6508141cc406Sopenharmony_ci __FILE__, __LINE__); 6509141cc406Sopenharmony_ci } 6510141cc406Sopenharmony_ci 6511141cc406Sopenharmony_ci 6512141cc406Sopenharmony_ci 6513141cc406Sopenharmony_ci REGISTERREAD (0x0C, 0x04); 6514141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x01); 6515141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 6516141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); 6517141cc406Sopenharmony_ci 6518141cc406Sopenharmony_ci WRITESLOW (0x08, 0x21); 6519141cc406Sopenharmony_ci init001 (); 6520141cc406Sopenharmony_ci DBG (16, "init001() passed... (%s:%d)\n", __FILE__, __LINE__); 6521141cc406Sopenharmony_ci SPPResetLPT (); 6522141cc406Sopenharmony_ci 6523141cc406Sopenharmony_ci if (init005 (0x80)) 6524141cc406Sopenharmony_ci { 6525141cc406Sopenharmony_ci DBG (0, "init005(0x80) failed... (%s:%d)\n", __FILE__, __LINE__); 6526141cc406Sopenharmony_ci } 6527141cc406Sopenharmony_ci DBG (16, "init005(0x80) passed... (%s:%d)\n", __FILE__, __LINE__); 6528141cc406Sopenharmony_ci if (init005 (0xEC)) 6529141cc406Sopenharmony_ci { 6530141cc406Sopenharmony_ci DBG (0, "init005(0xEC) failed... (%s:%d)\n", __FILE__, __LINE__); 6531141cc406Sopenharmony_ci } 6532141cc406Sopenharmony_ci DBG (16, "init005(0xEC) passed... (%s:%d)\n", __FILE__, __LINE__); 6533141cc406Sopenharmony_ci 6534141cc406Sopenharmony_ci 6535141cc406Sopenharmony_ci /* write/read buffer loop */ 6536141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 6537141cc406Sopenharmony_ci { 6538141cc406Sopenharmony_ci REGISTERWRITE (0x0A, i); 6539141cc406Sopenharmony_ci REGISTERREAD (0x0A, i); 6540141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0xFF - i); 6541141cc406Sopenharmony_ci REGISTERREAD (0x0A, 0xFF - i); 6542141cc406Sopenharmony_ci } 6543141cc406Sopenharmony_ci DBG (16, "EPP write/read buffer loop passed... (%s:%d)\n", __FILE__, 6544141cc406Sopenharmony_ci __LINE__); 6545141cc406Sopenharmony_ci 6546141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x01); 6547141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 6548141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x11); 6549141cc406Sopenharmony_ci 6550141cc406Sopenharmony_ci 6551141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6552141cc406Sopenharmony_ci { 6553141cc406Sopenharmony_ci bufferRead (0x400, dest); 6554141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferRead(0x400) passed... (%s:%d)\n", i, 6555141cc406Sopenharmony_ci __FILE__, __LINE__); 6556141cc406Sopenharmony_ci } 6557141cc406Sopenharmony_ci 6558141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6559141cc406Sopenharmony_ci { 6560141cc406Sopenharmony_ci bufferWrite (0x400, dest); 6561141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferWrite(0x400,dest) passed... (%s:%d)\n", i, 6562141cc406Sopenharmony_ci __FILE__, __LINE__); 6563141cc406Sopenharmony_ci } 6564141cc406Sopenharmony_ci REGISTERREAD (0x0C, 0x04); 6565141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x01); 6566141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 6567141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); 6568141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_EPP; 6569141cc406Sopenharmony_ci return 1; 6570141cc406Sopenharmony_ci} 6571141cc406Sopenharmony_ci 6572141cc406Sopenharmony_ci /* 6573141cc406Sopenharmony_ci * try ECP mode 6574141cc406Sopenharmony_ci * returns 1 on success, 0 on failure 6575141cc406Sopenharmony_ci */ 6576141cc406Sopenharmony_ciint 6577141cc406Sopenharmony_ciprobeECP (unsigned char *dest) 6578141cc406Sopenharmony_ci{ 6579141cc406Sopenharmony_ci int i, j, tmp; 6580141cc406Sopenharmony_ci unsigned char breg; 6581141cc406Sopenharmony_ci 6582141cc406Sopenharmony_ci /* if ECP not available, fail */ 6583141cc406Sopenharmony_ci if (gECP != 1) 6584141cc406Sopenharmony_ci { 6585141cc406Sopenharmony_ci DBG (1, "Hardware can't do ECP, giving up (%s:%d) ...\n", __FILE__, 6586141cc406Sopenharmony_ci __LINE__); 6587141cc406Sopenharmony_ci return 0; 6588141cc406Sopenharmony_ci } 6589141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_ECP; 6590141cc406Sopenharmony_ci 6591141cc406Sopenharmony_ci/* clean from EPP failure */ 6592141cc406Sopenharmony_ci breg = Inb (CONTROL); 6593141cc406Sopenharmony_ci Outb (CONTROL, breg & 0x04); 6594141cc406Sopenharmony_ci 6595141cc406Sopenharmony_ci/* reset sequence */ 6596141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); byte mode */ 6597141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6598141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 6599141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 6600141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 6601141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 6602141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 6603141cc406Sopenharmony_ci { 6604141cc406Sopenharmony_ci breg = (Inb (STATUS)) & 0xF8; 6605141cc406Sopenharmony_ci if (breg != 0x48) 6606141cc406Sopenharmony_ci { 6607141cc406Sopenharmony_ci DBG (0, 6608141cc406Sopenharmony_ci "probeECP() failed at sync step %d, status=0x%02X, expected 0x48 (%s:%d)\n", 6609141cc406Sopenharmony_ci i, breg, __FILE__, __LINE__); 6610141cc406Sopenharmony_ci return 0; 6611141cc406Sopenharmony_ci } 6612141cc406Sopenharmony_ci } 6613141cc406Sopenharmony_ci Outb (CONTROL, 0x0E); 6614141cc406Sopenharmony_ci Outb (CONTROL, 0x0E); 6615141cc406Sopenharmony_ci Outb (CONTROL, 0x0E); 6616141cc406Sopenharmony_ci breg = (Inb (STATUS)) & 0xF8; 6617141cc406Sopenharmony_ci if (breg != 0x48) 6618141cc406Sopenharmony_ci { 6619141cc406Sopenharmony_ci DBG (0, "probeECP() failed, status=0x%02X, expected 0x48 (%s:%d)\n", 6620141cc406Sopenharmony_ci breg, __FILE__, __LINE__); 6621141cc406Sopenharmony_ci return 0; 6622141cc406Sopenharmony_ci } 6623141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6624141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6625141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6626141cc406Sopenharmony_ci breg = Inb (STATUS) & 0xF8; 6627141cc406Sopenharmony_ci breg = (Inb (STATUS)) & 0xF8; 6628141cc406Sopenharmony_ci if (breg != 0xC8) 6629141cc406Sopenharmony_ci { 6630141cc406Sopenharmony_ci DBG (0, "probeECP() failed, status=0x%02X, expected 0xC8 (%s:%d)\n", 6631141cc406Sopenharmony_ci breg, __FILE__, __LINE__); 6632141cc406Sopenharmony_ci return 0; 6633141cc406Sopenharmony_ci } 6634141cc406Sopenharmony_ci/* end of reset sequence */ 6635141cc406Sopenharmony_ci 6636141cc406Sopenharmony_ci Outb (DATA, 0x00); 6637141cc406Sopenharmony_ci ClearRegister (0); 6638141cc406Sopenharmony_ci 6639141cc406Sopenharmony_ci/* utile ? semble tester le registre de configuration 6640141cc406Sopenharmony_ci * inb ECR,35 6641141cc406Sopenharmony_ci * inb 77B,FF 6642141cc406Sopenharmony_ci * inb ECR,35 6643141cc406Sopenharmony_ci */ 6644141cc406Sopenharmony_ci/* routine A */ 6645141cc406Sopenharmony_ci breg = Inb (CONTROL); /* 0x04 évidemment! */ 6646141cc406Sopenharmony_ci breg = Inb (ECR); 6647141cc406Sopenharmony_ci breg = Inb (ECR); 6648141cc406Sopenharmony_ci breg = Inb (ECR); 6649141cc406Sopenharmony_ci breg = Inb (ECR); 6650141cc406Sopenharmony_ci breg = Inb (CONTROL); 6651141cc406Sopenharmony_ci byteMode (); /*Outb (ECR, 0x20); byte mode */ 6652141cc406Sopenharmony_ci /*byteMode (); Outb (ECR, 0x20); */ 6653141cc406Sopenharmony_ci breg = Inb (CONTROL); 6654141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6655141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6656141cc406Sopenharmony_ci breg = Inb (ECR); /* 35 expected */ 6657141cc406Sopenharmony_ci breg = Inb (ECR); /* 35 expected */ 6658141cc406Sopenharmony_ci breg = Inb (ECR); /* 35 expected */ 6659141cc406Sopenharmony_ci breg = Inb (ECR); /* 35 expected */ 6660141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6661141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6662141cc406Sopenharmony_ci byteMode (); 6663141cc406Sopenharmony_ci byteMode (); 6664141cc406Sopenharmony_ci 6665141cc406Sopenharmony_ci ClearRegister (0); 6666141cc406Sopenharmony_ci 6667141cc406Sopenharmony_ci/* routine C */ 6668141cc406Sopenharmony_ci PS2registerWrite (0x08, 0x01); 6669141cc406Sopenharmony_ci 6670141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 6671141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6672141cc406Sopenharmony_ci 6673141cc406Sopenharmony_ci ClearRegister (0); 6674141cc406Sopenharmony_ci 6675141cc406Sopenharmony_ci breg = PS2Something (0x10); 6676141cc406Sopenharmony_ci if (breg != 0x0B) 6677141cc406Sopenharmony_ci { 6678141cc406Sopenharmony_ci DBG (0, "probeECP() failed, reg10=0x%02X, expected 0x0B (%s:%d)\n", 6679141cc406Sopenharmony_ci breg, __FILE__, __LINE__); 6680141cc406Sopenharmony_ci /* return 0; */ 6681141cc406Sopenharmony_ci } 6682141cc406Sopenharmony_ci 6683141cc406Sopenharmony_ci 6684141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 6685141cc406Sopenharmony_ci { 6686141cc406Sopenharmony_ci ECPregisterWrite (0x0A, i); 6687141cc406Sopenharmony_ci breg = ECPregisterRead (0x0A); 6688141cc406Sopenharmony_ci if (breg != i) 6689141cc406Sopenharmony_ci { 6690141cc406Sopenharmony_ci DBG (0, "probeECP(), loop %d failed (%s:%d)\n", i, __FILE__, 6691141cc406Sopenharmony_ci __LINE__); 6692141cc406Sopenharmony_ci return 0; 6693141cc406Sopenharmony_ci } 6694141cc406Sopenharmony_ci ECPregisterWrite (0x0A, 0xFF - i); 6695141cc406Sopenharmony_ci breg = ECPregisterRead (0x0A); 6696141cc406Sopenharmony_ci if (breg != 0xFF - i) 6697141cc406Sopenharmony_ci { 6698141cc406Sopenharmony_ci DBG (0, "probeECP(), loop %d failed (%s:%d)\n", i, __FILE__, 6699141cc406Sopenharmony_ci __LINE__); 6700141cc406Sopenharmony_ci return 0; 6701141cc406Sopenharmony_ci } 6702141cc406Sopenharmony_ci } 6703141cc406Sopenharmony_ci DBG (16, "probeECP(), loop passed (%s:%d)\n", __FILE__, __LINE__); 6704141cc406Sopenharmony_ci 6705141cc406Sopenharmony_ci ECPregisterWrite (0x13, 0x01); 6706141cc406Sopenharmony_ci ECPregisterWrite (0x13, 0x00); 6707141cc406Sopenharmony_ci ECPregisterWrite (0x0A, 0x11); 6708141cc406Sopenharmony_ci 6709141cc406Sopenharmony_ci /* there is one buffer transfer size set up */ 6710141cc406Sopenharmony_ci /* subsequent reads are done in a row */ 6711141cc406Sopenharmony_ci ECPSetBuffer (0x400); 6712141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6713141cc406Sopenharmony_ci { 6714141cc406Sopenharmony_ci /* if (i > 0) */ 6715141cc406Sopenharmony_ci compatMode (); 6716141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset ? */ 6717141cc406Sopenharmony_ci 6718141cc406Sopenharmony_ci ECPbufferRead (1024, dest); 6719141cc406Sopenharmony_ci /* check content of the returned buffer */ 6720141cc406Sopenharmony_ci for (j = 0; j < 256; j++) 6721141cc406Sopenharmony_ci { 6722141cc406Sopenharmony_ci if (dest[j * 2] != j) 6723141cc406Sopenharmony_ci { 6724141cc406Sopenharmony_ci DBG (0, 6725141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6726141cc406Sopenharmony_ci j * 2, j, dest[j * 2]); 6727141cc406Sopenharmony_ci return 0; 6728141cc406Sopenharmony_ci } 6729141cc406Sopenharmony_ci if (dest[j * 2 + 1] != 0xFF - j) 6730141cc406Sopenharmony_ci { 6731141cc406Sopenharmony_ci DBG 6732141cc406Sopenharmony_ci (0, 6733141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6734141cc406Sopenharmony_ci j * 2 + 1, 0xFF - j, dest[j * 2 + 1]); 6735141cc406Sopenharmony_ci return 0; 6736141cc406Sopenharmony_ci } 6737141cc406Sopenharmony_ci if (dest[512 + j * 2] != j) 6738141cc406Sopenharmony_ci { 6739141cc406Sopenharmony_ci DBG (0, 6740141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6741141cc406Sopenharmony_ci 512 + j * 2, j, dest[512 + j * 2]); 6742141cc406Sopenharmony_ci return 0; 6743141cc406Sopenharmony_ci } 6744141cc406Sopenharmony_ci if (dest[512 + j * 2 + 1] != 0xFF - j) 6745141cc406Sopenharmony_ci { 6746141cc406Sopenharmony_ci DBG 6747141cc406Sopenharmony_ci (0, 6748141cc406Sopenharmony_ci "Altered buffer value at %03X, expected 0x%02X, found 0x%02X\n", 6749141cc406Sopenharmony_ci 512 + j * 2 + 1, 0xFF - j, dest[512 + j * 2 + 1]); 6750141cc406Sopenharmony_ci return 0; 6751141cc406Sopenharmony_ci } 6752141cc406Sopenharmony_ci } 6753141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6754141cc406Sopenharmony_ci byteMode (); 6755141cc406Sopenharmony_ci } 6756141cc406Sopenharmony_ci 6757141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6758141cc406Sopenharmony_ci ECPbufferWrite (1024, dest); 6759141cc406Sopenharmony_ci 6760141cc406Sopenharmony_ci breg = ECPregisterRead (0x0C); 6761141cc406Sopenharmony_ci if (breg != 0x04) 6762141cc406Sopenharmony_ci { 6763141cc406Sopenharmony_ci DBG (0, "Warning! expected reg0C=0x04, found 0x%02X! (%s:%d) \n", breg, 6764141cc406Sopenharmony_ci __FILE__, __LINE__); 6765141cc406Sopenharmony_ci } 6766141cc406Sopenharmony_ci 6767141cc406Sopenharmony_ci ECPregisterWrite (0x13, 0x01); 6768141cc406Sopenharmony_ci ECPregisterWrite (0x13, 0x00); 6769141cc406Sopenharmony_ci ECPregisterWrite (0x0A, 0x18); 6770141cc406Sopenharmony_ci 6771141cc406Sopenharmony_ci /* reset printer ? */ 6772141cc406Sopenharmony_ci Outb (DATA, 0x00); 6773141cc406Sopenharmony_ci Outb (CONTROL, 0x00); 6774141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6775141cc406Sopenharmony_ci 6776141cc406Sopenharmony_ci for (i = 0; i < 3; i++) 6777141cc406Sopenharmony_ci { /* will go in a function */ 6778141cc406Sopenharmony_ci ClearRegister (0); 6779141cc406Sopenharmony_ci if (waitAck () != 1) 6780141cc406Sopenharmony_ci { 6781141cc406Sopenharmony_ci DBG (0, "probeECP failed because of waitAck() (%s:%d) \n", __FILE__, 6782141cc406Sopenharmony_ci __LINE__); 6783141cc406Sopenharmony_ci /* return 0; may fail without harm ... ??? */ 6784141cc406Sopenharmony_ci } 6785141cc406Sopenharmony_ci /* are these 2 out really needed ? */ 6786141cc406Sopenharmony_ci PS2registerWrite (0x08, 0x01); 6787141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); /* select + reset */ 6788141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset */ 6789141cc406Sopenharmony_ci } 6790141cc406Sopenharmony_ci 6791141cc406Sopenharmony_ci /* prologue of the 'rotate test' */ 6792141cc406Sopenharmony_ci ClearRegister (0); 6793141cc406Sopenharmony_ci breg = PS2Something (0x10); 6794141cc406Sopenharmony_ci if (breg != 0x0B) 6795141cc406Sopenharmony_ci { 6796141cc406Sopenharmony_ci DBG (0, 6797141cc406Sopenharmony_ci "PS2Something returned 0x%02X, 0x0B expected (%s:%d)\n", breg, 6798141cc406Sopenharmony_ci __FILE__, __LINE__); 6799141cc406Sopenharmony_ci } 6800141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset */ 6801141cc406Sopenharmony_ci 6802141cc406Sopenharmony_ci if (init005 (0x80)) 6803141cc406Sopenharmony_ci { 6804141cc406Sopenharmony_ci DBG (0, "init005(0x80) failed... (%s:%d)\n", __FILE__, __LINE__); 6805141cc406Sopenharmony_ci } 6806141cc406Sopenharmony_ci DBG (16, "init005(0x80) passed... (%s:%d)\n", __FILE__, __LINE__); 6807141cc406Sopenharmony_ci if (init005 (0xEC)) 6808141cc406Sopenharmony_ci { 6809141cc406Sopenharmony_ci DBG (0, "init005(0xEC) failed... (%s:%d)\n", __FILE__, __LINE__); 6810141cc406Sopenharmony_ci } 6811141cc406Sopenharmony_ci DBG (16, "init005(0xEC) passed... (%s:%d)\n", __FILE__, __LINE__); 6812141cc406Sopenharmony_ci 6813141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 6814141cc406Sopenharmony_ci { 6815141cc406Sopenharmony_ci REGISTERWRITE (0x0A, i); 6816141cc406Sopenharmony_ci REGISTERREAD (0x0A, i); 6817141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0xFF - i); 6818141cc406Sopenharmony_ci REGISTERREAD (0x0A, 0xFF - i); 6819141cc406Sopenharmony_ci } 6820141cc406Sopenharmony_ci DBG (16, "ECPprobe(), write/read buffer loop passed (%s:%d)\n", __FILE__, 6821141cc406Sopenharmony_ci __LINE__); 6822141cc406Sopenharmony_ci 6823141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x01); 6824141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 6825141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x11); 6826141cc406Sopenharmony_ci 6827141cc406Sopenharmony_ci /* should be a function */ 6828141cc406Sopenharmony_ci /* in probeEPP(), we begin 32 bit mode test here */ 6829141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6830141cc406Sopenharmony_ci { 6831141cc406Sopenharmony_ci compatMode (); 6832141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset ? */ 6833141cc406Sopenharmony_ci 6834141cc406Sopenharmony_ci ECPbufferRead (0x400, dest); 6835141cc406Sopenharmony_ci /* check content of the returned buffer */ 6836141cc406Sopenharmony_ci for (j = 0; j < 256; j++) 6837141cc406Sopenharmony_ci { 6838141cc406Sopenharmony_ci if (dest[j * 2] != j) 6839141cc406Sopenharmony_ci { 6840141cc406Sopenharmony_ci DBG (0, 6841141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6842141cc406Sopenharmony_ci j * 2, j, dest[j * 2]); 6843141cc406Sopenharmony_ci return 0; 6844141cc406Sopenharmony_ci } 6845141cc406Sopenharmony_ci if (dest[j * 2 + 1] != 0xFF - j) 6846141cc406Sopenharmony_ci { 6847141cc406Sopenharmony_ci DBG 6848141cc406Sopenharmony_ci (0, 6849141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6850141cc406Sopenharmony_ci j * 2 + 1, 0xFF - j, dest[j * 2 + 1]); 6851141cc406Sopenharmony_ci return 0; 6852141cc406Sopenharmony_ci } 6853141cc406Sopenharmony_ci if (dest[512 + j * 2] != j) 6854141cc406Sopenharmony_ci { 6855141cc406Sopenharmony_ci DBG (0, 6856141cc406Sopenharmony_ci "Altered buffer value at %03X, expected %02X, found %02X\n", 6857141cc406Sopenharmony_ci 512 + j * 2, j, dest[512 + j * 2]); 6858141cc406Sopenharmony_ci return 0; 6859141cc406Sopenharmony_ci } 6860141cc406Sopenharmony_ci if (dest[512 + j * 2 + 1] != 0xFF - j) 6861141cc406Sopenharmony_ci { 6862141cc406Sopenharmony_ci DBG 6863141cc406Sopenharmony_ci (0, 6864141cc406Sopenharmony_ci "Altered buffer value at %03X, expected 0x%02X, found 0x%02X\n", 6865141cc406Sopenharmony_ci 512 + j * 2 + 1, 0xFF - j, dest[512 + j * 2 + 1]); 6866141cc406Sopenharmony_ci return 0; 6867141cc406Sopenharmony_ci } 6868141cc406Sopenharmony_ci } 6869141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 6870141cc406Sopenharmony_ci byteMode (); 6871141cc406Sopenharmony_ci } 6872141cc406Sopenharmony_ci 6873141cc406Sopenharmony_ci for (i = 0; i < 10; i++) 6874141cc406Sopenharmony_ci ECPbufferWrite (1024, dest); 6875141cc406Sopenharmony_ci 6876141cc406Sopenharmony_ci REGISTERREAD (0x0C, 0x04); 6877141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x01); 6878141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 6879141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); 6880141cc406Sopenharmony_ci waitAck (); 6881141cc406Sopenharmony_ci 6882141cc406Sopenharmony_ci return 1; 6883141cc406Sopenharmony_ci} 6884141cc406Sopenharmony_ci 6885141cc406Sopenharmony_ci 6886141cc406Sopenharmony_ci 6887141cc406Sopenharmony_ci/* 1: OK 6888141cc406Sopenharmony_ci 0: probe failed */ 6889141cc406Sopenharmony_ci 6890141cc406Sopenharmony_ciint 6891141cc406Sopenharmony_cisanei_umax_pp_probeScanner (int recover) 6892141cc406Sopenharmony_ci{ 6893141cc406Sopenharmony_ci int tmp, i, j; 6894141cc406Sopenharmony_ci int reg, nb; 6895141cc406Sopenharmony_ci unsigned char *dest = NULL; 6896141cc406Sopenharmony_ci int initbuf[2049]; 6897141cc406Sopenharmony_ci int voidbuf[2049]; 6898141cc406Sopenharmony_ci int val; 6899141cc406Sopenharmony_ci int zero[5] = { 0, 0, 0, 0, -1 }; 6900141cc406Sopenharmony_ci int model; 6901141cc406Sopenharmony_ci 6902141cc406Sopenharmony_ci /* saves port state */ 6903141cc406Sopenharmony_ci gData = Inb (DATA); 6904141cc406Sopenharmony_ci gControl = Inb (CONTROL); 6905141cc406Sopenharmony_ci 6906141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 6907141cc406Sopenharmony_ci return probe610p (recover); 6908141cc406Sopenharmony_ci 6909141cc406Sopenharmony_ci /* save and set CONTROL */ 6910141cc406Sopenharmony_ci tmp = (Inb (CONTROL)) & 0x1F; 6911141cc406Sopenharmony_ci tmp = (Inb (CONTROL)) & 0x1F; 6912141cc406Sopenharmony_ci Outb (CONTROL, tmp); 6913141cc406Sopenharmony_ci Outb (CONTROL, tmp); 6914141cc406Sopenharmony_ci 6915141cc406Sopenharmony_ci tmp = Inb (DATA); 6916141cc406Sopenharmony_ci tmp = Inb (CONTROL) & 0x3F; 6917141cc406Sopenharmony_ci Outb (CONTROL, tmp); 6918141cc406Sopenharmony_ci 6919141cc406Sopenharmony_ci tmp = Inb (CONTROL) & 0x3F; 6920141cc406Sopenharmony_ci tmp = Inb (DATA); 6921141cc406Sopenharmony_ci tmp = Inb (CONTROL) & 0x3F; 6922141cc406Sopenharmony_ci tmp = Inb (DATA); 6923141cc406Sopenharmony_ci 6924141cc406Sopenharmony_ci /* any scanner ? */ 6925141cc406Sopenharmony_ci /* fast detect */ 6926141cc406Sopenharmony_ci tmp = ringScanner (2, 0); 6927141cc406Sopenharmony_ci if (!tmp) 6928141cc406Sopenharmony_ci { 6929141cc406Sopenharmony_ci DBG (1, "No scanner detected by 'ringScanner(2,0)'...\n"); 6930141cc406Sopenharmony_ci tmp = ringScanner (5, 0); 6931141cc406Sopenharmony_ci if (!tmp) 6932141cc406Sopenharmony_ci { 6933141cc406Sopenharmony_ci DBG (1, "No scanner detected by 'ringScanner(5,0)'...\n"); 6934141cc406Sopenharmony_ci tmp = ringScanner (5, 10000); 6935141cc406Sopenharmony_ci if (!tmp) 6936141cc406Sopenharmony_ci { 6937141cc406Sopenharmony_ci DBG (1, "No scanner detected by 'ringScanner(5,10000)'...\n"); 6938141cc406Sopenharmony_ci tmp = ringScanner (5, 10000); 6939141cc406Sopenharmony_ci if (!tmp) 6940141cc406Sopenharmony_ci { 6941141cc406Sopenharmony_ci DBG (1, 6942141cc406Sopenharmony_ci "No scanner detected by 'ringScanner(5,10000)'...\n"); 6943141cc406Sopenharmony_ci } 6944141cc406Sopenharmony_ci } 6945141cc406Sopenharmony_ci } 6946141cc406Sopenharmony_ci } 6947141cc406Sopenharmony_ci if (!tmp) 6948141cc406Sopenharmony_ci { 6949141cc406Sopenharmony_ci DBG (1, "No 1220P/2000P scanner detected by 'ringScanner()'...\n"); 6950141cc406Sopenharmony_ci } 6951141cc406Sopenharmony_ci DBG (16, "ringScanner passed...\n"); 6952141cc406Sopenharmony_ci 6953141cc406Sopenharmony_ci gControl = Inb (CONTROL) & 0x3F; 6954141cc406Sopenharmony_ci g67D = 1; 6955141cc406Sopenharmony_ci if (sendCommand (0x30) == 0) 6956141cc406Sopenharmony_ci { 6957141cc406Sopenharmony_ci DBG (0, "sendCommand(0x30) (%s:%d) failed ...\n", __FILE__, __LINE__); 6958141cc406Sopenharmony_ci return 0; 6959141cc406Sopenharmony_ci } 6960141cc406Sopenharmony_ci DBG (16, "sendCommand(0x30) passed ... (%s:%d)\n", __FILE__, __LINE__); 6961141cc406Sopenharmony_ci g67E = 4; /* bytes to read */ 6962141cc406Sopenharmony_ci if (sendCommand (0x00) == 0) 6963141cc406Sopenharmony_ci { 6964141cc406Sopenharmony_ci DBG (0, "sendCommand(0x00) (%s:%d) failed ...\n", __FILE__, __LINE__); 6965141cc406Sopenharmony_ci return 0; 6966141cc406Sopenharmony_ci } 6967141cc406Sopenharmony_ci DBG (16, "sendCommand(0x00) passed... (%s:%d)\n", __FILE__, __LINE__); 6968141cc406Sopenharmony_ci g67E = 0; /* bytes to read */ 6969141cc406Sopenharmony_ci if (testVersion (0) == 0) 6970141cc406Sopenharmony_ci { 6971141cc406Sopenharmony_ci DBG (16, "testVersion(0) (%s:%d) failed ...\n", __FILE__, __LINE__); 6972141cc406Sopenharmony_ci } 6973141cc406Sopenharmony_ci DBG (16, "testVersion(0) passed...\n"); 6974141cc406Sopenharmony_ci /* must fail for 1220P and 2000P */ 6975141cc406Sopenharmony_ci if (testVersion (1) == 0) /* software doesn't do it for model 0x07 */ 6976141cc406Sopenharmony_ci { /* but it works .. */ 6977141cc406Sopenharmony_ci DBG (16, "testVersion(1) failed (expected) ... (%s:%d)\n", __FILE__, 6978141cc406Sopenharmony_ci __LINE__); 6979141cc406Sopenharmony_ci } 6980141cc406Sopenharmony_ci else 6981141cc406Sopenharmony_ci { 6982141cc406Sopenharmony_ci DBG (16, "Unexpected success on testVersion(1) ... (%s:%d)\n", __FILE__, 6983141cc406Sopenharmony_ci __LINE__); 6984141cc406Sopenharmony_ci } 6985141cc406Sopenharmony_ci if (testVersion (0) == 0) 6986141cc406Sopenharmony_ci { 6987141cc406Sopenharmony_ci DBG (16, "testVersion(0) (%s:%d) failed ...\n", __FILE__, __LINE__); 6988141cc406Sopenharmony_ci } 6989141cc406Sopenharmony_ci DBG (16, "testVersion(0) passed...\n"); 6990141cc406Sopenharmony_ci /* must fail */ 6991141cc406Sopenharmony_ci if (testVersion (1) == 0) 6992141cc406Sopenharmony_ci { 6993141cc406Sopenharmony_ci DBG (16, "testVersion(1) failed (expected) ... (%s:%d)\n", __FILE__, 6994141cc406Sopenharmony_ci __LINE__); 6995141cc406Sopenharmony_ci } 6996141cc406Sopenharmony_ci else 6997141cc406Sopenharmony_ci { 6998141cc406Sopenharmony_ci DBG (16, "Unexpected success on testVersion(1) ... (%s:%d)\n", __FILE__, 6999141cc406Sopenharmony_ci __LINE__); 7000141cc406Sopenharmony_ci } 7001141cc406Sopenharmony_ci 7002141cc406Sopenharmony_ci Outb (DATA, 0x04); 7003141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 7004141cc406Sopenharmony_ci Outb (DATA, 0x04); 7005141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 7006141cc406Sopenharmony_ci 7007141cc406Sopenharmony_ci gControl = Inb (CONTROL) & 0x3F; 7008141cc406Sopenharmony_ci Outb (CONTROL, gControl & 0xEF); 7009141cc406Sopenharmony_ci 7010141cc406Sopenharmony_ci 7011141cc406Sopenharmony_ci 7012141cc406Sopenharmony_ci if (sendCommand (0x40) == 0) 7013141cc406Sopenharmony_ci { 7014141cc406Sopenharmony_ci DBG (0, "sendCommand(0x40) (%s:%d) failed ...\n", __FILE__, __LINE__); 7015141cc406Sopenharmony_ci return 0; 7016141cc406Sopenharmony_ci } 7017141cc406Sopenharmony_ci DBG (16, "sendCommand(0x40) passed...\n"); 7018141cc406Sopenharmony_ci if (sendCommand (0xE0) == 0) 7019141cc406Sopenharmony_ci { 7020141cc406Sopenharmony_ci DBG (0, "sendCommand(0xE0) (%s:%d) failed ...\n", __FILE__, __LINE__); 7021141cc406Sopenharmony_ci return 0; 7022141cc406Sopenharmony_ci } 7023141cc406Sopenharmony_ci DBG (16, "sendCommand(0xE0) passed...\n"); 7024141cc406Sopenharmony_ci 7025141cc406Sopenharmony_ci ClearRegister (0); 7026141cc406Sopenharmony_ci DBG (16, "ClearRegister(0) passed...\n"); 7027141cc406Sopenharmony_ci 7028141cc406Sopenharmony_ci SPPResetLPT (); 7029141cc406Sopenharmony_ci DBG (16, "SPPResetLPT() passed...\n"); 7030141cc406Sopenharmony_ci 7031141cc406Sopenharmony_ci Outb (CONTROL, 4); 7032141cc406Sopenharmony_ci Outb (CONTROL, 4); 7033141cc406Sopenharmony_ci 7034141cc406Sopenharmony_ci 7035141cc406Sopenharmony_ci /* test PS2 mode */ 7036141cc406Sopenharmony_ci 7037141cc406Sopenharmony_ci tmp = PS2registerRead (0x0B); 7038141cc406Sopenharmony_ci if (tmp == 0xC7) 7039141cc406Sopenharmony_ci { 7040141cc406Sopenharmony_ci /* epat C7 detected */ 7041141cc406Sopenharmony_ci DBG (16, "PS2registerRead(0x0B)=0x%X passed...\n", tmp); 7042141cc406Sopenharmony_ci 7043141cc406Sopenharmony_ci PS2registerWrite (8, 0); 7044141cc406Sopenharmony_ci DBG (16, "PS2registerWrite(8,0) passed... (%s:%d)\n", __FILE__, 7045141cc406Sopenharmony_ci __LINE__); 7046141cc406Sopenharmony_ci 7047141cc406Sopenharmony_ci tmp = PS2registerRead (0x0A); 7048141cc406Sopenharmony_ci if (tmp != 0x00) 7049141cc406Sopenharmony_ci { 7050141cc406Sopenharmony_ci if (tmp == 0x1C) 7051141cc406Sopenharmony_ci { 7052141cc406Sopenharmony_ci DBG (16, "Previous probe detected ... (%s:%d)\n", __FILE__, 7053141cc406Sopenharmony_ci __LINE__); 7054141cc406Sopenharmony_ci } 7055141cc406Sopenharmony_ci else 7056141cc406Sopenharmony_ci { 7057141cc406Sopenharmony_ci DBG (0, "Found 0x%X expected 0x00 (%s:%d)\n", tmp, __FILE__, 7058141cc406Sopenharmony_ci __LINE__); 7059141cc406Sopenharmony_ci } 7060141cc406Sopenharmony_ci } 7061141cc406Sopenharmony_ci DBG (16, "PS2registerRead(0x0A)=0x%X passed ...(%s:%d)\n", tmp, 7062141cc406Sopenharmony_ci __FILE__, __LINE__); 7063141cc406Sopenharmony_ci 7064141cc406Sopenharmony_ci } 7065141cc406Sopenharmony_ci else 7066141cc406Sopenharmony_ci { 7067141cc406Sopenharmony_ci DBG (4, "Found 0x%X expected 0xC7 (%s:%d)\n", tmp, __FILE__, __LINE__); 7068141cc406Sopenharmony_ci if ((tmp == 0xFF) && (sanei_umax_pp_getparport () < 1)) 7069141cc406Sopenharmony_ci { 7070141cc406Sopenharmony_ci DBG (0, 7071141cc406Sopenharmony_ci "It is likely that the hardware address (0x%X) you specified is wrong\n", 7072141cc406Sopenharmony_ci gPort); 7073141cc406Sopenharmony_ci return 0; 7074141cc406Sopenharmony_ci } 7075141cc406Sopenharmony_ci /* probe for a 610p, since we can't detect an EPAT */ 7076141cc406Sopenharmony_ci DBG (1, "Trying 610p (%s:%d)\n", __FILE__, __LINE__); 7077141cc406Sopenharmony_ci return probe610p (recover); 7078141cc406Sopenharmony_ci } 7079141cc406Sopenharmony_ci 7080141cc406Sopenharmony_ci /* clear register 3 */ 7081141cc406Sopenharmony_ci ClearRegister (3); 7082141cc406Sopenharmony_ci DBG (16, "ClearRegister(3) passed...\n"); 7083141cc406Sopenharmony_ci 7084141cc406Sopenharmony_ci /* wait ? */ 7085141cc406Sopenharmony_ci i = 65535; 7086141cc406Sopenharmony_ci while (i > 0) 7087141cc406Sopenharmony_ci { 7088141cc406Sopenharmony_ci tmp = Inb (DATA); 7089141cc406Sopenharmony_ci tmp = Inb (DATA); 7090141cc406Sopenharmony_ci i--; 7091141cc406Sopenharmony_ci } 7092141cc406Sopenharmony_ci DBG (16, "FFFF in loop passed...\n"); 7093141cc406Sopenharmony_ci 7094141cc406Sopenharmony_ci ClearRegister (0); 7095141cc406Sopenharmony_ci DBG (16, "ClearRegister(0) passed... (%s:%d)\n", __FILE__, __LINE__); 7096141cc406Sopenharmony_ci fflush (stdout); 7097141cc406Sopenharmony_ci 7098141cc406Sopenharmony_ci /* 1220/2000P branch */ 7099141cc406Sopenharmony_ci WRITESLOW (0x0E, 1); 7100141cc406Sopenharmony_ci 7101141cc406Sopenharmony_ci /* register 0x0F used only once: model number ? Or ASIC revision ? */ 7102141cc406Sopenharmony_ci /* comm mode ? */ 7103141cc406Sopenharmony_ci model = PS2registerRead (0x0F); 7104141cc406Sopenharmony_ci DBG (1, "UMAX Astra 1220/1600/2000 P ASIC detected (mode=%d)\n", model); 7105141cc406Sopenharmony_ci setModel (model); 7106141cc406Sopenharmony_ci DBG (16, "PS2registerRead(0x0F) passed... (%s:%d)\n", __FILE__, __LINE__); 7107141cc406Sopenharmony_ci 7108141cc406Sopenharmony_ci /* scanner powered off */ 7109141cc406Sopenharmony_ci if (model == 0x1B) 7110141cc406Sopenharmony_ci { 7111141cc406Sopenharmony_ci DBG (0, "Register 0x0F=0x1B, scanner powered off ! (%s:%d)\n", __FILE__, 7112141cc406Sopenharmony_ci __LINE__); 7113141cc406Sopenharmony_ci return 0; 7114141cc406Sopenharmony_ci } 7115141cc406Sopenharmony_ci 7116141cc406Sopenharmony_ci 7117141cc406Sopenharmony_ci if ((model != 0x1F) && (model != 0x07)) 7118141cc406Sopenharmony_ci { 7119141cc406Sopenharmony_ci DBG 7120141cc406Sopenharmony_ci (0, 7121141cc406Sopenharmony_ci "Unexpected value for for register 0x0F, expected 0x07 or 0x1F, got 0x%02X ! (%s:%d)\n", 7122141cc406Sopenharmony_ci model, __FILE__, __LINE__); 7123141cc406Sopenharmony_ci DBG (0, "There is a new scanner revision in town, or a bug ....\n"); 7124141cc406Sopenharmony_ci } 7125141cc406Sopenharmony_ci 7126141cc406Sopenharmony_ci WRITESLOW (0x08, 0x02); 7127141cc406Sopenharmony_ci WRITESLOW (0x0E, 0x0F); 7128141cc406Sopenharmony_ci WRITESLOW (0x0F, 0x0C); 7129141cc406Sopenharmony_ci WRITESLOW (0x0C, 0x04); 7130141cc406Sopenharmony_ci tmp = PS2registerRead (0x0D); 7131141cc406Sopenharmony_ci if ((tmp != 0x00) && (tmp != 0x40)) 7132141cc406Sopenharmony_ci { 7133141cc406Sopenharmony_ci DBG 7134141cc406Sopenharmony_ci (0, 7135141cc406Sopenharmony_ci "Unexpected value for for register 0x0D, expected 0x00 or 0x40, got 0x%02X ! (%s:%d)\n", 7136141cc406Sopenharmony_ci tmp, __FILE__, __LINE__); 7137141cc406Sopenharmony_ci } 7138141cc406Sopenharmony_ci WRITESLOW (0x0D, 0x1B); 7139141cc406Sopenharmony_ci switch (model) 7140141cc406Sopenharmony_ci { 7141141cc406Sopenharmony_ci case 0x1F: 7142141cc406Sopenharmony_ci WRITESLOW (0x12, 0x14); 7143141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x12, 0x10); 7144141cc406Sopenharmony_ci break; 7145141cc406Sopenharmony_ci case 0x07: 7146141cc406Sopenharmony_ci WRITESLOW (0x12, 0x00); 7147141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x12, 0x00); 7148141cc406Sopenharmony_ci /* we may get 0x20, in this case some color aberration may occur */ 7149141cc406Sopenharmony_ci /* must depend on the parport */ 7150141cc406Sopenharmony_ci /* model 0x07 + 0x00=>0x20=2000P */ 7151141cc406Sopenharmony_ci break; 7152141cc406Sopenharmony_ci default: 7153141cc406Sopenharmony_ci WRITESLOW (0x12, 0x00); 7154141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x12, 0x20); 7155141cc406Sopenharmony_ci break; 7156141cc406Sopenharmony_ci } 7157141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0D, 0x18); 7158141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0C, 0x04); 7159141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0A, 0x00); 7160141cc406Sopenharmony_ci WRITESLOW (0x0E, 0x0A); 7161141cc406Sopenharmony_ci WRITESLOW (0x0F, 0x00); 7162141cc406Sopenharmony_ci WRITESLOW (0x0E, 0x0D); 7163141cc406Sopenharmony_ci WRITESLOW (0x0F, 0x00); 7164141cc406Sopenharmony_ci dest = (unsigned char *) malloc (65536); 7165141cc406Sopenharmony_ci if (dest == NULL) 7166141cc406Sopenharmony_ci { 7167141cc406Sopenharmony_ci DBG (0, "Failed to allocate 64K (%s:%d)\n", __FILE__, __LINE__); 7168141cc406Sopenharmony_ci return 0; 7169141cc406Sopenharmony_ci } 7170141cc406Sopenharmony_ci 7171141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_PS2; 7172141cc406Sopenharmony_ci if (probePS2 (dest)) 7173141cc406Sopenharmony_ci { /* PS2 mode works */ 7174141cc406Sopenharmony_ci DBG (16, "probePS2 passed ... (%s:%d)\n", __FILE__, __LINE__); 7175141cc406Sopenharmony_ci gprobed = UMAX_PP_PARPORT_PS2; 7176141cc406Sopenharmony_ci } 7177141cc406Sopenharmony_ci 7178141cc406Sopenharmony_ci Outb (CONTROL, 4); 7179141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0A, 0x18); 7180141cc406Sopenharmony_ci WRITESLOW (0x08, 0x40); 7181141cc406Sopenharmony_ci WRITESLOW (0x08, 0x60); 7182141cc406Sopenharmony_ci WRITESLOW (0x08, 0x22); 7183141cc406Sopenharmony_ci 7184141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_EPP; 7185141cc406Sopenharmony_ci if (probeEPP (dest)) 7186141cc406Sopenharmony_ci { /* EPP mode works */ 7187141cc406Sopenharmony_ci gprobed = UMAX_PP_PARPORT_EPP; 7188141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_EPP; 7189141cc406Sopenharmony_ci DBG (16, "probeEPP passed ... (%s:%d)\n", __FILE__, __LINE__); 7190141cc406Sopenharmony_ci } 7191141cc406Sopenharmony_ci else 7192141cc406Sopenharmony_ci { /* EPP fails, try ECP */ 7193141cc406Sopenharmony_ci DBG (16, "probeEPP failed ... (%s:%d)\n", __FILE__, __LINE__); 7194141cc406Sopenharmony_ci gMode = UMAX_PP_PARPORT_ECP; 7195141cc406Sopenharmony_ci if (probeECP (dest)) 7196141cc406Sopenharmony_ci { /* ECP mode works */ 7197141cc406Sopenharmony_ci DBG (16, "probeECP passed ... (%s:%d)\n", __FILE__, __LINE__); 7198141cc406Sopenharmony_ci gprobed = UMAX_PP_PARPORT_ECP; 7199141cc406Sopenharmony_ci } 7200141cc406Sopenharmony_ci else 7201141cc406Sopenharmony_ci { /* ECP and EPP fail, give up */ 7202141cc406Sopenharmony_ci /* PS2 could be used */ 7203141cc406Sopenharmony_ci DBG (16, "probeECP failed ... (%s:%d)\n", __FILE__, __LINE__); 7204141cc406Sopenharmony_ci DBG (1, "No EPP or ECP mode working, giving up ... (%s:%d)\n", 7205141cc406Sopenharmony_ci __FILE__, __LINE__); 7206141cc406Sopenharmony_ci free (dest); 7207141cc406Sopenharmony_ci return 0; 7208141cc406Sopenharmony_ci } 7209141cc406Sopenharmony_ci } 7210141cc406Sopenharmony_ci 7211141cc406Sopenharmony_ci /* some operations here may have to go into probeEPP/probeECP */ 7212141cc406Sopenharmony_ci g6FE = 1; 7213141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 7214141cc406Sopenharmony_ci { 7215141cc406Sopenharmony_ci WRITESLOW (0x08, 0x01); 7216141cc406Sopenharmony_ci Outb (CONTROL, 0x0C); 7217141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 7218141cc406Sopenharmony_ci ClearRegister (0); 7219141cc406Sopenharmony_ci tmp = PS2Something (0x10); 7220141cc406Sopenharmony_ci if (tmp != 0x0B) 7221141cc406Sopenharmony_ci { 7222141cc406Sopenharmony_ci DBG (0, 7223141cc406Sopenharmony_ci "PS2Something returned 0x%02X, 0x0B expected (%s:%d)\n", tmp, 7224141cc406Sopenharmony_ci __FILE__, __LINE__); 7225141cc406Sopenharmony_ci } 7226141cc406Sopenharmony_ci } 7227141cc406Sopenharmony_ci else 7228141cc406Sopenharmony_ci { 7229141cc406Sopenharmony_ci WRITESLOW (0x08, 0x21); 7230141cc406Sopenharmony_ci init001 (); 7231141cc406Sopenharmony_ci DBG (16, "init001() passed... (%s:%d)\n", __FILE__, __LINE__); 7232141cc406Sopenharmony_ci } 7233141cc406Sopenharmony_ci 7234141cc406Sopenharmony_ci 7235141cc406Sopenharmony_ci reg = registerRead (0x0D); 7236141cc406Sopenharmony_ci reg = (reg & 0xE8) | 0x43; 7237141cc406Sopenharmony_ci registerWrite (0x0D, reg); 7238141cc406Sopenharmony_ci 7239141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); 7240141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0F); 7241141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x0C); 7242141cc406Sopenharmony_ci 7243141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x1C); 7244141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x10); 7245141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x1C); 7246141cc406Sopenharmony_ci 7247141cc406Sopenharmony_ci 7248141cc406Sopenharmony_ci reg = registerRead (0x0D); /* 0x48 expected */ 7249141cc406Sopenharmony_ci reg = registerRead (0x0D); 7250141cc406Sopenharmony_ci reg = registerRead (0x0D); 7251141cc406Sopenharmony_ci reg = (reg & 0xB7) | 0x03; 7252141cc406Sopenharmony_ci registerWrite (0x0D, reg); 7253141cc406Sopenharmony_ci DBG (16, "(%s:%d) passed \n", __FILE__, __LINE__); 7254141cc406Sopenharmony_ci 7255141cc406Sopenharmony_ci reg = registerRead (0x12); /* 0x10 for model 0x0F, 0x20 for model 0x07 */ 7256141cc406Sopenharmony_ci /* 0x00 when in ECP mode ... */ 7257141cc406Sopenharmony_ci reg = reg & 0xEF; 7258141cc406Sopenharmony_ci registerWrite (0x12, reg); 7259141cc406Sopenharmony_ci DBG (16, "(%s:%d) passed \n", __FILE__, __LINE__); 7260141cc406Sopenharmony_ci 7261141cc406Sopenharmony_ci reg = registerRead (0x0A); 7262141cc406Sopenharmony_ci if (reg != 0x1C) 7263141cc406Sopenharmony_ci { 7264141cc406Sopenharmony_ci DBG (0, "Warning! expected reg0A=0x1C, found 0x%02X! (%s:%d) \n", reg, 7265141cc406Sopenharmony_ci __FILE__, __LINE__); 7266141cc406Sopenharmony_ci } 7267141cc406Sopenharmony_ci DBG (16, "(%s:%d) passed \n", __FILE__, __LINE__); 7268141cc406Sopenharmony_ci 7269141cc406Sopenharmony_ci /*Inb(CONTROL); ECP 0x04 expected */ 7270141cc406Sopenharmony_ci disconnect (); 7271141cc406Sopenharmony_ci DBG (16, "disconnect() passed... (%s:%d)\n", __FILE__, __LINE__); 7272141cc406Sopenharmony_ci connect (); 7273141cc406Sopenharmony_ci DBG (16, "connect() passed... (%s:%d)\n", __FILE__, __LINE__); 7274141cc406Sopenharmony_ci 7275141cc406Sopenharmony_ci 7276141cc406Sopenharmony_ci /* some sort of countdown, some warming-up ? */ 7277141cc406Sopenharmony_ci /* maybe some data sent to the stepper motor */ 7278141cc406Sopenharmony_ci /* if (model == 0x07) */ 7279141cc406Sopenharmony_ci { 7280141cc406Sopenharmony_ci /* REGISTERWRITE (0x0A, 0x00); 7281141cc406Sopenharmony_ci reg = registerRead (0x0D); 7282141cc406Sopenharmony_ci reg = (reg & 0xE8); 7283141cc406Sopenharmony_ci registerWrite (0x0D, reg); 7284141cc406Sopenharmony_ci DBG (16, "(%s:%d) passed \n", __FILE__, __LINE__); */ 7285141cc406Sopenharmony_ci epilogue (); 7286141cc406Sopenharmony_ci prologue (0x10); 7287141cc406Sopenharmony_ci 7288141cc406Sopenharmony_ci reg = registerRead (0x13); 7289141cc406Sopenharmony_ci if (reg != 0x00) 7290141cc406Sopenharmony_ci { 7291141cc406Sopenharmony_ci DBG (0, "Warning! expected reg13=0x00, found 0x%02X! (%s:%d) \n", 7292141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 7293141cc406Sopenharmony_ci } 7294141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x81); 7295141cc406Sopenharmony_ci usleep (10000); 7296141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x80); 7297141cc406Sopenharmony_ci /* could it be step-motor values ? */ 7298141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x04); /* FF->R04 */ 7299141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0xFF); 7300141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x05); /* 03->R05 */ 7301141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x03); 7302141cc406Sopenharmony_ci REGISTERWRITE (0x10, 0x66); 7303141cc406Sopenharmony_ci usleep (10000); 7304141cc406Sopenharmony_ci 7305141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x04); /* FF->R04 */ 7306141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0xFF); 7307141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x05); /* 01 ->R05 */ 7308141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x01); 7309141cc406Sopenharmony_ci REGISTERWRITE (0x10, 0x55); 7310141cc406Sopenharmony_ci usleep (10000); 7311141cc406Sopenharmony_ci 7312141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x04); /* FF -> R04 */ 7313141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0xFF); 7314141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x05); /* 00 -> R05 */ 7315141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 7316141cc406Sopenharmony_ci REGISTERWRITE (0x10, 0x44); 7317141cc406Sopenharmony_ci usleep (10000); 7318141cc406Sopenharmony_ci 7319141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x04); /* 7F -> R04 */ 7320141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x7F); 7321141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x05); /* 00 -> R05 */ 7322141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 7323141cc406Sopenharmony_ci REGISTERWRITE (0x10, 0x33); 7324141cc406Sopenharmony_ci usleep (10000); 7325141cc406Sopenharmony_ci 7326141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x04); /* 3F -> R04 */ 7327141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x3F); 7328141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x05); 7329141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); /* 00 -> R05 */ 7330141cc406Sopenharmony_ci REGISTERWRITE (0x10, 0x22); 7331141cc406Sopenharmony_ci usleep (10000); 7332141cc406Sopenharmony_ci 7333141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x04); 7334141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 7335141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x05); 7336141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 7337141cc406Sopenharmony_ci REGISTERWRITE (0x10, 0x11); 7338141cc406Sopenharmony_ci usleep (10000); 7339141cc406Sopenharmony_ci 7340141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x81); 7341141cc406Sopenharmony_ci usleep (10000); 7342141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x80); 7343141cc406Sopenharmony_ci 7344141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x04); 7345141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 7346141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x05); 7347141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 7348141cc406Sopenharmony_ci usleep (10000); 7349141cc406Sopenharmony_ci 7350141cc406Sopenharmony_ci reg = registerRead (0x10); 7351141cc406Sopenharmony_ci DBG (1, "Count-down value is 0x%02X (%s:%d)\n", reg, __FILE__, __LINE__); 7352141cc406Sopenharmony_ci /* 2 reports of CF, was FF first (typo ?) */ 7353141cc406Sopenharmony_ci /* CF seems a valid value */ 7354141cc406Sopenharmony_ci /* in case of CF, we may have timeout ... */ 7355141cc406Sopenharmony_ci /*if (reg != 0x00) 7356141cc406Sopenharmony_ci { 7357141cc406Sopenharmony_ci DBG (0, "Warning! expected reg10=0x00, found 0x%02X! (%s:%d) \n", 7358141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 7359141cc406Sopenharmony_ci } */ 7360141cc406Sopenharmony_ci REGISTERWRITE (0x13, 0x00); 7361141cc406Sopenharmony_ci } 7362141cc406Sopenharmony_ci/* end of countdown */ 7363141cc406Sopenharmony_ci DBG (16, "(%s:%d) passed \n", __FILE__, __LINE__); 7364141cc406Sopenharmony_ci /* *NOT* epilogue(); (when EPP) */ 7365141cc406Sopenharmony_ci /*REGISTERWRITE (0x0A, 0x00); 7366141cc406Sopenharmony_ci REGISTERREAD (0x0D, 0x40); 7367141cc406Sopenharmony_ci REGISTERWRITE (0x0D, 0x00); */ 7368141cc406Sopenharmony_ci epilogue (); 7369141cc406Sopenharmony_ci prologue (0x10); 7370141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0D); 7371141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 7372141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x1C); 7373141cc406Sopenharmony_ci 7374141cc406Sopenharmony_ci /* real start of high level protocol ? */ 7375141cc406Sopenharmony_ci if (fonc001 () != 1) 7376141cc406Sopenharmony_ci { 7377141cc406Sopenharmony_ci DBG (0, "fonc001() failed ! (%s:%d) \n", __FILE__, __LINE__); 7378141cc406Sopenharmony_ci return 0; 7379141cc406Sopenharmony_ci } 7380141cc406Sopenharmony_ci DBG (16, "fonc001() passed (%s:%d) \n", __FILE__, __LINE__); 7381141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xC8; 7382141cc406Sopenharmony_ci /* if reg=E8 or D8 , we have a 'messed' scanner */ 7383141cc406Sopenharmony_ci 7384141cc406Sopenharmony_ci /* 4 transform buffers + 'void' are sent: 1 B&W, and 3 RGB ? */ 7385141cc406Sopenharmony_ci memset (initbuf, 0x00, 2048 * sizeof (int)); 7386141cc406Sopenharmony_ci memset (voidbuf, 0x00, 2048 * sizeof (int)); 7387141cc406Sopenharmony_ci 7388141cc406Sopenharmony_ci initbuf[512] = 0xFF; 7389141cc406Sopenharmony_ci initbuf[513] = 0xAA; 7390141cc406Sopenharmony_ci initbuf[514] = 0x55; 7391141cc406Sopenharmony_ci 7392141cc406Sopenharmony_ci for (j = 0; j < 4; j++) 7393141cc406Sopenharmony_ci { 7394141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 7395141cc406Sopenharmony_ci { 7396141cc406Sopenharmony_ci voidbuf[512 * j + 2 * i] = i; 7397141cc406Sopenharmony_ci voidbuf[512 * j + 2 * i] = 0xFF - i; 7398141cc406Sopenharmony_ci } 7399141cc406Sopenharmony_ci } 7400141cc406Sopenharmony_ci 7401141cc406Sopenharmony_ci /* one pass (B&W ?) */ 7402141cc406Sopenharmony_ci if (cmdSetDataBuffer (initbuf) != 1) 7403141cc406Sopenharmony_ci { 7404141cc406Sopenharmony_ci DBG (0, "cmdSetDataBuffer(initbuf) failed ! (%s:%d) \n", __FILE__, 7405141cc406Sopenharmony_ci __LINE__); 7406141cc406Sopenharmony_ci return 0; 7407141cc406Sopenharmony_ci } 7408141cc406Sopenharmony_ci DBG (16, "cmdSetDataBuffer(initbuf) passed... (%s:%d)\n", __FILE__, 7409141cc406Sopenharmony_ci __LINE__); 7410141cc406Sopenharmony_ci if (cmdSetDataBuffer (voidbuf) != 1) 7411141cc406Sopenharmony_ci { 7412141cc406Sopenharmony_ci DBG (0, "cmdSetDataBuffer(voidbuf) failed ! (%s:%d) \n", __FILE__, 7413141cc406Sopenharmony_ci __LINE__); 7414141cc406Sopenharmony_ci return 0; 7415141cc406Sopenharmony_ci } 7416141cc406Sopenharmony_ci DBG (16, "cmdSetDataBuffer(voidbuf) passed... (%s:%d)\n", __FILE__, 7417141cc406Sopenharmony_ci __LINE__); 7418141cc406Sopenharmony_ci 7419141cc406Sopenharmony_ci /* everything above the FF 55 AA tag is 'void' */ 7420141cc406Sopenharmony_ci /* it seems that the buffer is reused and only the beginning is initialized */ 7421141cc406Sopenharmony_ci for (i = 515; i < 2048; i++) 7422141cc406Sopenharmony_ci initbuf[i] = voidbuf[i]; 7423141cc406Sopenharmony_ci 7424141cc406Sopenharmony_ci /* three pass (RGB ?) */ 7425141cc406Sopenharmony_ci for (i = 0; i < 3; i++) 7426141cc406Sopenharmony_ci { 7427141cc406Sopenharmony_ci if (cmdSetDataBuffer (initbuf) != 1) 7428141cc406Sopenharmony_ci { 7429141cc406Sopenharmony_ci DBG (0, "cmdSetDataBuffer(initbuf) failed ! (%s:%d) \n", __FILE__, 7430141cc406Sopenharmony_ci __LINE__); 7431141cc406Sopenharmony_ci return 0; 7432141cc406Sopenharmony_ci } 7433141cc406Sopenharmony_ci DBG (16, "Loop %d: cmdSetDataBuffer(initbuf) passed... (%s:%d)\n", i, 7434141cc406Sopenharmony_ci __FILE__, __LINE__); 7435141cc406Sopenharmony_ci if (cmdSetDataBuffer (voidbuf) != 1) 7436141cc406Sopenharmony_ci { 7437141cc406Sopenharmony_ci DBG (0, "Loop %d: cmdSetDataBuffer(voidbuf) failed ! (%s:%d) \n", i, 7438141cc406Sopenharmony_ci __FILE__, __LINE__); 7439141cc406Sopenharmony_ci return 0; 7440141cc406Sopenharmony_ci } 7441141cc406Sopenharmony_ci } 7442141cc406Sopenharmony_ci 7443141cc406Sopenharmony_ci 7444141cc406Sopenharmony_ci /* memory size testing ? */ 7445141cc406Sopenharmony_ci /* load 150 Ko in scanner */ 7446141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x00); 7447141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x0C); 7448141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x00); 7449141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x0C); 7450141cc406Sopenharmony_ci 7451141cc406Sopenharmony_ci 7452141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x11); /* start */ 7453141cc406Sopenharmony_ci nb = 150; 7454141cc406Sopenharmony_ci for (i = 0; i < nb; i++) /* 300 for ECP ??? */ 7455141cc406Sopenharmony_ci { 7456141cc406Sopenharmony_ci bufferWrite (0x400, dest); 7457141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferWrite(0x400,dest) passed... (%s:%d)\n", i, 7458141cc406Sopenharmony_ci __FILE__, __LINE__); 7459141cc406Sopenharmony_ci } 7460141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); /* end */ 7461141cc406Sopenharmony_ci 7462141cc406Sopenharmony_ci /* read them back */ 7463141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x11); /*start transfer */ 7464141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 7465141cc406Sopenharmony_ci { 7466141cc406Sopenharmony_ci ECPSetBuffer (0x400); 7467141cc406Sopenharmony_ci } 7468141cc406Sopenharmony_ci 7469141cc406Sopenharmony_ci for (i = 0; i < nb; i++) /* 300 for ECP ??? */ 7470141cc406Sopenharmony_ci { 7471141cc406Sopenharmony_ci bufferRead (0x400, dest); 7472141cc406Sopenharmony_ci DBG (16, "Loop %d: bufferRead(0x400,dest) passed... (%s:%d)\n", i, 7473141cc406Sopenharmony_ci __FILE__, __LINE__); 7474141cc406Sopenharmony_ci } 7475141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x18); /*end transfer */ 7476141cc406Sopenharmony_ci 7477141cc406Sopenharmony_ci /* fully disconnect, then reconnect */ 7478141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 7479141cc406Sopenharmony_ci { 7480141cc406Sopenharmony_ci epilogue (); 7481141cc406Sopenharmony_ci sendCommand (0xE0); 7482141cc406Sopenharmony_ci Outb (DATA, 0xFF); 7483141cc406Sopenharmony_ci Outb (DATA, 0xFF); 7484141cc406Sopenharmony_ci ClearRegister (0); 7485141cc406Sopenharmony_ci WRITESLOW (0x0E, 0x0A); 7486141cc406Sopenharmony_ci SLOWNIBBLEREGISTERREAD (0x0F, 0x00); 7487141cc406Sopenharmony_ci WRITESLOW (0x0F, 0x08); 7488141cc406Sopenharmony_ci WRITESLOW (0x08, 0x10); /* 0x10 ?? */ 7489141cc406Sopenharmony_ci prologue (0x10); 7490141cc406Sopenharmony_ci } 7491141cc406Sopenharmony_ci 7492141cc406Sopenharmony_ci 7493141cc406Sopenharmony_ci /* almost cmdSync(0x00) which halts any pending operation */ 7494141cc406Sopenharmony_ci if (fonc001 () != 1) 7495141cc406Sopenharmony_ci { 7496141cc406Sopenharmony_ci DBG (0, "fonc001() failed ! (%s:%d) \n", __FILE__, __LINE__); 7497141cc406Sopenharmony_ci return 0; 7498141cc406Sopenharmony_ci } 7499141cc406Sopenharmony_ci DBG (16, "Fct001() passed (%s:%d) \n", __FILE__, __LINE__); 7500141cc406Sopenharmony_ci if (sendWord (zero) == 0) 7501141cc406Sopenharmony_ci { 7502141cc406Sopenharmony_ci DBG (0, "sendWord(zero) failed (%s:%d)\n", __FILE__, __LINE__); 7503141cc406Sopenharmony_ci return 0; 7504141cc406Sopenharmony_ci } 7505141cc406Sopenharmony_ci epilogue (); 7506141cc406Sopenharmony_ci DBG (16, "sendWord(zero) passed (%s:%d)\n", __FILE__, __LINE__); 7507141cc406Sopenharmony_ci 7508141cc406Sopenharmony_ci 7509141cc406Sopenharmony_ci /* end transport init */ 7510141cc406Sopenharmony_ci /* now high level (connected) protocol begins */ 7511141cc406Sopenharmony_ci val = sanei_umax_pp_initScanner (recover); 7512141cc406Sopenharmony_ci if (val == 0) 7513141cc406Sopenharmony_ci { 7514141cc406Sopenharmony_ci DBG (0, "initScanner() failed (%s:%d)\n", __FILE__, __LINE__); 7515141cc406Sopenharmony_ci return 0; 7516141cc406Sopenharmony_ci } 7517141cc406Sopenharmony_ci 7518141cc406Sopenharmony_ci 7519141cc406Sopenharmony_ci /* if no homing .... */ 7520141cc406Sopenharmony_ci if (val == 1) 7521141cc406Sopenharmony_ci { 7522141cc406Sopenharmony_ci CMDSYNC (0); 7523141cc406Sopenharmony_ci CMDSYNC (0xC2); 7524141cc406Sopenharmony_ci CMDSYNC (0); 7525141cc406Sopenharmony_ci } 7526141cc406Sopenharmony_ci 7527141cc406Sopenharmony_ci /* set port to its initial state */ 7528141cc406Sopenharmony_ci Outb (DATA, gData); 7529141cc406Sopenharmony_ci Outb (CONTROL, gControl); 7530141cc406Sopenharmony_ci 7531141cc406Sopenharmony_ci free (dest); 7532141cc406Sopenharmony_ci DBG (1, "probe done ...\n"); 7533141cc406Sopenharmony_ci return 1; 7534141cc406Sopenharmony_ci} 7535141cc406Sopenharmony_ci 7536141cc406Sopenharmony_ci 7537141cc406Sopenharmony_cistatic int 7538141cc406Sopenharmony_cidisconnect_epat (void) 7539141cc406Sopenharmony_ci{ 7540141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x00); 7541141cc406Sopenharmony_ci registerRead (0x0D); 7542141cc406Sopenharmony_ci REGISTERWRITE (0x0D, 0x00); 7543141cc406Sopenharmony_ci disconnect (); 7544141cc406Sopenharmony_ci return 1; 7545141cc406Sopenharmony_ci} 7546141cc406Sopenharmony_ci 7547141cc406Sopenharmony_ci 7548141cc406Sopenharmony_cistatic int 7549141cc406Sopenharmony_ciconnect_epat (int r08) 7550141cc406Sopenharmony_ci{ 7551141cc406Sopenharmony_ci int reg; 7552141cc406Sopenharmony_ci 7553141cc406Sopenharmony_ci if (connect () != 1) 7554141cc406Sopenharmony_ci { 7555141cc406Sopenharmony_ci DBG (0, "connect_epat: connect() failed! (%s:%d)\n", __FILE__, 7556141cc406Sopenharmony_ci __LINE__); 7557141cc406Sopenharmony_ci return 0; 7558141cc406Sopenharmony_ci } 7559141cc406Sopenharmony_ci 7560141cc406Sopenharmony_ci reg = registerRead (0x0B); 7561141cc406Sopenharmony_ci if (reg != gEPAT) 7562141cc406Sopenharmony_ci { 7563141cc406Sopenharmony_ci /* ASIC version is not */ 7564141cc406Sopenharmony_ci /* the one expected (epat c7) */ 7565141cc406Sopenharmony_ci DBG (0, "Error! expected reg0B=0x%02X, found 0x%02X! (%s:%d) \n", gEPAT, 7566141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 7567141cc406Sopenharmony_ci /* we try to clean all */ 7568141cc406Sopenharmony_ci disconnect (); 7569141cc406Sopenharmony_ci return 0; 7570141cc406Sopenharmony_ci } 7571141cc406Sopenharmony_ci reg = registerRead (0x0D); 7572141cc406Sopenharmony_ci reg = (reg | 0x43) & 0xEB; 7573141cc406Sopenharmony_ci REGISTERWRITE (0x0D, reg); 7574141cc406Sopenharmony_ci REGISTERWRITE (0x0C, 0x04); 7575141cc406Sopenharmony_ci reg = registerRead (0x0A); 7576141cc406Sopenharmony_ci if (reg != 0x00) 7577141cc406Sopenharmony_ci { 7578141cc406Sopenharmony_ci /* a previous unfinished command */ 7579141cc406Sopenharmony_ci /* has left an uncleared value */ 7580141cc406Sopenharmony_ci DBG (0, "Warning! expected reg0A=0x00, found 0x%02X! (%s:%d) \n", reg, 7581141cc406Sopenharmony_ci __FILE__, __LINE__); 7582141cc406Sopenharmony_ci } 7583141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x1C); 7584141cc406Sopenharmony_ci if (r08 != 0) 7585141cc406Sopenharmony_ci { 7586141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 7587141cc406Sopenharmony_ci { 7588141cc406Sopenharmony_ci REGISTERWRITE (0x08, r08); /* 0x01 or 0x10 ??? */ 7589141cc406Sopenharmony_ci } 7590141cc406Sopenharmony_ci else 7591141cc406Sopenharmony_ci { 7592141cc406Sopenharmony_ci REGISTERWRITE (0x08, 0x21); 7593141cc406Sopenharmony_ci } 7594141cc406Sopenharmony_ci } 7595141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0F); 7596141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x0C); 7597141cc406Sopenharmony_ci REGISTERWRITE (0x0A, 0x1C); 7598141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x10); 7599141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x1C); 7600141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 7601141cc406Sopenharmony_ci { 7602141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 7603141cc406Sopenharmony_ci } 7604141cc406Sopenharmony_ci return 1; 7605141cc406Sopenharmony_ci} 7606141cc406Sopenharmony_ci 7607141cc406Sopenharmony_ci 7608141cc406Sopenharmony_cistatic int 7609141cc406Sopenharmony_ciprologue (int r08) 7610141cc406Sopenharmony_ci{ 7611141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 7612141cc406Sopenharmony_ci { 7613141cc406Sopenharmony_ci case 610: 7614141cc406Sopenharmony_ci connect610p (); 7615141cc406Sopenharmony_ci return sync610p (); 7616141cc406Sopenharmony_ci case 1220: 7617141cc406Sopenharmony_ci case 1600: 7618141cc406Sopenharmony_ci case 2000: 7619141cc406Sopenharmony_ci default: 7620141cc406Sopenharmony_ci return connect_epat (r08); 7621141cc406Sopenharmony_ci } 7622141cc406Sopenharmony_ci} 7623141cc406Sopenharmony_ci 7624141cc406Sopenharmony_ci 7625141cc406Sopenharmony_ci 7626141cc406Sopenharmony_cistatic int 7627141cc406Sopenharmony_ciepilogue (void) 7628141cc406Sopenharmony_ci{ 7629141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 7630141cc406Sopenharmony_ci { 7631141cc406Sopenharmony_ci case 610: 7632141cc406Sopenharmony_ci return disconnect610p (); 7633141cc406Sopenharmony_ci case 1220: 7634141cc406Sopenharmony_ci case 1600: 7635141cc406Sopenharmony_ci case 2000: 7636141cc406Sopenharmony_ci default: 7637141cc406Sopenharmony_ci return disconnect_epat (); 7638141cc406Sopenharmony_ci } 7639141cc406Sopenharmony_ci} 7640141cc406Sopenharmony_ci 7641141cc406Sopenharmony_ci 7642141cc406Sopenharmony_cistatic int 7643141cc406Sopenharmony_ciEPPcmdGet610p (int cmd, int len, int *val) 7644141cc406Sopenharmony_ci{ 7645141cc406Sopenharmony_ci int word[4]; 7646141cc406Sopenharmony_ci int i, status, control; 7647141cc406Sopenharmony_ci 7648141cc406Sopenharmony_ci word[0] = len / 65536; 7649141cc406Sopenharmony_ci word[1] = len / 256 % 256; 7650141cc406Sopenharmony_ci word[2] = len % 256; 7651141cc406Sopenharmony_ci word[3] = (cmd & 0x3F) | 0x80 | 0x40; /* 0x40 means 'read' */ 7652141cc406Sopenharmony_ci 7653141cc406Sopenharmony_ci connect610p (); 7654141cc406Sopenharmony_ci sync610p (); 7655141cc406Sopenharmony_ci 7656141cc406Sopenharmony_ci /* sends magic seal 55 AA */ 7657141cc406Sopenharmony_ci status = EPPputByte610p (0x55); 7658141cc406Sopenharmony_ci if (status != 0xC8) 7659141cc406Sopenharmony_ci { 7660141cc406Sopenharmony_ci DBG (1, "EPPcmdGet610p: Found 0x%X expected 0xC8 (%s:%d)\n", status, 7661141cc406Sopenharmony_ci __FILE__, __LINE__); 7662141cc406Sopenharmony_ci return 0; 7663141cc406Sopenharmony_ci } 7664141cc406Sopenharmony_ci status = EPPputByte610p (0xAA); 7665141cc406Sopenharmony_ci if (status != 0xC8) 7666141cc406Sopenharmony_ci { 7667141cc406Sopenharmony_ci DBG (1, "EPPcmdGet610p: Found 0x%02X expected 0xC8 (%s:%d)\n", status, 7668141cc406Sopenharmony_ci __FILE__, __LINE__); 7669141cc406Sopenharmony_ci return 0; 7670141cc406Sopenharmony_ci } 7671141cc406Sopenharmony_ci 7672141cc406Sopenharmony_ci /* tests status */ 7673141cc406Sopenharmony_ci /* scannerStatus=0x58 */ 7674141cc406Sopenharmony_ci status = EPPgetStatus610p (); 7675141cc406Sopenharmony_ci if (status != 0xC8) 7676141cc406Sopenharmony_ci { 7677141cc406Sopenharmony_ci DBG (1, 7678141cc406Sopenharmony_ci "EPPcmdGet610p: Found 0x%X expected 0xC8, status=0x%02X (%s:%d)\n", 7679141cc406Sopenharmony_ci status, scannerStatus, __FILE__, __LINE__); 7680141cc406Sopenharmony_ci return 0; 7681141cc406Sopenharmony_ci } 7682141cc406Sopenharmony_ci 7683141cc406Sopenharmony_ci 7684141cc406Sopenharmony_ci /* sends length of data */ 7685141cc406Sopenharmony_ci for (i = 0; (i < 4) && (status == 0xC8); i++) 7686141cc406Sopenharmony_ci { 7687141cc406Sopenharmony_ci status = EPPputByte610p (word[i]); 7688141cc406Sopenharmony_ci } 7689141cc406Sopenharmony_ci if (status != 0xC8) 7690141cc406Sopenharmony_ci { 7691141cc406Sopenharmony_ci DBG (1, "EPPcmdGet610p: loop %d, found 0x%02X expected 0xC8 (%s:%d)\n", 7692141cc406Sopenharmony_ci i, status, __FILE__, __LINE__); 7693141cc406Sopenharmony_ci return 0; 7694141cc406Sopenharmony_ci } 7695141cc406Sopenharmony_ci 7696141cc406Sopenharmony_ci Outb (DATA, 0xFF); 7697141cc406Sopenharmony_ci 7698141cc406Sopenharmony_ci /* tests status */ 7699141cc406Sopenharmony_ci /* scannerStatus=0x58 */ 7700141cc406Sopenharmony_ci status = EPPgetStatus610p (); 7701141cc406Sopenharmony_ci if (status != 0xD0) 7702141cc406Sopenharmony_ci { 7703141cc406Sopenharmony_ci DBG (1, 7704141cc406Sopenharmony_ci "EPPcmdGet610p: Found 0x%X expected 0xD0, status=0x%02X (%s:%d)\n", 7705141cc406Sopenharmony_ci status, scannerStatus, __FILE__, __LINE__); 7706141cc406Sopenharmony_ci return 0; 7707141cc406Sopenharmony_ci } 7708141cc406Sopenharmony_ci 7709141cc406Sopenharmony_ci /* data reverse */ 7710141cc406Sopenharmony_ci control = Inb (CONTROL) & 0xF4; 7711141cc406Sopenharmony_ci control = control | 0xA0; 7712141cc406Sopenharmony_ci 7713141cc406Sopenharmony_ci /* receive data */ 7714141cc406Sopenharmony_ci i = 0; 7715141cc406Sopenharmony_ci while (i < len) 7716141cc406Sopenharmony_ci { 7717141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 7718141cc406Sopenharmony_ci if (status & 0x08) 7719141cc406Sopenharmony_ci { 7720141cc406Sopenharmony_ci DBG (1, 7721141cc406Sopenharmony_ci "EPPcmdGet610p: loop %d, found 0x%X expected 0xD0 or 0xC0 (%s:%d)\n", 7722141cc406Sopenharmony_ci i, status, __FILE__, __LINE__); 7723141cc406Sopenharmony_ci return 0; 7724141cc406Sopenharmony_ci } 7725141cc406Sopenharmony_ci val[i] = Inb (EPPDATA); 7726141cc406Sopenharmony_ci i++; 7727141cc406Sopenharmony_ci } 7728141cc406Sopenharmony_ci 7729141cc406Sopenharmony_ci if (DBG_LEVEL >= 8) 7730141cc406Sopenharmony_ci { 7731141cc406Sopenharmony_ci char *str = NULL; 7732141cc406Sopenharmony_ci 7733141cc406Sopenharmony_ci str = malloc (3 * len + 1); 7734141cc406Sopenharmony_ci if (str != NULL) 7735141cc406Sopenharmony_ci { 7736141cc406Sopenharmony_ci for (i = 0; i < len; i++) 7737141cc406Sopenharmony_ci { 7738141cc406Sopenharmony_ci sprintf (str + 3 * i, "%02X ", val[i]); 7739141cc406Sopenharmony_ci } 7740141cc406Sopenharmony_ci str[3 * i] = 0x00; 7741141cc406Sopenharmony_ci DBG (8, "String received for %02X: %s\n", cmd, str); 7742141cc406Sopenharmony_ci free (str); 7743141cc406Sopenharmony_ci } 7744141cc406Sopenharmony_ci else 7745141cc406Sopenharmony_ci { 7746141cc406Sopenharmony_ci TRACE (8, "not enough memory for debugging ..."); 7747141cc406Sopenharmony_ci } 7748141cc406Sopenharmony_ci } 7749141cc406Sopenharmony_ci 7750141cc406Sopenharmony_ci /* scannerStatus=0x58 */ 7751141cc406Sopenharmony_ci status = EPPgetStatus610p (); 7752141cc406Sopenharmony_ci scannerStatus = status; 7753141cc406Sopenharmony_ci if (status != 0xC0) 7754141cc406Sopenharmony_ci { 7755141cc406Sopenharmony_ci DBG (0, "EPPcmdGet610p: Found 0x%02X expected 0xC0 (%s:%d)\n", status, 7756141cc406Sopenharmony_ci __FILE__, __LINE__); 7757141cc406Sopenharmony_ci return 0; 7758141cc406Sopenharmony_ci } 7759141cc406Sopenharmony_ci disconnect610p (); 7760141cc406Sopenharmony_ci return 1; 7761141cc406Sopenharmony_ci} 7762141cc406Sopenharmony_ci 7763141cc406Sopenharmony_ci 7764141cc406Sopenharmony_ci 7765141cc406Sopenharmony_cistatic int 7766141cc406Sopenharmony_cicmdGet610p (int cmd, int len, int *val) 7767141cc406Sopenharmony_ci{ 7768141cc406Sopenharmony_ci int word[5]; 7769141cc406Sopenharmony_ci int i, j, status; 7770141cc406Sopenharmony_ci 7771141cc406Sopenharmony_ci if ((cmd == 8) && (len > 0x23)) 7772141cc406Sopenharmony_ci len = 0x23; 7773141cc406Sopenharmony_ci 7774141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 7775141cc406Sopenharmony_ci return EPPcmdGet610p (cmd, len, val); 7776141cc406Sopenharmony_ci 7777141cc406Sopenharmony_ci /* compute word */ 7778141cc406Sopenharmony_ci word[0] = len / 65536; 7779141cc406Sopenharmony_ci word[1] = len / 256 % 256; 7780141cc406Sopenharmony_ci word[2] = len % 256; 7781141cc406Sopenharmony_ci word[3] = (cmd & 0x3F) | 0x80 | 0x40; /* 0x40 means 'read' */ 7782141cc406Sopenharmony_ci word[4] = -1; 7783141cc406Sopenharmony_ci 7784141cc406Sopenharmony_ci connect610p (); 7785141cc406Sopenharmony_ci sync610p (); 7786141cc406Sopenharmony_ci if (sendLength610p (word) == 0) 7787141cc406Sopenharmony_ci { 7788141cc406Sopenharmony_ci DBG (0, "sendLength610p(word) failed... (%s:%d)\n", __FILE__, __LINE__); 7789141cc406Sopenharmony_ci return 0; 7790141cc406Sopenharmony_ci } 7791141cc406Sopenharmony_ci status = getStatus610p (); 7792141cc406Sopenharmony_ci scannerStatus = status; 7793141cc406Sopenharmony_ci if ((status != 0xC0) && (status != 0xD0)) 7794141cc406Sopenharmony_ci { 7795141cc406Sopenharmony_ci DBG (0, "Found 0x%02X expected 0xC0 or 0xD0 (%s:%d)\n", status, 7796141cc406Sopenharmony_ci __FILE__, __LINE__); 7797141cc406Sopenharmony_ci return 0; 7798141cc406Sopenharmony_ci } 7799141cc406Sopenharmony_ci if (receiveData610p (val, len) == 0) 7800141cc406Sopenharmony_ci { 7801141cc406Sopenharmony_ci DBG (0, "sendData610p(val,%d) failed (%s:%d)\n", len, __FILE__, 7802141cc406Sopenharmony_ci __LINE__); 7803141cc406Sopenharmony_ci return 0; 7804141cc406Sopenharmony_ci } 7805141cc406Sopenharmony_ci status = getStatus610p (); 7806141cc406Sopenharmony_ci scannerStatus = status; 7807141cc406Sopenharmony_ci j = 0; 7808141cc406Sopenharmony_ci while ((j < 256) && (status & 0x08)) 7809141cc406Sopenharmony_ci { 7810141cc406Sopenharmony_ci status = getStatus610p (); 7811141cc406Sopenharmony_ci j++; 7812141cc406Sopenharmony_ci } 7813141cc406Sopenharmony_ci if (status != 0xC0) 7814141cc406Sopenharmony_ci { 7815141cc406Sopenharmony_ci DBG (0, "Found 0x%02X expected 0xC0 (%s:%d)\n", status, __FILE__, 7816141cc406Sopenharmony_ci __LINE__); 7817141cc406Sopenharmony_ci return 0; 7818141cc406Sopenharmony_ci } 7819141cc406Sopenharmony_ci disconnect610p (); 7820141cc406Sopenharmony_ci 7821141cc406Sopenharmony_ci if (DBG_LEVEL >= 8) 7822141cc406Sopenharmony_ci { 7823141cc406Sopenharmony_ci char *str = NULL; 7824141cc406Sopenharmony_ci 7825141cc406Sopenharmony_ci str = malloc (3 * len + 1); 7826141cc406Sopenharmony_ci if (str != NULL) 7827141cc406Sopenharmony_ci { 7828141cc406Sopenharmony_ci for (i = 0; i < len; i++) 7829141cc406Sopenharmony_ci { 7830141cc406Sopenharmony_ci sprintf (str + 3 * i, "%02X ", val[i]); 7831141cc406Sopenharmony_ci } 7832141cc406Sopenharmony_ci str[3 * i] = 0x00; 7833141cc406Sopenharmony_ci DBG (8, "String received for %02X: %s\n", cmd, str); 7834141cc406Sopenharmony_ci free (str); 7835141cc406Sopenharmony_ci } 7836141cc406Sopenharmony_ci else 7837141cc406Sopenharmony_ci { 7838141cc406Sopenharmony_ci TRACE (8, "not enough memory for debugging ..."); 7839141cc406Sopenharmony_ci } 7840141cc406Sopenharmony_ci } 7841141cc406Sopenharmony_ci return 1; 7842141cc406Sopenharmony_ci} 7843141cc406Sopenharmony_ci 7844141cc406Sopenharmony_ci 7845141cc406Sopenharmony_cistatic int 7846141cc406Sopenharmony_ciEPPcmdSet610p (int cmd, int len, int *val) 7847141cc406Sopenharmony_ci{ 7848141cc406Sopenharmony_ci int word[5]; 7849141cc406Sopenharmony_ci int i, status; 7850141cc406Sopenharmony_ci 7851141cc406Sopenharmony_ci if ((cmd == 8) && (len > 0x23)) 7852141cc406Sopenharmony_ci { 7853141cc406Sopenharmony_ci /* blank useless extra bytes */ 7854141cc406Sopenharmony_ci for (i = 0x22; i < len; i++) 7855141cc406Sopenharmony_ci val[i] = 0x00; 7856141cc406Sopenharmony_ci } 7857141cc406Sopenharmony_ci 7858141cc406Sopenharmony_ci word[0] = len / 65536; 7859141cc406Sopenharmony_ci word[1] = len / 256 % 256; 7860141cc406Sopenharmony_ci word[2] = len % 256; 7861141cc406Sopenharmony_ci word[3] = (cmd & 0x3F) | 0x80; 7862141cc406Sopenharmony_ci 7863141cc406Sopenharmony_ci connect610p (); 7864141cc406Sopenharmony_ci sync610p (); 7865141cc406Sopenharmony_ci 7866141cc406Sopenharmony_ci /* sends magic seal 55 AA */ 7867141cc406Sopenharmony_ci status = EPPputByte610p (0x55); 7868141cc406Sopenharmony_ci if ((status != 0xC8) && (status!=0xC0)) 7869141cc406Sopenharmony_ci { 7870141cc406Sopenharmony_ci DBG (0, "EPPcmdSet610p: Found 0x%X expected 0xC0 or 0xC8 (%s:%d)\n", status, 7871141cc406Sopenharmony_ci __FILE__, __LINE__); 7872141cc406Sopenharmony_ci return 0; 7873141cc406Sopenharmony_ci } 7874141cc406Sopenharmony_ci status = EPPputByte610p (0xAA); 7875141cc406Sopenharmony_ci if ((status != 0xC8) && (status!=0xC0)) 7876141cc406Sopenharmony_ci { 7877141cc406Sopenharmony_ci DBG (0, "EPPcmdSet610p: Found 0x%X expected 0xC0 or 0xC8 (%s:%d)\n", status, 7878141cc406Sopenharmony_ci __FILE__, __LINE__); 7879141cc406Sopenharmony_ci return 0; 7880141cc406Sopenharmony_ci } 7881141cc406Sopenharmony_ci 7882141cc406Sopenharmony_ci /* tests status */ 7883141cc406Sopenharmony_ci status = EPPgetStatus610p (); 7884141cc406Sopenharmony_ci if ((status != 0xC8) && (status!=0xC0)) 7885141cc406Sopenharmony_ci { 7886141cc406Sopenharmony_ci DBG (0, "EPPcmdSet610p: Found 0x%02X expected 0xC0 or 0xC8 (%s:%d)\n", status, 7887141cc406Sopenharmony_ci __FILE__, __LINE__); 7888141cc406Sopenharmony_ci return 0; 7889141cc406Sopenharmony_ci } 7890141cc406Sopenharmony_ci 7891141cc406Sopenharmony_ci /* sends length of data */ 7892141cc406Sopenharmony_ci for (i = 0; i < 4; i++) 7893141cc406Sopenharmony_ci { 7894141cc406Sopenharmony_ci status = EPPputByte610p (word[i]); 7895141cc406Sopenharmony_ci } 7896141cc406Sopenharmony_ci if ((status != 0xC8) && (status!=0xC0)) 7897141cc406Sopenharmony_ci { 7898141cc406Sopenharmony_ci DBG (0, "EPPcmdSet610p: loop %d, found 0x%02X expected 0xC0 or 0xC8 (%s:%d)\n", 7899141cc406Sopenharmony_ci i, status, __FILE__, __LINE__); 7900141cc406Sopenharmony_ci return 0; 7901141cc406Sopenharmony_ci } 7902141cc406Sopenharmony_ci 7903141cc406Sopenharmony_ci Outb (DATA, 0xFF); 7904141cc406Sopenharmony_ci 7905141cc406Sopenharmony_ci /* tests status */ 7906141cc406Sopenharmony_ci status = EPPgetStatus610p (); 7907141cc406Sopenharmony_ci if (status != 0xC0) 7908141cc406Sopenharmony_ci { 7909141cc406Sopenharmony_ci DBG (0, "Found 0x%X expected 0xC0 (%s:%d)\n", status, __FILE__, 7910141cc406Sopenharmony_ci __LINE__); 7911141cc406Sopenharmony_ci return 0; 7912141cc406Sopenharmony_ci } 7913141cc406Sopenharmony_ci 7914141cc406Sopenharmony_ci /* sends data */ 7915141cc406Sopenharmony_ci status = 0xC8; 7916141cc406Sopenharmony_ci for (i = 0; (i < len) && (status == 0xC8); i++) 7917141cc406Sopenharmony_ci { 7918141cc406Sopenharmony_ci /* escape special values with ESC (0x1B) */ 7919141cc406Sopenharmony_ci if (val[i] == 0x1B) 7920141cc406Sopenharmony_ci status = EPPputByte610p (0x1B); 7921141cc406Sopenharmony_ci if (i > 0) 7922141cc406Sopenharmony_ci { 7923141cc406Sopenharmony_ci if ((val[i] == 0xAA) && (val[i - 1] == 0x55)) 7924141cc406Sopenharmony_ci status = EPPputByte610p (0x1B); 7925141cc406Sopenharmony_ci } 7926141cc406Sopenharmony_ci /* now send data */ 7927141cc406Sopenharmony_ci status = EPPputByte610p (val[i]); 7928141cc406Sopenharmony_ci } 7929141cc406Sopenharmony_ci 7930141cc406Sopenharmony_ci if (status != 0xC8) 7931141cc406Sopenharmony_ci { 7932141cc406Sopenharmony_ci DBG (0, "EPPcmdSet610p: loop %d, found 0x%02X expected 0xC8 (%s:%d)\n", 7933141cc406Sopenharmony_ci i, status, __FILE__, __LINE__); 7934141cc406Sopenharmony_ci return 0; 7935141cc406Sopenharmony_ci } 7936141cc406Sopenharmony_ci 7937141cc406Sopenharmony_ci Outb (DATA, 0xFF); 7938141cc406Sopenharmony_ci status = EPPgetStatus610p (); 7939141cc406Sopenharmony_ci if (status != 0xC0) 7940141cc406Sopenharmony_ci { 7941141cc406Sopenharmony_ci DBG (0, "Found 0x%X expected 0xC0 (%s:%d)\n", status, __FILE__, 7942141cc406Sopenharmony_ci __LINE__); 7943141cc406Sopenharmony_ci return 0; 7944141cc406Sopenharmony_ci } 7945141cc406Sopenharmony_ci 7946141cc406Sopenharmony_ci disconnect610p (); 7947141cc406Sopenharmony_ci return 1; 7948141cc406Sopenharmony_ci} 7949141cc406Sopenharmony_ci 7950141cc406Sopenharmony_ci 7951141cc406Sopenharmony_cistatic int 7952141cc406Sopenharmony_cicmdSet610p (int cmd, int len, int *val) 7953141cc406Sopenharmony_ci{ 7954141cc406Sopenharmony_ci int word[5]; 7955141cc406Sopenharmony_ci int i, j, status; 7956141cc406Sopenharmony_ci 7957141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 7958141cc406Sopenharmony_ci return EPPcmdSet610p (cmd, len, val); 7959141cc406Sopenharmony_ci 7960141cc406Sopenharmony_ci if ((cmd == 8) && (len > 0x23)) 7961141cc406Sopenharmony_ci { 7962141cc406Sopenharmony_ci /* blank useless extra bytes */ 7963141cc406Sopenharmony_ci for (i = 0x22; i < len; i++) 7964141cc406Sopenharmony_ci val[i] = 0x00; 7965141cc406Sopenharmony_ci } 7966141cc406Sopenharmony_ci 7967141cc406Sopenharmony_ci /* compute word */ 7968141cc406Sopenharmony_ci word[0] = len / 65536; 7969141cc406Sopenharmony_ci word[1] = len / 256 % 256; 7970141cc406Sopenharmony_ci word[2] = len % 256; 7971141cc406Sopenharmony_ci word[3] = (cmd & 0x3F) | 0x80; 7972141cc406Sopenharmony_ci word[4] = -1; 7973141cc406Sopenharmony_ci 7974141cc406Sopenharmony_ci connect610p (); 7975141cc406Sopenharmony_ci sync610p (); 7976141cc406Sopenharmony_ci if (sendLength610p (word) == 0) 7977141cc406Sopenharmony_ci { 7978141cc406Sopenharmony_ci DBG (0, "sendLength610p(word) failed... (%s:%d)\n", __FILE__, __LINE__); 7979141cc406Sopenharmony_ci return 0; 7980141cc406Sopenharmony_ci } 7981141cc406Sopenharmony_ci status = getStatus610p (); 7982141cc406Sopenharmony_ci scannerStatus = status; 7983141cc406Sopenharmony_ci if ((status != 0xC0) && (status != 0xD0)) 7984141cc406Sopenharmony_ci { 7985141cc406Sopenharmony_ci DBG (1, "Found 0x%X expected 0xC0 or 0xD0 (%s:%d)\n", status, __FILE__, 7986141cc406Sopenharmony_ci __LINE__); 7987141cc406Sopenharmony_ci return 0; 7988141cc406Sopenharmony_ci } 7989141cc406Sopenharmony_ci if (sendData610p (val, len) == 0) 7990141cc406Sopenharmony_ci { 7991141cc406Sopenharmony_ci DBG (1, "sendData610p(val,%d) failed (%s:%d)\n", len, __FILE__, 7992141cc406Sopenharmony_ci __LINE__); 7993141cc406Sopenharmony_ci return 0; 7994141cc406Sopenharmony_ci } 7995141cc406Sopenharmony_ci status = getStatus610p (); 7996141cc406Sopenharmony_ci scannerStatus = status; 7997141cc406Sopenharmony_ci j = 0; 7998141cc406Sopenharmony_ci while ((j < 256) && (status & 0x08)) 7999141cc406Sopenharmony_ci { 8000141cc406Sopenharmony_ci status = getStatus610p (); 8001141cc406Sopenharmony_ci j++; 8002141cc406Sopenharmony_ci } 8003141cc406Sopenharmony_ci if (status != 0xC0) 8004141cc406Sopenharmony_ci { 8005141cc406Sopenharmony_ci DBG (1, "Found 0x%X expected 0xC0 (%s:%d)\n", status, __FILE__, 8006141cc406Sopenharmony_ci __LINE__); 8007141cc406Sopenharmony_ci /* return 0; */ 8008141cc406Sopenharmony_ci } 8009141cc406Sopenharmony_ci disconnect610p (); 8010141cc406Sopenharmony_ci return 1; 8011141cc406Sopenharmony_ci} 8012141cc406Sopenharmony_ci 8013141cc406Sopenharmony_cistatic int 8014141cc406Sopenharmony_cicmdSet (int cmd, int len, int *val) 8015141cc406Sopenharmony_ci{ 8016141cc406Sopenharmony_ci int word[5]; 8017141cc406Sopenharmony_ci int i; 8018141cc406Sopenharmony_ci 8019141cc406Sopenharmony_ci if (DBG_LEVEL >= 8) 8020141cc406Sopenharmony_ci { 8021141cc406Sopenharmony_ci char *str = NULL; 8022141cc406Sopenharmony_ci 8023141cc406Sopenharmony_ci str = malloc (3 * len + 1); 8024141cc406Sopenharmony_ci if (str != NULL) 8025141cc406Sopenharmony_ci { 8026141cc406Sopenharmony_ci for (i = 0; i < len; i++) 8027141cc406Sopenharmony_ci { 8028141cc406Sopenharmony_ci sprintf (str + 3 * i, "%02X ", val[i]); 8029141cc406Sopenharmony_ci } 8030141cc406Sopenharmony_ci str[3 * i] = 0x00; 8031141cc406Sopenharmony_ci DBG (8, "String sent for %02X: %s\n", cmd, str); 8032141cc406Sopenharmony_ci free (str); 8033141cc406Sopenharmony_ci } 8034141cc406Sopenharmony_ci else 8035141cc406Sopenharmony_ci { 8036141cc406Sopenharmony_ci TRACE (8, "not enough memory for debugging ..."); 8037141cc406Sopenharmony_ci } 8038141cc406Sopenharmony_ci } 8039141cc406Sopenharmony_ci 8040141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 8041141cc406Sopenharmony_ci return cmdSet610p (cmd, len, val); 8042141cc406Sopenharmony_ci 8043141cc406Sopenharmony_ci /* cmd 08 as 2 length depending upon model */ 8044141cc406Sopenharmony_ci if ((cmd == 8) && (getModel () == 0x07)) 8045141cc406Sopenharmony_ci { 8046141cc406Sopenharmony_ci len = 35; 8047141cc406Sopenharmony_ci } 8048141cc406Sopenharmony_ci 8049141cc406Sopenharmony_ci /* compute word */ 8050141cc406Sopenharmony_ci word[0] = len / 65536; 8051141cc406Sopenharmony_ci word[1] = len / 256 % 256; 8052141cc406Sopenharmony_ci word[2] = len % 256; 8053141cc406Sopenharmony_ci word[3] = (cmd & 0x3F) | 0x80; 8054141cc406Sopenharmony_ci 8055141cc406Sopenharmony_ci if (!prologue (0x10)) 8056141cc406Sopenharmony_ci { 8057141cc406Sopenharmony_ci DBG (0, "cmdSet: prologue failed ! (%s:%d)\n", __FILE__, __LINE__); 8058141cc406Sopenharmony_ci return 0; 8059141cc406Sopenharmony_ci } 8060141cc406Sopenharmony_ci 8061141cc406Sopenharmony_ci /* send data */ 8062141cc406Sopenharmony_ci if (sendLength (word, 4) == 0) 8063141cc406Sopenharmony_ci { 8064141cc406Sopenharmony_ci DBG (0, "sendLength(word,4) failed (%s:%d)\n", __FILE__, __LINE__); 8065141cc406Sopenharmony_ci return 0; 8066141cc406Sopenharmony_ci } 8067141cc406Sopenharmony_ci TRACE (16, "sendLength(word,4) passed ..."); 8068141cc406Sopenharmony_ci 8069141cc406Sopenharmony_ci /* head end */ 8070141cc406Sopenharmony_ci epilogue (); 8071141cc406Sopenharmony_ci 8072141cc406Sopenharmony_ci if (len > 0) 8073141cc406Sopenharmony_ci { 8074141cc406Sopenharmony_ci /* send body */ 8075141cc406Sopenharmony_ci if (!prologue (0x10)) 8076141cc406Sopenharmony_ci { 8077141cc406Sopenharmony_ci DBG (0, "cmdSet: prologue failed ! (%s:%d)\n", __FILE__, 8078141cc406Sopenharmony_ci __LINE__); 8079141cc406Sopenharmony_ci } 8080141cc406Sopenharmony_ci 8081141cc406Sopenharmony_ci /* send data */ 8082141cc406Sopenharmony_ci if (sendData (val, len) == 0) 8083141cc406Sopenharmony_ci { 8084141cc406Sopenharmony_ci DBG (0, "sendData(word,%d) failed (%s:%d)\n", len, __FILE__, 8085141cc406Sopenharmony_ci __LINE__); 8086141cc406Sopenharmony_ci epilogue (); 8087141cc406Sopenharmony_ci return 0; 8088141cc406Sopenharmony_ci } 8089141cc406Sopenharmony_ci TRACE (16, "sendData(val,len) passed ..."); 8090141cc406Sopenharmony_ci /* body end */ 8091141cc406Sopenharmony_ci epilogue (); 8092141cc406Sopenharmony_ci } 8093141cc406Sopenharmony_ci return 1; 8094141cc406Sopenharmony_ci} 8095141cc406Sopenharmony_ci 8096141cc406Sopenharmony_cistatic int 8097141cc406Sopenharmony_cicmdGet (int cmd, int len, int *val) 8098141cc406Sopenharmony_ci{ 8099141cc406Sopenharmony_ci int word[5]; 8100141cc406Sopenharmony_ci int i; 8101141cc406Sopenharmony_ci 8102141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 8103141cc406Sopenharmony_ci return cmdGet610p (cmd, len, val); 8104141cc406Sopenharmony_ci 8105141cc406Sopenharmony_ci /* cmd 08 as 2 length depending upon model */ 8106141cc406Sopenharmony_ci if ((cmd == 8) && (getModel () == 0x07)) 8107141cc406Sopenharmony_ci { 8108141cc406Sopenharmony_ci len = 35; 8109141cc406Sopenharmony_ci } 8110141cc406Sopenharmony_ci 8111141cc406Sopenharmony_ci /* compute word */ 8112141cc406Sopenharmony_ci word[0] = len / 65536; 8113141cc406Sopenharmony_ci word[1] = len / 256 % 256; 8114141cc406Sopenharmony_ci word[2] = len % 256; 8115141cc406Sopenharmony_ci word[3] = (cmd & 0x3F) | 0x80 | 0x40; /* 0x40 means 'read' */ 8116141cc406Sopenharmony_ci word[4] = -1; 8117141cc406Sopenharmony_ci 8118141cc406Sopenharmony_ci /* send header */ 8119141cc406Sopenharmony_ci if (!prologue (0x10)) 8120141cc406Sopenharmony_ci { 8121141cc406Sopenharmony_ci DBG (0, "cmdGet: prologue failed ! (%s:%d)\n", __FILE__, __LINE__); 8122141cc406Sopenharmony_ci return 0; 8123141cc406Sopenharmony_ci } 8124141cc406Sopenharmony_ci 8125141cc406Sopenharmony_ci /* send data */ 8126141cc406Sopenharmony_ci if (sendLength (word, 4) == 0) 8127141cc406Sopenharmony_ci { 8128141cc406Sopenharmony_ci DBG (0, "sendLength(word,4) failed (%s:%d)\n", __FILE__, __LINE__); 8129141cc406Sopenharmony_ci return 0; 8130141cc406Sopenharmony_ci } 8131141cc406Sopenharmony_ci TRACE (16, "sendLength(word,4) passed ..."); 8132141cc406Sopenharmony_ci 8133141cc406Sopenharmony_ci /* head end */ 8134141cc406Sopenharmony_ci epilogue (); 8135141cc406Sopenharmony_ci 8136141cc406Sopenharmony_ci 8137141cc406Sopenharmony_ci /* send header */ 8138141cc406Sopenharmony_ci if (!prologue (0x10)) 8139141cc406Sopenharmony_ci { 8140141cc406Sopenharmony_ci DBG (0, "cmdGet: prologue failed ! (%s:%d)\n", __FILE__, __LINE__); 8141141cc406Sopenharmony_ci return 0; 8142141cc406Sopenharmony_ci } 8143141cc406Sopenharmony_ci 8144141cc406Sopenharmony_ci /* get actual data */ 8145141cc406Sopenharmony_ci if (receiveData (val, len) == 0) 8146141cc406Sopenharmony_ci { 8147141cc406Sopenharmony_ci DBG (0, "receiveData(val,len) failed (%s:%d)\n", __FILE__, __LINE__); 8148141cc406Sopenharmony_ci epilogue (); 8149141cc406Sopenharmony_ci return 0; 8150141cc406Sopenharmony_ci } 8151141cc406Sopenharmony_ci if (DBG_LEVEL >= 8) 8152141cc406Sopenharmony_ci { 8153141cc406Sopenharmony_ci char *str = NULL; 8154141cc406Sopenharmony_ci 8155141cc406Sopenharmony_ci str = malloc (3 * len + 1); 8156141cc406Sopenharmony_ci if (str != NULL) 8157141cc406Sopenharmony_ci { 8158141cc406Sopenharmony_ci for (i = 0; i < len; i++) 8159141cc406Sopenharmony_ci { 8160141cc406Sopenharmony_ci sprintf (str + 3 * i, "%02X ", val[i]); 8161141cc406Sopenharmony_ci } 8162141cc406Sopenharmony_ci str[3 * i] = 0x00; 8163141cc406Sopenharmony_ci DBG (8, "String received for %02X: %s\n", cmd, str); 8164141cc406Sopenharmony_ci free (str); 8165141cc406Sopenharmony_ci } 8166141cc406Sopenharmony_ci else 8167141cc406Sopenharmony_ci { 8168141cc406Sopenharmony_ci TRACE (8, "not enough memory for debugging ..."); 8169141cc406Sopenharmony_ci } 8170141cc406Sopenharmony_ci } 8171141cc406Sopenharmony_ci epilogue (); 8172141cc406Sopenharmony_ci return 1; 8173141cc406Sopenharmony_ci} 8174141cc406Sopenharmony_ci 8175141cc406Sopenharmony_ci 8176141cc406Sopenharmony_ci 8177141cc406Sopenharmony_cistatic int 8178141cc406Sopenharmony_cicmdSetGet (int cmd, int len, int *val) 8179141cc406Sopenharmony_ci{ 8180141cc406Sopenharmony_ci int *tampon; 8181141cc406Sopenharmony_ci int i; 8182141cc406Sopenharmony_ci 8183141cc406Sopenharmony_ci /* model revision 0x07 uses 35 bytes buffers */ 8184141cc406Sopenharmony_ci /* cmd 08 as 2 length depending upon model */ 8185141cc406Sopenharmony_ci if ((cmd == 8) && (getModel () == 0x07)) 8186141cc406Sopenharmony_ci { 8187141cc406Sopenharmony_ci len = 0x23; 8188141cc406Sopenharmony_ci } 8189141cc406Sopenharmony_ci 8190141cc406Sopenharmony_ci /* first we send */ 8191141cc406Sopenharmony_ci if (cmdSet (cmd, len, val) == 0) 8192141cc406Sopenharmony_ci { 8193141cc406Sopenharmony_ci DBG (0, "cmdSetGet failed ! (%s:%d)\n", __FILE__, __LINE__); 8194141cc406Sopenharmony_ci return 0; 8195141cc406Sopenharmony_ci } 8196141cc406Sopenharmony_ci 8197141cc406Sopenharmony_ci tampon = (int *) malloc (len * sizeof (int)); 8198141cc406Sopenharmony_ci memset (tampon, 0x00, len * sizeof (int)); 8199141cc406Sopenharmony_ci if (tampon == NULL) 8200141cc406Sopenharmony_ci { 8201141cc406Sopenharmony_ci DBG (0, "Failed to allocate room for %d int ! (%s:%d)\n", len, __FILE__, 8202141cc406Sopenharmony_ci __LINE__); 8203141cc406Sopenharmony_ci epilogue (); 8204141cc406Sopenharmony_ci return 0; 8205141cc406Sopenharmony_ci } 8206141cc406Sopenharmony_ci 8207141cc406Sopenharmony_ci /* then we receive */ 8208141cc406Sopenharmony_ci if (cmdGet (cmd, len, tampon) == 0) 8209141cc406Sopenharmony_ci { 8210141cc406Sopenharmony_ci DBG (0, "cmdSetGet failed ! (%s:%d)\n", __FILE__, __LINE__); 8211141cc406Sopenharmony_ci free (tampon); 8212141cc406Sopenharmony_ci epilogue (); 8213141cc406Sopenharmony_ci return 0; 8214141cc406Sopenharmony_ci } 8215141cc406Sopenharmony_ci 8216141cc406Sopenharmony_ci /* check and copy */ 8217141cc406Sopenharmony_ci for (i = 0; (i < len) && (val[i] >= 0); i++) 8218141cc406Sopenharmony_ci { 8219141cc406Sopenharmony_ci if (tampon[i] != val[i]) 8220141cc406Sopenharmony_ci { 8221141cc406Sopenharmony_ci DBG 8222141cc406Sopenharmony_ci (0, 8223141cc406Sopenharmony_ci "Warning data read back differs: expected %02X found tampon[%d]=%02X ! (%s:%d)\n", 8224141cc406Sopenharmony_ci val[i], i, tampon[i], __FILE__, __LINE__); 8225141cc406Sopenharmony_ci } 8226141cc406Sopenharmony_ci val[i] = tampon[i]; 8227141cc406Sopenharmony_ci } 8228141cc406Sopenharmony_ci 8229141cc406Sopenharmony_ci 8230141cc406Sopenharmony_ci /* OK */ 8231141cc406Sopenharmony_ci free (tampon); 8232141cc406Sopenharmony_ci return 1; 8233141cc406Sopenharmony_ci} 8234141cc406Sopenharmony_ci 8235141cc406Sopenharmony_ci 8236141cc406Sopenharmony_ci/* 1 OK, 0 failed */ 8237141cc406Sopenharmony_cistatic int 8238141cc406Sopenharmony_ciEPPcmdGetBuffer610p (int cmd, int len, unsigned char *buffer) 8239141cc406Sopenharmony_ci{ 8240141cc406Sopenharmony_ci int status, i, tmp, control; 8241141cc406Sopenharmony_ci int word[5]; 8242141cc406Sopenharmony_ci int count, needed, max; 8243141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 8244141cc406Sopenharmony_ci int fd, mode, rc, wait; 8245141cc406Sopenharmony_ci#endif 8246141cc406Sopenharmony_ci int loop, remain; 8247141cc406Sopenharmony_ci 8248141cc406Sopenharmony_ci /* first we set length and channel */ 8249141cc406Sopenharmony_ci /* compute word */ 8250141cc406Sopenharmony_ci word[0] = len / 65536; 8251141cc406Sopenharmony_ci word[1] = (len / 256) % 256; 8252141cc406Sopenharmony_ci word[2] = len % 256; 8253141cc406Sopenharmony_ci word[3] = (cmd & 0x0F) | 0xC0; 8254141cc406Sopenharmony_ci word[4] = -1; 8255141cc406Sopenharmony_ci 8256141cc406Sopenharmony_ci connect610p (); /* start of EPPsendLength610p */ 8257141cc406Sopenharmony_ci sync610p (); 8258141cc406Sopenharmony_ci 8259141cc406Sopenharmony_ci /* sends magic seal 55 AA */ 8260141cc406Sopenharmony_ci status = EPPputByte610p (0x55); 8261141cc406Sopenharmony_ci if ((status != 0xD0) && (status != 0xC8)) 8262141cc406Sopenharmony_ci { 8263141cc406Sopenharmony_ci DBG (0, "EPPcmdGetBuffer610p: Found 0x%X expected 0xC8 or 0xD0 (%s:%d)\n", 8264141cc406Sopenharmony_ci status, __FILE__, __LINE__); 8265141cc406Sopenharmony_ci return 0; 8266141cc406Sopenharmony_ci } 8267141cc406Sopenharmony_ci status = EPPputByte610p (0xAA); 8268141cc406Sopenharmony_ci if ((status != 0xD0) && (status != 0xC8)) 8269141cc406Sopenharmony_ci { 8270141cc406Sopenharmony_ci DBG (0, "EPPcmdGetBuffer610p: Found 0x%02X expected 0xC8 or 0xD0 (%s:%d)\n", 8271141cc406Sopenharmony_ci status, __FILE__, __LINE__); 8272141cc406Sopenharmony_ci return 0; 8273141cc406Sopenharmony_ci } 8274141cc406Sopenharmony_ci 8275141cc406Sopenharmony_ci /* tests status */ 8276141cc406Sopenharmony_ci status = EPPgetStatus610p (); 8277141cc406Sopenharmony_ci if ((status != 0xD0) && (status != 0xC8)) 8278141cc406Sopenharmony_ci { 8279141cc406Sopenharmony_ci DBG (0, "EPPcmdGetBuffer610p: Found 0x%X expected 0xC8 or 0xD0 (%s:%d)\n", 8280141cc406Sopenharmony_ci status, __FILE__, __LINE__); 8281141cc406Sopenharmony_ci return 0; 8282141cc406Sopenharmony_ci } 8283141cc406Sopenharmony_ci 8284141cc406Sopenharmony_ci /* sends length of data */ 8285141cc406Sopenharmony_ci for (i = 0; i < 4; i++) 8286141cc406Sopenharmony_ci { 8287141cc406Sopenharmony_ci status = EPPputByte610p (word[i]); 8288141cc406Sopenharmony_ci } 8289141cc406Sopenharmony_ci if ((status != 0xC0) && (status != 0xC8)) 8290141cc406Sopenharmony_ci { 8291141cc406Sopenharmony_ci DBG (0, 8292141cc406Sopenharmony_ci "EPPcmdGetBuffer610p: loop %d, found 0x%02X expected 0xC0 or 0xC8 (%s:%d)\n", 8293141cc406Sopenharmony_ci i, status, __FILE__, __LINE__); 8294141cc406Sopenharmony_ci return 0; 8295141cc406Sopenharmony_ci } 8296141cc406Sopenharmony_ci 8297141cc406Sopenharmony_ci Outb (DATA, 0xFF); 8298141cc406Sopenharmony_ci 8299141cc406Sopenharmony_ci /* test status */ 8300141cc406Sopenharmony_ci status = EPPgetStatus610p (); 8301141cc406Sopenharmony_ci if ((status != 0xC0) && (status != 0xD0)) 8302141cc406Sopenharmony_ci { 8303141cc406Sopenharmony_ci DBG (0, 8304141cc406Sopenharmony_ci "EPPcmdGetBuffer610p: Found 0x%X expected 0xC0 or 0xD0 (%s:%d)\n", 8305141cc406Sopenharmony_ci status, __FILE__, __LINE__); 8306141cc406Sopenharmony_ci /*return 0; */ 8307141cc406Sopenharmony_ci } 8308141cc406Sopenharmony_ci disconnect610p (); /* end of EPPsendLength610p */ 8309141cc406Sopenharmony_ci 8310141cc406Sopenharmony_ci /* max data read in one go */ 8311141cc406Sopenharmony_ci if (sanei_umax_pp_getfull () == 1) 8312141cc406Sopenharmony_ci max = 2550 / 3; 8313141cc406Sopenharmony_ci else 8314141cc406Sopenharmony_ci max = 32768; 8315141cc406Sopenharmony_ci 8316141cc406Sopenharmony_ci /* loop until enough data is read */ 8317141cc406Sopenharmony_ci count = 0; 8318141cc406Sopenharmony_ci while (count < len) 8319141cc406Sopenharmony_ci { 8320141cc406Sopenharmony_ci if (len - count > max) 8321141cc406Sopenharmony_ci needed = max; 8322141cc406Sopenharmony_ci else 8323141cc406Sopenharmony_ci needed = len - count; 8324141cc406Sopenharmony_ci if (needed % 4) 8325141cc406Sopenharmony_ci remain = needed % 4; 8326141cc406Sopenharmony_ci else 8327141cc406Sopenharmony_ci remain = 4; 8328141cc406Sopenharmony_ci loop = (needed - remain) / 2; 8329141cc406Sopenharmony_ci DBG (32, "EPPcmdGetBuffer610p: %d loops to do \n", loop); 8330141cc406Sopenharmony_ci 8331141cc406Sopenharmony_ci status = 0x20; 8332141cc406Sopenharmony_ci 8333141cc406Sopenharmony_ci /* wait for data ready */ 8334141cc406Sopenharmony_ci while ((status & 0x80) != 0x80) 8335141cc406Sopenharmony_ci { 8336141cc406Sopenharmony_ci /* this is SPPgetStatus */ 8337141cc406Sopenharmony_ci connect610p (); 8338141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 8339141cc406Sopenharmony_ci Outb (DATA, 0xFF); 8340141cc406Sopenharmony_ci tmp = Inb (DATA); 8341141cc406Sopenharmony_ci if (tmp != 0xFF) 8342141cc406Sopenharmony_ci { 8343141cc406Sopenharmony_ci DBG (0, 8344141cc406Sopenharmony_ci "EPPcmdGetBuffer610p found 0x%02X expected 0xFF (%s:%d)\n", 8345141cc406Sopenharmony_ci tmp, __FILE__, __LINE__); 8346141cc406Sopenharmony_ci return 0; 8347141cc406Sopenharmony_ci } 8348141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 8349141cc406Sopenharmony_ci if ((status & 0x80) != 0x80) 8350141cc406Sopenharmony_ci { 8351141cc406Sopenharmony_ci disconnect610p (); 8352141cc406Sopenharmony_ci usleep(1000); 8353141cc406Sopenharmony_ci } 8354141cc406Sopenharmony_ci else 8355141cc406Sopenharmony_ci { 8356141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 8357141cc406Sopenharmony_ci sync610p (); 8358141cc406Sopenharmony_ci Outb (DATA, 0xFF); 8359141cc406Sopenharmony_ci control = (Inb (CONTROL) & 0x44) | 0xE4; 8360141cc406Sopenharmony_ci Outb (CONTROL, control); 8361141cc406Sopenharmony_ci } 8362141cc406Sopenharmony_ci } 8363141cc406Sopenharmony_ci 8364141cc406Sopenharmony_ci /* EPP block read */ 8365141cc406Sopenharmony_ci /* there is one form for full CCD width reads, and another for other 8366141cc406Sopenharmony_ci reads */ 8367141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H 8368141cc406Sopenharmony_ci wait = 0; 8369141cc406Sopenharmony_ci /* check we have ppdev working */ 8370141cc406Sopenharmony_ci fd = sanei_umax_pp_getparport (); 8371141cc406Sopenharmony_ci if (fd > 0) 8372141cc406Sopenharmony_ci { 8373141cc406Sopenharmony_ci mode = 1; /* data_reverse */ 8374141cc406Sopenharmony_ci rc = ioctl (fd, PPDATADIR, &mode); 8375141cc406Sopenharmony_ci if (rc) 8376141cc406Sopenharmony_ci DBG (0, 8377141cc406Sopenharmony_ci "EPPcmdGetBuffer610p: ppdev ioctl returned <%s> (%s:%d)\n", 8378141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 8379141cc406Sopenharmony_ci 8380141cc406Sopenharmony_ci#ifdef PPSETFLAGS 8381141cc406Sopenharmony_ci mode = PP_FASTREAD; 8382141cc406Sopenharmony_ci rc = ioctl (fd, PPSETFLAGS, &mode); 8383141cc406Sopenharmony_ci if (rc) 8384141cc406Sopenharmony_ci DBG (0, 8385141cc406Sopenharmony_ci "EPPcmdGetBuffer610p: ppdev ioctl returned <%s> (%s:%d)\n", 8386141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 8387141cc406Sopenharmony_ci#endif 8388141cc406Sopenharmony_ci mode = IEEE1284_MODE_EPP | IEEE1284_DATA; 8389141cc406Sopenharmony_ci rc = ioctl (fd, PPSETMODE, &mode); 8390141cc406Sopenharmony_ci if (rc) 8391141cc406Sopenharmony_ci { 8392141cc406Sopenharmony_ci DBG (0, 8393141cc406Sopenharmony_ci "EPPcmdGetBuffer610p: ppdev ioctl returned <%s> (%s:%d)\n", 8394141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 8395141cc406Sopenharmony_ci return 0; 8396141cc406Sopenharmony_ci } 8397141cc406Sopenharmony_ci if (sanei_umax_pp_getfull () == 1) 8398141cc406Sopenharmony_ci { 8399141cc406Sopenharmony_ci do 8400141cc406Sopenharmony_ci { 8401141cc406Sopenharmony_ci rc = read (fd, buffer + count, needed); 8402141cc406Sopenharmony_ci } 8403141cc406Sopenharmony_ci while (rc == EAGAIN); 8404141cc406Sopenharmony_ci if (rc < 0) 8405141cc406Sopenharmony_ci { 8406141cc406Sopenharmony_ci DBG (0, 8407141cc406Sopenharmony_ci "EPPcmdGetBuffer610p: ppdev read failed <%s> (%s:%d)\n", 8408141cc406Sopenharmony_ci strerror (errno), __FILE__, __LINE__); 8409141cc406Sopenharmony_ci return 0; 8410141cc406Sopenharmony_ci } 8411141cc406Sopenharmony_ci#ifdef IOLOG 8412141cc406Sopenharmony_ci DBG (0, "insb *%d\n", rc); 8413141cc406Sopenharmony_ci#endif 8414141cc406Sopenharmony_ci needed = rc; 8415141cc406Sopenharmony_ci } 8416141cc406Sopenharmony_ci else 8417141cc406Sopenharmony_ci { 8418141cc406Sopenharmony_ci for (loop = 0; (loop < needed) && (wait==0); loop++) 8419141cc406Sopenharmony_ci { 8420141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 8421141cc406Sopenharmony_ci if ((status != 0xD0) && (status != 0xC0) 8422141cc406Sopenharmony_ci && (status != 0xC8)) 8423141cc406Sopenharmony_ci { 8424141cc406Sopenharmony_ci DBG (0, 8425141cc406Sopenharmony_ci "EPPcmdGetBuffer610p found 0x%02X expected 0xD0 or 0xC0 (%s:%d)\n", 8426141cc406Sopenharmony_ci status, __FILE__, __LINE__); 8427141cc406Sopenharmony_ci return 0; 8428141cc406Sopenharmony_ci } 8429141cc406Sopenharmony_ci if (status == 0xC8) 8430141cc406Sopenharmony_ci { 8431141cc406Sopenharmony_ci wait = 1; 8432141cc406Sopenharmony_ci needed=loop; 8433141cc406Sopenharmony_ci } 8434141cc406Sopenharmony_ci else 8435141cc406Sopenharmony_ci { 8436141cc406Sopenharmony_ci tmp = Inb (EPPDATA); 8437141cc406Sopenharmony_ci buffer[count + loop] = tmp; 8438141cc406Sopenharmony_ci } 8439141cc406Sopenharmony_ci } 8440141cc406Sopenharmony_ci } 8441141cc406Sopenharmony_ci } 8442141cc406Sopenharmony_ci else 8443141cc406Sopenharmony_ci#endif /* HAVE_LINUX_PPDEV_H */ 8444141cc406Sopenharmony_ci { 8445141cc406Sopenharmony_ci Insb (EPPDATA, buffer + count, needed); 8446141cc406Sopenharmony_ci } 8447141cc406Sopenharmony_ci count += needed; 8448141cc406Sopenharmony_ci disconnect610p (); 8449141cc406Sopenharmony_ci } 8450141cc406Sopenharmony_ci usleep (10000); 8451141cc406Sopenharmony_ci /* ??? CMDSYNC (0x00); */ 8452141cc406Sopenharmony_ci /* everything went fine */ 8453141cc406Sopenharmony_ci return 1; 8454141cc406Sopenharmony_ci} 8455141cc406Sopenharmony_ci 8456141cc406Sopenharmony_ci/* 1 OK, 0 failed */ 8457141cc406Sopenharmony_cistatic int 8458141cc406Sopenharmony_cicmdGetBuffer610p (int cmd, int len, unsigned char *buffer) 8459141cc406Sopenharmony_ci{ 8460141cc406Sopenharmony_ci int status, i, tmp; 8461141cc406Sopenharmony_ci int word[5]; 8462141cc406Sopenharmony_ci int read, needed, max; 8463141cc406Sopenharmony_ci 8464141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 8465141cc406Sopenharmony_ci return EPPcmdGetBuffer610p (cmd, len, buffer); 8466141cc406Sopenharmony_ci 8467141cc406Sopenharmony_ci /* first we set length and channel */ 8468141cc406Sopenharmony_ci /* compute word */ 8469141cc406Sopenharmony_ci word[0] = len / 65536; 8470141cc406Sopenharmony_ci word[1] = (len / 256) % 256; 8471141cc406Sopenharmony_ci word[2] = len % 256; 8472141cc406Sopenharmony_ci word[3] = (cmd & 0x0F) | 0xC0; 8473141cc406Sopenharmony_ci word[4] = -1; 8474141cc406Sopenharmony_ci 8475141cc406Sopenharmony_ci connect610p (); 8476141cc406Sopenharmony_ci sync610p (); 8477141cc406Sopenharmony_ci if (sendLength610p (word) == 0) 8478141cc406Sopenharmony_ci { 8479141cc406Sopenharmony_ci DBG (0, "sendLength610p(word) failed... (%s:%d)\n", __FILE__, __LINE__); 8480141cc406Sopenharmony_ci return 0; 8481141cc406Sopenharmony_ci } 8482141cc406Sopenharmony_ci status = getStatus610p (); 8483141cc406Sopenharmony_ci scannerStatus = status; 8484141cc406Sopenharmony_ci if ((status != 0xC0) && (status != 0xD0)) 8485141cc406Sopenharmony_ci { 8486141cc406Sopenharmony_ci DBG (1, "Found 0x%X expected 0xC0 or 0xD0 (%s:%d)\n", status, __FILE__, 8487141cc406Sopenharmony_ci __LINE__); 8488141cc406Sopenharmony_ci return 0; 8489141cc406Sopenharmony_ci } 8490141cc406Sopenharmony_ci disconnect610p (); 8491141cc406Sopenharmony_ci 8492141cc406Sopenharmony_ci if (sanei_umax_pp_getfull () == 1) 8493141cc406Sopenharmony_ci max = 2550 / 3; 8494141cc406Sopenharmony_ci else 8495141cc406Sopenharmony_ci max = 32768; 8496141cc406Sopenharmony_ci read = 0; 8497141cc406Sopenharmony_ci while (read < len) 8498141cc406Sopenharmony_ci { 8499141cc406Sopenharmony_ci if (len - read > max) 8500141cc406Sopenharmony_ci needed = max; 8501141cc406Sopenharmony_ci else 8502141cc406Sopenharmony_ci needed = len - read; 8503141cc406Sopenharmony_ci 8504141cc406Sopenharmony_ci if (sanei_umax_pp_getfull () == 0) 8505141cc406Sopenharmony_ci status = getStatus610p (); 8506141cc406Sopenharmony_ci else 8507141cc406Sopenharmony_ci status = 0x20; 8508141cc406Sopenharmony_ci 8509141cc406Sopenharmony_ci /* wait for data ready */ 8510141cc406Sopenharmony_ci while ((status & 0x80) == 0x00) 8511141cc406Sopenharmony_ci { 8512141cc406Sopenharmony_ci connect610p (); 8513141cc406Sopenharmony_ci Outb (CONTROL, 0x07); 8514141cc406Sopenharmony_ci Outb (DATA, 0xFF); 8515141cc406Sopenharmony_ci tmp = Inb (DATA); 8516141cc406Sopenharmony_ci if (tmp != 0xFF) 8517141cc406Sopenharmony_ci { 8518141cc406Sopenharmony_ci DBG (0, 8519141cc406Sopenharmony_ci "cmdGetBuffer610p found 0x%02X expected 0xFF (%s:%d)\n", 8520141cc406Sopenharmony_ci tmp, __FILE__, __LINE__); 8521141cc406Sopenharmony_ci return 0; 8522141cc406Sopenharmony_ci } 8523141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 8524141cc406Sopenharmony_ci if ((status & 0x80) == 0x00) 8525141cc406Sopenharmony_ci disconnect610p (); 8526141cc406Sopenharmony_ci else 8527141cc406Sopenharmony_ci { 8528141cc406Sopenharmony_ci Outb (CONTROL, 0x04); 8529141cc406Sopenharmony_ci sync610p (); 8530141cc406Sopenharmony_ci byteMode (); 8531141cc406Sopenharmony_ci } 8532141cc406Sopenharmony_ci } 8533141cc406Sopenharmony_ci 8534141cc406Sopenharmony_ci i = 0; 8535141cc406Sopenharmony_ci while (i < needed) 8536141cc406Sopenharmony_ci { 8537141cc406Sopenharmony_ci if (sanei_umax_pp_getfull () == 0) 8538141cc406Sopenharmony_ci { 8539141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 8540141cc406Sopenharmony_ci if (status == 0xC8) 8541141cc406Sopenharmony_ci { 8542141cc406Sopenharmony_ci for (tmp = 0; tmp < 18; tmp++) 8543141cc406Sopenharmony_ci status = Inb (STATUS) & 0xF8; 8544141cc406Sopenharmony_ci break; 8545141cc406Sopenharmony_ci } 8546141cc406Sopenharmony_ci } 8547141cc406Sopenharmony_ci Outb (CONTROL, 0x26); /* data reverse+ 'reg' */ 8548141cc406Sopenharmony_ci buffer[read + i] = Inb (DATA); 8549141cc406Sopenharmony_ci Outb (CONTROL, 0x24); /* data reverse+ 'reg' */ 8550141cc406Sopenharmony_ci i++; 8551141cc406Sopenharmony_ci } 8552141cc406Sopenharmony_ci byteMode (); 8553141cc406Sopenharmony_ci disconnect610p (); 8554141cc406Sopenharmony_ci read += i; 8555141cc406Sopenharmony_ci } 8556141cc406Sopenharmony_ci 8557141cc406Sopenharmony_ci return 1; 8558141cc406Sopenharmony_ci} 8559141cc406Sopenharmony_ci 8560141cc406Sopenharmony_ci 8561141cc406Sopenharmony_ci/* 1 OK, 0 failed */ 8562141cc406Sopenharmony_cistatic int 8563141cc406Sopenharmony_cicmdGetBuffer (int cmd, int len, unsigned char *buffer) 8564141cc406Sopenharmony_ci{ 8565141cc406Sopenharmony_ci int reg, tmp; 8566141cc406Sopenharmony_ci int word[5], read; 8567141cc406Sopenharmony_ci int needed; 8568141cc406Sopenharmony_ci 8569141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 8570141cc406Sopenharmony_ci return cmdGetBuffer610p (cmd, len, buffer); 8571141cc406Sopenharmony_ci 8572141cc406Sopenharmony_ci /* compute word */ 8573141cc406Sopenharmony_ci word[0] = len / 65536; 8574141cc406Sopenharmony_ci word[1] = len / 256 % 256; 8575141cc406Sopenharmony_ci word[2] = len % 256; 8576141cc406Sopenharmony_ci word[3] = (cmd & 0x0F) | 0xC0; 8577141cc406Sopenharmony_ci word[4] = -1; 8578141cc406Sopenharmony_ci 8579141cc406Sopenharmony_ci /* send word: len+addr(?) */ 8580141cc406Sopenharmony_ci if (foncSendWord (word) == 0) 8581141cc406Sopenharmony_ci { 8582141cc406Sopenharmony_ci DBG (0, "foncSendWord(word) failed (%s:%d)\n", __FILE__, __LINE__); 8583141cc406Sopenharmony_ci return 0; 8584141cc406Sopenharmony_ci } 8585141cc406Sopenharmony_ci DBG (16, "(%s:%d) passed \n", __FILE__, __LINE__); 8586141cc406Sopenharmony_ci 8587141cc406Sopenharmony_ci prologue (0x10); 8588141cc406Sopenharmony_ci 8589141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0D); 8590141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 8591141cc406Sopenharmony_ci 8592141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8593141cc406Sopenharmony_ci 8594141cc406Sopenharmony_ci /* wait if busy */ 8595141cc406Sopenharmony_ci while ((reg & 0x08) == 0x08) 8596141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8597141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 8598141cc406Sopenharmony_ci { 8599141cc406Sopenharmony_ci DBG (0, "cmdGetBuffer failed (%s:%d)\n", __FILE__, __LINE__); 8600141cc406Sopenharmony_ci return 0; 8601141cc406Sopenharmony_ci } 8602141cc406Sopenharmony_ci 8603141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 8604141cc406Sopenharmony_ci { 8605141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x44); 8606141cc406Sopenharmony_ci } 8607141cc406Sopenharmony_ci 8608141cc406Sopenharmony_ci read = 0; 8609141cc406Sopenharmony_ci reg = registerRead (0x0C); 8610141cc406Sopenharmony_ci if (reg != 0x04) 8611141cc406Sopenharmony_ci { 8612141cc406Sopenharmony_ci DBG (0, "cmdGetBuffer failed: unexpected status 0x%02X ...(%s:%d)\n", 8613141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 8614141cc406Sopenharmony_ci return 0; 8615141cc406Sopenharmony_ci } 8616141cc406Sopenharmony_ci REGISTERWRITE (0x0C, reg | 0x40); 8617141cc406Sopenharmony_ci 8618141cc406Sopenharmony_ci /* actual data */ 8619141cc406Sopenharmony_ci read = 0; 8620141cc406Sopenharmony_ci while (read < len) 8621141cc406Sopenharmony_ci { 8622141cc406Sopenharmony_ci needed = len - read; 8623141cc406Sopenharmony_ci if (needed > 32768) 8624141cc406Sopenharmony_ci needed = 32768; 8625141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 8626141cc406Sopenharmony_ci { 8627141cc406Sopenharmony_ci compatMode (); 8628141cc406Sopenharmony_ci Outb (CONTROL, 0x04); /* reset ? */ 8629141cc406Sopenharmony_ci ECPSetBuffer (needed); 8630141cc406Sopenharmony_ci tmp = ECPbufferRead (needed, buffer + read); 8631141cc406Sopenharmony_ci DBG (16, "ECPbufferRead(%d,buffer+read) passed (%s:%d)\n", needed, 8632141cc406Sopenharmony_ci __FILE__, __LINE__); 8633141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x84); 8634141cc406Sopenharmony_ci } 8635141cc406Sopenharmony_ci else 8636141cc406Sopenharmony_ci { 8637141cc406Sopenharmony_ci tmp = pausedBufferRead (needed, buffer + read); 8638141cc406Sopenharmony_ci } 8639141cc406Sopenharmony_ci if (tmp < needed) 8640141cc406Sopenharmony_ci { 8641141cc406Sopenharmony_ci DBG (64, "cmdGetBuffer only got %d bytes out of %d ...(%s:%d)\n", 8642141cc406Sopenharmony_ci tmp, needed, __FILE__, __LINE__); 8643141cc406Sopenharmony_ci } 8644141cc406Sopenharmony_ci else 8645141cc406Sopenharmony_ci { 8646141cc406Sopenharmony_ci DBG (64, 8647141cc406Sopenharmony_ci "cmdGetBuffer got all %d bytes out of %d , read=%d...(%s:%d)\n", 8648141cc406Sopenharmony_ci tmp, 32768, read, __FILE__, __LINE__); 8649141cc406Sopenharmony_ci } 8650141cc406Sopenharmony_ci read += tmp; 8651141cc406Sopenharmony_ci DBG (16, "Read %d bytes out of %d (last block is %d bytes) (%s:%d)\n", 8652141cc406Sopenharmony_ci read, len, tmp, __FILE__, __LINE__); 8653141cc406Sopenharmony_ci if (read < len) 8654141cc406Sopenharmony_ci { 8655141cc406Sopenharmony_ci /* wait for scanner to be ready */ 8656141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8657141cc406Sopenharmony_ci DBG (64, "Status after block read is 0x%02X (%s:%d)\n", reg, 8658141cc406Sopenharmony_ci __FILE__, __LINE__); 8659141cc406Sopenharmony_ci if ((reg & 0x08) == 0x08) 8660141cc406Sopenharmony_ci { 8661141cc406Sopenharmony_ci int pass = 0; 8662141cc406Sopenharmony_ci 8663141cc406Sopenharmony_ci do 8664141cc406Sopenharmony_ci { 8665141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8666141cc406Sopenharmony_ci usleep (100); 8667141cc406Sopenharmony_ci pass++; 8668141cc406Sopenharmony_ci } 8669141cc406Sopenharmony_ci while ((pass < 32768) && ((reg & 0x08) == 0x08)); 8670141cc406Sopenharmony_ci DBG (64, "Status after waiting is 0x%02X (pass=%d) (%s:%d)\n", 8671141cc406Sopenharmony_ci reg, pass, __FILE__, __LINE__); 8672141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 8673141cc406Sopenharmony_ci { 8674141cc406Sopenharmony_ci DBG (0, 8675141cc406Sopenharmony_ci "Unexpected status 0x%02X, expected 0xC0 or 0xD0 ! (%s:%d)\n", 8676141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 8677141cc406Sopenharmony_ci DBG (0, "Going on...\n"); 8678141cc406Sopenharmony_ci } 8679141cc406Sopenharmony_ci } 8680141cc406Sopenharmony_ci 8681141cc406Sopenharmony_ci /* signal we want next data chunk */ 8682141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_ECP) 8683141cc406Sopenharmony_ci { 8684141cc406Sopenharmony_ci REGISTERWRITE (0x1A, 0x44); 8685141cc406Sopenharmony_ci } 8686141cc406Sopenharmony_ci reg = registerRead (0x0C); 8687141cc406Sopenharmony_ci registerWrite (0x0C, reg | 0x40); 8688141cc406Sopenharmony_ci } 8689141cc406Sopenharmony_ci } 8690141cc406Sopenharmony_ci 8691141cc406Sopenharmony_ci /* OK ! */ 8692141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0D); 8693141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 8694141cc406Sopenharmony_ci 8695141cc406Sopenharmony_ci /* epilogue */ 8696141cc406Sopenharmony_ci epilogue (); 8697141cc406Sopenharmony_ci return 1; 8698141cc406Sopenharmony_ci} 8699141cc406Sopenharmony_ci 8700141cc406Sopenharmony_ci/* 1 OK, 0 failed */ 8701141cc406Sopenharmony_cistatic int 8702141cc406Sopenharmony_cicmdGetBuffer32 (int cmd, int len, unsigned char *buffer) 8703141cc406Sopenharmony_ci{ 8704141cc406Sopenharmony_ci int reg, tmp; 8705141cc406Sopenharmony_ci int word[5], read; 8706141cc406Sopenharmony_ci 8707141cc406Sopenharmony_ci /* compute word */ 8708141cc406Sopenharmony_ci word[0] = len / 65536; 8709141cc406Sopenharmony_ci word[1] = len / 256 % 256; 8710141cc406Sopenharmony_ci word[2] = len % 256; 8711141cc406Sopenharmony_ci word[3] = (cmd & 0x3F) | 0x80 | 0x40; 8712141cc406Sopenharmony_ci 8713141cc406Sopenharmony_ci if (!prologue (0x10)) 8714141cc406Sopenharmony_ci { 8715141cc406Sopenharmony_ci DBG (0, "cmdSet: prologue failed ! (%s:%d)\n", __FILE__, __LINE__); 8716141cc406Sopenharmony_ci return 0; 8717141cc406Sopenharmony_ci } 8718141cc406Sopenharmony_ci 8719141cc406Sopenharmony_ci /* send data */ 8720141cc406Sopenharmony_ci if (sendLength (word, 4) == 0) 8721141cc406Sopenharmony_ci { 8722141cc406Sopenharmony_ci DBG (0, "sendLength(word,4) failed (%s:%d)\n", __FILE__, __LINE__); 8723141cc406Sopenharmony_ci return 0; 8724141cc406Sopenharmony_ci } 8725141cc406Sopenharmony_ci TRACE (16, "sendLength(word,4) passed ..."); 8726141cc406Sopenharmony_ci 8727141cc406Sopenharmony_ci /* head end */ 8728141cc406Sopenharmony_ci epilogue (); 8729141cc406Sopenharmony_ci 8730141cc406Sopenharmony_ci prologue (0x10); 8731141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0D); 8732141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 8733141cc406Sopenharmony_ci 8734141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8735141cc406Sopenharmony_ci 8736141cc406Sopenharmony_ci /* wait if busy */ 8737141cc406Sopenharmony_ci while ((reg & 0x08) == 0x08) 8738141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8739141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 8740141cc406Sopenharmony_ci { 8741141cc406Sopenharmony_ci DBG (0, "cmdGetBuffer32 failed: unexpected status 0x%02X ...(%s:%d)\n", 8742141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 8743141cc406Sopenharmony_ci return 0; 8744141cc406Sopenharmony_ci } 8745141cc406Sopenharmony_ci reg = registerRead (0x0C); 8746141cc406Sopenharmony_ci if (reg != 0x04) 8747141cc406Sopenharmony_ci { 8748141cc406Sopenharmony_ci DBG (0, "cmdGetBuffer32 failed: unexpected status 0x%02X ...(%s:%d)\n", 8749141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 8750141cc406Sopenharmony_ci return 0; 8751141cc406Sopenharmony_ci } 8752141cc406Sopenharmony_ci REGISTERWRITE (0x0C, reg | 0x40); 8753141cc406Sopenharmony_ci 8754141cc406Sopenharmony_ci read = 0; 8755141cc406Sopenharmony_ci while (read < len) 8756141cc406Sopenharmony_ci { 8757141cc406Sopenharmony_ci if (read + 1700 < len) 8758141cc406Sopenharmony_ci { 8759141cc406Sopenharmony_ci tmp = 1700; 8760141cc406Sopenharmony_ci bufferRead (tmp, buffer + read); 8761141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8762141cc406Sopenharmony_ci if ((read + tmp < len) && (reg & 0x08) == 0x08) 8763141cc406Sopenharmony_ci { 8764141cc406Sopenharmony_ci do 8765141cc406Sopenharmony_ci { 8766141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8767141cc406Sopenharmony_ci } 8768141cc406Sopenharmony_ci while ((reg & 0x08) == 0x08); 8769141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0)) 8770141cc406Sopenharmony_ci { 8771141cc406Sopenharmony_ci DBG (0, 8772141cc406Sopenharmony_ci "Unexpected status 0x%02X, expected 0xC0 or 0xD0 ! (%s:%d)\n", 8773141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 8774141cc406Sopenharmony_ci DBG (0, "Going on...\n"); 8775141cc406Sopenharmony_ci } 8776141cc406Sopenharmony_ci } 8777141cc406Sopenharmony_ci reg = registerRead (0x0C); 8778141cc406Sopenharmony_ci registerWrite (0x0C, reg | 0x40); 8779141cc406Sopenharmony_ci read += tmp; 8780141cc406Sopenharmony_ci } 8781141cc406Sopenharmony_ci else 8782141cc406Sopenharmony_ci { 8783141cc406Sopenharmony_ci tmp = len - read; 8784141cc406Sopenharmony_ci bufferRead (tmp, buffer + read); 8785141cc406Sopenharmony_ci read += tmp; 8786141cc406Sopenharmony_ci if ((read < len)) 8787141cc406Sopenharmony_ci { 8788141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8789141cc406Sopenharmony_ci while ((reg & 0x08) == 0x08) 8790141cc406Sopenharmony_ci { 8791141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8792141cc406Sopenharmony_ci } 8793141cc406Sopenharmony_ci } 8794141cc406Sopenharmony_ci } 8795141cc406Sopenharmony_ci } 8796141cc406Sopenharmony_ci 8797141cc406Sopenharmony_ci /* OK ! */ 8798141cc406Sopenharmony_ci epilogue (); 8799141cc406Sopenharmony_ci return 1; 8800141cc406Sopenharmony_ci} 8801141cc406Sopenharmony_ci 8802141cc406Sopenharmony_ciint 8803141cc406Sopenharmony_cisanei_umax_pp_cmdSync (int cmd) 8804141cc406Sopenharmony_ci{ 8805141cc406Sopenharmony_ci int word[5]; 8806141cc406Sopenharmony_ci 8807141cc406Sopenharmony_ci 8808141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 8809141cc406Sopenharmony_ci return cmdSync610p (cmd); 8810141cc406Sopenharmony_ci 8811141cc406Sopenharmony_ci /* compute word */ 8812141cc406Sopenharmony_ci word[0] = 0x00; 8813141cc406Sopenharmony_ci word[1] = 0x00; 8814141cc406Sopenharmony_ci word[2] = 0x00; 8815141cc406Sopenharmony_ci word[3] = cmd; 8816141cc406Sopenharmony_ci 8817141cc406Sopenharmony_ci if (!prologue (0x10)) 8818141cc406Sopenharmony_ci { 8819141cc406Sopenharmony_ci DBG (0, "cmdSync: prologue failed ! (%s:%d)\n", __FILE__, __LINE__); 8820141cc406Sopenharmony_ci } 8821141cc406Sopenharmony_ci 8822141cc406Sopenharmony_ci /* send data */ 8823141cc406Sopenharmony_ci if (sendLength (word, 4) == 0) 8824141cc406Sopenharmony_ci { 8825141cc406Sopenharmony_ci DBG (0, "sendLength(word,4) failed (%s:%d)\n", __FILE__, __LINE__); 8826141cc406Sopenharmony_ci return 0; 8827141cc406Sopenharmony_ci } 8828141cc406Sopenharmony_ci TRACE (16, "sendLength(word,4) passed ..."); 8829141cc406Sopenharmony_ci 8830141cc406Sopenharmony_ci /* end OK */ 8831141cc406Sopenharmony_ci epilogue (); 8832141cc406Sopenharmony_ci 8833141cc406Sopenharmony_ci return 1; 8834141cc406Sopenharmony_ci} 8835141cc406Sopenharmony_ci 8836141cc406Sopenharmony_ci 8837141cc406Sopenharmony_ci/* numbers of bytes read, else 0 (failed) */ 8838141cc406Sopenharmony_ci/* read data by chunk EXACTLY the width of the scan area in the given */ 8839141cc406Sopenharmony_ci/* resolution . If a valid file descriptor is given, we write data */ 8840141cc406Sopenharmony_ci/* in it according to the color mode, before polling the scanner */ 8841141cc406Sopenharmony_ci/* len should not be bigger than 2 Megs */ 8842141cc406Sopenharmony_ci 8843141cc406Sopenharmony_ciint 8844141cc406Sopenharmony_cicmdGetBlockBuffer (int cmd, int len, int window, unsigned char *buffer) 8845141cc406Sopenharmony_ci{ 8846141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 8847141cc406Sopenharmony_ci struct timeval td, tf; 8848141cc406Sopenharmony_ci float elapsed; 8849141cc406Sopenharmony_ci#endif 8850141cc406Sopenharmony_ci int reg; 8851141cc406Sopenharmony_ci int word[5], read; 8852141cc406Sopenharmony_ci 8853141cc406Sopenharmony_ci /* compute word */ 8854141cc406Sopenharmony_ci word[0] = len / 65536; 8855141cc406Sopenharmony_ci word[1] = len / 256 % 256; 8856141cc406Sopenharmony_ci word[2] = len % 256; 8857141cc406Sopenharmony_ci word[3] = (cmd & 0x3F) | 0x80 | 0x40; 8858141cc406Sopenharmony_ci 8859141cc406Sopenharmony_ci if (!prologue (0x10)) 8860141cc406Sopenharmony_ci { 8861141cc406Sopenharmony_ci DBG (0, "cmdGetBlockBuffer: prologue failed ! (%s:%d)\n", __FILE__, 8862141cc406Sopenharmony_ci __LINE__); 8863141cc406Sopenharmony_ci } 8864141cc406Sopenharmony_ci 8865141cc406Sopenharmony_ci /* send data */ 8866141cc406Sopenharmony_ci if (sendLength (word, 4) == 0) 8867141cc406Sopenharmony_ci { 8868141cc406Sopenharmony_ci DBG (0, "sendLength(word,4) failed (%s:%d)\n", __FILE__, __LINE__); 8869141cc406Sopenharmony_ci return 0; 8870141cc406Sopenharmony_ci } 8871141cc406Sopenharmony_ci TRACE (16, "sendLength(word,4) passed ..."); 8872141cc406Sopenharmony_ci /* head end */ 8873141cc406Sopenharmony_ci epilogue (); 8874141cc406Sopenharmony_ci 8875141cc406Sopenharmony_ci 8876141cc406Sopenharmony_ci 8877141cc406Sopenharmony_ci if (!prologue (0x10)) 8878141cc406Sopenharmony_ci { 8879141cc406Sopenharmony_ci DBG (0, "cmdGetBlockBuffer: prologue failed ! (%s:%d)\n", __FILE__, 8880141cc406Sopenharmony_ci __LINE__); 8881141cc406Sopenharmony_ci } 8882141cc406Sopenharmony_ci 8883141cc406Sopenharmony_ci 8884141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0D); 8885141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 8886141cc406Sopenharmony_ci 8887141cc406Sopenharmony_ci /* init counter */ 8888141cc406Sopenharmony_ci read = 0; 8889141cc406Sopenharmony_ci 8890141cc406Sopenharmony_ci /* read scanner state */ 8891141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8892141cc406Sopenharmony_ci 8893141cc406Sopenharmony_ci 8894141cc406Sopenharmony_ci /* read loop */ 8895141cc406Sopenharmony_ci while (read < len) 8896141cc406Sopenharmony_ci { 8897141cc406Sopenharmony_ci /* wait for the data to be ready */ 8898141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 8899141cc406Sopenharmony_ci gettimeofday (&td, NULL); 8900141cc406Sopenharmony_ci#endif 8901141cc406Sopenharmony_ci while ((reg & 0x08) == 0x08) 8902141cc406Sopenharmony_ci { 8903141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8904141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 8905141cc406Sopenharmony_ci gettimeofday (&tf, NULL); 8906141cc406Sopenharmony_ci elapsed = 8907141cc406Sopenharmony_ci ((tf.tv_sec * 1000000 + tf.tv_usec) - 8908141cc406Sopenharmony_ci (td.tv_sec * 1000000 + td.tv_usec)) / 1000000; 8909141cc406Sopenharmony_ci if (elapsed > 3) 8910141cc406Sopenharmony_ci { 8911141cc406Sopenharmony_ci DBG 8912141cc406Sopenharmony_ci (0, 8913141cc406Sopenharmony_ci "Time-out (%.2f s) waiting for scanner ... giving up on status 0x%02X ! (%s:%d)\n", 8914141cc406Sopenharmony_ci elapsed, reg, __FILE__, __LINE__); 8915141cc406Sopenharmony_ci epilogue (); 8916141cc406Sopenharmony_ci return read; 8917141cc406Sopenharmony_ci } 8918141cc406Sopenharmony_ci#endif 8919141cc406Sopenharmony_ci } 8920141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0) && (reg != 0x00)) 8921141cc406Sopenharmony_ci { 8922141cc406Sopenharmony_ci DBG (0, 8923141cc406Sopenharmony_ci "Unexpected status 0x%02X, expected 0xC0 or 0xD0 ! (%s:%d)\n", 8924141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 8925141cc406Sopenharmony_ci DBG (0, "Going on...\n"); 8926141cc406Sopenharmony_ci } 8927141cc406Sopenharmony_ci 8928141cc406Sopenharmony_ci /* signals next chunk */ 8929141cc406Sopenharmony_ci reg = registerRead (0x0C); 8930141cc406Sopenharmony_ci if (reg != 0x04) 8931141cc406Sopenharmony_ci { 8932141cc406Sopenharmony_ci DBG (0, 8933141cc406Sopenharmony_ci "cmdGetBlockBuffer failed: unexpected value reg0C=0x%02X ...(%s:%d)\n", 8934141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 8935141cc406Sopenharmony_ci return 0; 8936141cc406Sopenharmony_ci } 8937141cc406Sopenharmony_ci REGISTERWRITE (0x0C, reg | 0x40); 8938141cc406Sopenharmony_ci 8939141cc406Sopenharmony_ci 8940141cc406Sopenharmony_ci /* there is always a full block ready when scanner is ready */ 8941141cc406Sopenharmony_ci /* 32 bits I/O read , window must match the width of scan */ 8942141cc406Sopenharmony_ci bufferRead (window, buffer + read); 8943141cc406Sopenharmony_ci 8944141cc406Sopenharmony_ci /* add bytes read */ 8945141cc406Sopenharmony_ci read += window; 8946141cc406Sopenharmony_ci 8947141cc406Sopenharmony_ci 8948141cc406Sopenharmony_ci DBG (16, "Read %d bytes out of %d (last block is %d bytes) (%s:%d)\n", 8949141cc406Sopenharmony_ci read, len, window, __FILE__, __LINE__); 8950141cc406Sopenharmony_ci 8951141cc406Sopenharmony_ci /* test status after read */ 8952141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8953141cc406Sopenharmony_ci } 8954141cc406Sopenharmony_ci 8955141cc406Sopenharmony_ci 8956141cc406Sopenharmony_ci /* wait for the data to be ready */ 8957141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 8958141cc406Sopenharmony_ci gettimeofday (&td, NULL); 8959141cc406Sopenharmony_ci#endif 8960141cc406Sopenharmony_ci while ((reg & 0x08) == 0x08) 8961141cc406Sopenharmony_ci { 8962141cc406Sopenharmony_ci reg = registerRead (0x19) & 0xF8; 8963141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 8964141cc406Sopenharmony_ci gettimeofday (&tf, NULL); 8965141cc406Sopenharmony_ci elapsed = 8966141cc406Sopenharmony_ci ((tf.tv_sec * 1000000 + tf.tv_usec) - 8967141cc406Sopenharmony_ci (td.tv_sec * 1000000 + td.tv_usec)) / 1000000; 8968141cc406Sopenharmony_ci if (elapsed > 3) 8969141cc406Sopenharmony_ci { 8970141cc406Sopenharmony_ci DBG 8971141cc406Sopenharmony_ci (0, 8972141cc406Sopenharmony_ci "Time-out (%.2f s) waiting for scanner ... giving up on status 0x%02X ! (%s:%d)\n", 8973141cc406Sopenharmony_ci elapsed, reg, __FILE__, __LINE__); 8974141cc406Sopenharmony_ci epilogue (); 8975141cc406Sopenharmony_ci return read; 8976141cc406Sopenharmony_ci } 8977141cc406Sopenharmony_ci#endif 8978141cc406Sopenharmony_ci } 8979141cc406Sopenharmony_ci if ((reg != 0xC0) && (reg != 0xD0) && (reg != 0x00)) 8980141cc406Sopenharmony_ci { 8981141cc406Sopenharmony_ci DBG (0, "Unexpected status 0x%02X, expected 0xC0 or 0xD0 ! (%s:%d)\n", 8982141cc406Sopenharmony_ci reg, __FILE__, __LINE__); 8983141cc406Sopenharmony_ci DBG (0, "Going on...\n"); 8984141cc406Sopenharmony_ci } 8985141cc406Sopenharmony_ci 8986141cc406Sopenharmony_ci REGISTERWRITE (0x0E, 0x0D); 8987141cc406Sopenharmony_ci REGISTERWRITE (0x0F, 0x00); 8988141cc406Sopenharmony_ci 8989141cc406Sopenharmony_ci 8990141cc406Sopenharmony_ci /* OK ! */ 8991141cc406Sopenharmony_ci epilogue (); 8992141cc406Sopenharmony_ci return read; 8993141cc406Sopenharmony_ci} 8994141cc406Sopenharmony_ci 8995141cc406Sopenharmony_ci/* 8996141cc406Sopenharmony_ci * encodes DC offsets: must be in [0..0x0F] range 8997141cc406Sopenharmony_ci */ 8998141cc406Sopenharmony_cistatic void 8999141cc406Sopenharmony_ciencodeDC (int dcRed, int dcGreen, int dcBlue, int *motor) 9000141cc406Sopenharmony_ci{ 9001141cc406Sopenharmony_ci motor[11] = (motor[11] & 0x0F) | dcRed << 4; 9002141cc406Sopenharmony_ci motor[12] = (motor[12] & 0xC3) | dcGreen << 2; 9003141cc406Sopenharmony_ci motor[13] = (motor[13] & 0xF0) | dcBlue; 9004141cc406Sopenharmony_ci} 9005141cc406Sopenharmony_ci 9006141cc406Sopenharmony_cistatic void 9007141cc406Sopenharmony_cidecodeDC (int *motor) 9008141cc406Sopenharmony_ci{ 9009141cc406Sopenharmony_ci DBG (0, "DC (R,G,B)=(%d,%d,%d)\n", 9010141cc406Sopenharmony_ci (motor[11] & 0xF0) >> 4, (motor[12] & 0x3C) >> 2, motor[13] & 0x0F); 9011141cc406Sopenharmony_ci} 9012141cc406Sopenharmony_ci 9013141cc406Sopenharmony_ci 9014141cc406Sopenharmony_ci/* 9015141cc406Sopenharmony_ci * encodes VGA : must be in [0..0x0F] range 9016141cc406Sopenharmony_ci */ 9017141cc406Sopenharmony_cistatic void 9018141cc406Sopenharmony_ciencodeVGA (int vgaRed, int vgaGreen, int vgaBlue, int *motor) 9019141cc406Sopenharmony_ci{ 9020141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () > 610) 9021141cc406Sopenharmony_ci { 9022141cc406Sopenharmony_ci motor[10] = (vgaRed << 4) | vgaGreen; 9023141cc406Sopenharmony_ci motor[11] = (motor[11] & 0xF0) | vgaBlue; 9024141cc406Sopenharmony_ci } 9025141cc406Sopenharmony_ci else 9026141cc406Sopenharmony_ci { 9027141cc406Sopenharmony_ci motor[10] = (vgaGreen << 4) | vgaBlue; 9028141cc406Sopenharmony_ci motor[11] = (motor[11] & 0xF0) | vgaRed; 9029141cc406Sopenharmony_ci /* ancien 9030141cc406Sopenharmony_ci F00: vert 9031141cc406Sopenharmony_ci 0F0: bleu 9032141cc406Sopenharmony_ci 00F: rouge 9033141cc406Sopenharmony_ci motor[10] = (vgaRed << 4) | vgaGreen; 9034141cc406Sopenharmony_ci motor[11] = (motor[11] & 0xF0) | vgaBlue; */ 9035141cc406Sopenharmony_ci } 9036141cc406Sopenharmony_ci} 9037141cc406Sopenharmony_ci 9038141cc406Sopenharmony_cistatic void 9039141cc406Sopenharmony_cidecodeVGA (int *motor) 9040141cc406Sopenharmony_ci{ 9041141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () > 610) 9042141cc406Sopenharmony_ci { 9043141cc406Sopenharmony_ci DBG (0, "VGA (R,G,B)=(%d,%d,%d)\n", 9044141cc406Sopenharmony_ci (motor[10] & 0xF0) >> 4, (motor[10] & 0x0F), (motor[11] & 0x0F)); 9045141cc406Sopenharmony_ci } 9046141cc406Sopenharmony_ci else 9047141cc406Sopenharmony_ci { 9048141cc406Sopenharmony_ci DBG (0, "VGA (R,G,B)=(%d,%d,%d)\n", 9049141cc406Sopenharmony_ci (motor[11] & 0x0F), (motor[10] & 0xF0) >> 4, (motor[10] & 0x0F)); 9050141cc406Sopenharmony_ci } 9051141cc406Sopenharmony_ci} 9052141cc406Sopenharmony_ci 9053141cc406Sopenharmony_ci/* 9054141cc406Sopenharmony_ci * this function encodes total head movement which includes 9055141cc406Sopenharmony_ci * y movement and scan area height 9056141cc406Sopenharmony_ci * height is scan area height 9057141cc406Sopenharmony_ci * ypos is head movement before scan 9058141cc406Sopenharmony_ci * total move will be ypos+height */ 9059141cc406Sopenharmony_cistatic void 9060141cc406Sopenharmony_ciencodeHY (int height, int ypos, int *motor) 9061141cc406Sopenharmony_ci{ 9062141cc406Sopenharmony_ci motor[0] = height % 256; 9063141cc406Sopenharmony_ci motor[1] = (height / 256) & 0x3F; 9064141cc406Sopenharmony_ci motor[1] = motor[1] | (ypos & 0x03) << 6; 9065141cc406Sopenharmony_ci motor[2] = (ypos >> 2) % 256; 9066141cc406Sopenharmony_ci motor[3] = (motor[3] & 0xF0) | ((ypos >> 10) & 0x0F); 9067141cc406Sopenharmony_ci} 9068141cc406Sopenharmony_ci 9069141cc406Sopenharmony_ci/* 9070141cc406Sopenharmony_ci * this function encodes x start and x end on the CCD 9071141cc406Sopenharmony_ci * w is width of scanning area 9072141cc406Sopenharmony_ci * x is start of scanning area 9073141cc406Sopenharmony_ci * dpi is x resolution 9074141cc406Sopenharmony_ci * color is non zero if scanning in color 9075141cc406Sopenharmony_ci * bytes is on aoverride for bpl, since it sin't clear today when 9076141cc406Sopenharmony_ci * the formula has to be applied 9077141cc406Sopenharmony_ci */ 9078141cc406Sopenharmony_cistatic void 9079141cc406Sopenharmony_ciencodeWX (int width, int xstart, int dpi, int color, int *ccd, int bytes) 9080141cc406Sopenharmony_ci{ 9081141cc406Sopenharmony_ci int xend; 9082141cc406Sopenharmony_ci int bpl; 9083141cc406Sopenharmony_ci int x; 9084141cc406Sopenharmony_ci 9085141cc406Sopenharmony_ci xend = xstart + width; 9086141cc406Sopenharmony_ci x = xstart - 1; 9087141cc406Sopenharmony_ci 9088141cc406Sopenharmony_ci /* x start encoding */ 9089141cc406Sopenharmony_ci ccd[17] = x % 256; 9090141cc406Sopenharmony_ci ccd[18] = (ccd[18] & 0xF0) | ((x / 256) & 0x0F); 9091141cc406Sopenharmony_ci /* models >=1220P have a 600 dpi CCD: x is bigger */ 9092141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () > 610) 9093141cc406Sopenharmony_ci { 9094141cc406Sopenharmony_ci if (x > 0x1000) 9095141cc406Sopenharmony_ci ccd[33] |= 0x40; 9096141cc406Sopenharmony_ci else 9097141cc406Sopenharmony_ci ccd[33] &= 0xBF; 9098141cc406Sopenharmony_ci } 9099141cc406Sopenharmony_ci 9100141cc406Sopenharmony_ci /* x end encoding */ 9101141cc406Sopenharmony_ci ccd[18] = (ccd[18] & 0x0F) | ((xend % 16) << 4); 9102141cc406Sopenharmony_ci ccd[19] = (xend / 16) % 256; 9103141cc406Sopenharmony_ci /* models >=1220P have a 600 dpi CCD: x is bigger */ 9104141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () > 610) 9105141cc406Sopenharmony_ci { 9106141cc406Sopenharmony_ci if (xend > 0x1000) 9107141cc406Sopenharmony_ci ccd[33] |= 0x80; 9108141cc406Sopenharmony_ci else 9109141cc406Sopenharmony_ci ccd[33] &= 0x7F; 9110141cc406Sopenharmony_ci } 9111141cc406Sopenharmony_ci 9112141cc406Sopenharmony_ci /* now bytes per line */ 9113141cc406Sopenharmony_ci /* bpl = (op[24] - 0x41) * 256 + 8192 * (op[34] & 0x01) + op[23]; */ 9114141cc406Sopenharmony_ci bpl = (color == 0 ? 1 : 3) * width * dpi; 9115141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () > 610) 9116141cc406Sopenharmony_ci { 9117141cc406Sopenharmony_ci bpl /= 600; 9118141cc406Sopenharmony_ci if (bpl >= 8192) 9119141cc406Sopenharmony_ci ccd[34] |= 0x01; 9120141cc406Sopenharmony_ci else 9121141cc406Sopenharmony_ci ccd[34] &= 0xFE; 9122141cc406Sopenharmony_ci } 9123141cc406Sopenharmony_ci else 9124141cc406Sopenharmony_ci { 9125141cc406Sopenharmony_ci bpl /= 300; 9126141cc406Sopenharmony_ci } 9127141cc406Sopenharmony_ci if (bytes > 0) 9128141cc406Sopenharmony_ci bpl = bytes; 9129141cc406Sopenharmony_ci ccd[23] = bpl % 256; 9130141cc406Sopenharmony_ci ccd[24] = 0x41 + ((bpl / 256) & 0x1F); 9131141cc406Sopenharmony_ci} 9132141cc406Sopenharmony_ci 9133141cc406Sopenharmony_ci /* cropping coefficient: last 2 bytes gives the coefficient applied */ 9134141cc406Sopenharmony_ci /* to data scanned to get the actual image resolution */ 9135141cc406Sopenharmony_cistatic void 9136141cc406Sopenharmony_ciencodeCoefficient (int color, int dpi, int *calibration) 9137141cc406Sopenharmony_ci{ 9138141cc406Sopenharmony_ci int w, idx = 0; 9139141cc406Sopenharmony_ci int *coeff; 9140141cc406Sopenharmony_ci 9141141cc406Sopenharmony_ci /* 75, 150, 300, 600 and 1200 dpi */ 9142141cc406Sopenharmony_ci int color610p[4][2] = 9143141cc406Sopenharmony_ci { {0x88, 0x88}, {0xAA, 0xAA}, {0xFF, 0xFF}, {0xFF, 0xFF} }; 9144141cc406Sopenharmony_ci int gray610p[4][2] = 9145141cc406Sopenharmony_ci { {0x88, 0x01}, {0xAA, 0x11}, {0xFF, 0xAA}, {0xFF, 0xFF} }; 9146141cc406Sopenharmony_ci 9147141cc406Sopenharmony_ci /* FF means coeff=1 9148141cc406Sopenharmony_ci * AA coeff=1/2 9149141cc406Sopenharmony_ci * 88 coeff=1/4 9150141cc406Sopenharmony_ci * 80 coeff=1/8 9151141cc406Sopenharmony_ci * first coeff for CCD (x) 9152141cc406Sopenharmony_ci * second coeff for motor steps (y) 9153141cc406Sopenharmony_ci */ 9154141cc406Sopenharmony_ci int color1220p[5][2] = 9155141cc406Sopenharmony_ci { {0x80, 0xAA}, {0x88, 0xFF}, {0xAA, 0xFF}, {0xFF, 0xFF}, {0xFF, 0xFF} }; 9156141cc406Sopenharmony_ci int gray1220p[5][2] = 9157141cc406Sopenharmony_ci { {0x80, 0x88}, {0x88, 0xAA}, {0xAA, 0xFF}, {0xFF, 0xFF}, {0xFF, 0xFF} }; 9158141cc406Sopenharmony_ci 9159141cc406Sopenharmony_ci switch (dpi) 9160141cc406Sopenharmony_ci { 9161141cc406Sopenharmony_ci case 1200: 9162141cc406Sopenharmony_ci idx = 4; 9163141cc406Sopenharmony_ci break; 9164141cc406Sopenharmony_ci case 600: 9165141cc406Sopenharmony_ci idx = 3; 9166141cc406Sopenharmony_ci break; 9167141cc406Sopenharmony_ci case 300: 9168141cc406Sopenharmony_ci idx = 2; 9169141cc406Sopenharmony_ci break; 9170141cc406Sopenharmony_ci case 150: 9171141cc406Sopenharmony_ci idx = 1; 9172141cc406Sopenharmony_ci break; 9173141cc406Sopenharmony_ci case 75: 9174141cc406Sopenharmony_ci idx = 0; 9175141cc406Sopenharmony_ci break; 9176141cc406Sopenharmony_ci } 9177141cc406Sopenharmony_ci 9178141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1210) 9179141cc406Sopenharmony_ci { 9180141cc406Sopenharmony_ci w = 2550; 9181141cc406Sopenharmony_ci if (color >= RGB_MODE) 9182141cc406Sopenharmony_ci coeff = color610p[idx]; 9183141cc406Sopenharmony_ci else 9184141cc406Sopenharmony_ci coeff = gray610p[idx]; 9185141cc406Sopenharmony_ci } 9186141cc406Sopenharmony_ci else 9187141cc406Sopenharmony_ci { 9188141cc406Sopenharmony_ci w = 5100; 9189141cc406Sopenharmony_ci if (color >= RGB_MODE) 9190141cc406Sopenharmony_ci coeff = color1220p[idx]; 9191141cc406Sopenharmony_ci else 9192141cc406Sopenharmony_ci coeff = gray1220p[idx]; 9193141cc406Sopenharmony_ci } 9194141cc406Sopenharmony_ci 9195141cc406Sopenharmony_ci /* x coefficient */ 9196141cc406Sopenharmony_ci calibration[3 * w + 768] = coeff[0]; 9197141cc406Sopenharmony_ci 9198141cc406Sopenharmony_ci /* y coefficient */ 9199141cc406Sopenharmony_ci calibration[3 * w + 769] = coeff[1]; 9200141cc406Sopenharmony_ci} 9201141cc406Sopenharmony_ci 9202141cc406Sopenharmony_ci 9203141cc406Sopenharmony_cistatic void 9204141cc406Sopenharmony_cibloc2Decode (int *op) 9205141cc406Sopenharmony_ci{ 9206141cc406Sopenharmony_ci int i; 9207141cc406Sopenharmony_ci int scanh; 9208141cc406Sopenharmony_ci int skiph; 9209141cc406Sopenharmony_ci int dpi = 0; 9210141cc406Sopenharmony_ci int dir = 0; 9211141cc406Sopenharmony_ci int color = 0; 9212141cc406Sopenharmony_ci char str[64]; 9213141cc406Sopenharmony_ci 9214141cc406Sopenharmony_ci for (i = 0; i < 16; i++) 9215141cc406Sopenharmony_ci sprintf (str + 3 * i, "%02X ", (unsigned char) op[i]); 9216141cc406Sopenharmony_ci str[48] = 0x00; 9217141cc406Sopenharmony_ci DBG (0, "Command block 2: %s\n", str); 9218141cc406Sopenharmony_ci 9219141cc406Sopenharmony_ci 9220141cc406Sopenharmony_ci scanh = op[0] + (op[1] & 0x3F) * 256; 9221141cc406Sopenharmony_ci skiph = ((op[1] & 0xC0) >> 6) + (op[2] << 2) + ((op[3] & 0x0F) << 10); 9222141cc406Sopenharmony_ci 9223141cc406Sopenharmony_ci if (op[3] & 0x10) 9224141cc406Sopenharmony_ci dir = 1; 9225141cc406Sopenharmony_ci else 9226141cc406Sopenharmony_ci dir = 0; 9227141cc406Sopenharmony_ci 9228141cc406Sopenharmony_ci /* XXX STEF XXX seems to conflict with DC definitions */ 9229141cc406Sopenharmony_ci if (op[13] & 0x40) 9230141cc406Sopenharmony_ci color = 1; 9231141cc406Sopenharmony_ci else 9232141cc406Sopenharmony_ci color = 0; 9233141cc406Sopenharmony_ci 9234141cc406Sopenharmony_ci /* op[6]=0x60 at 600 and 1200 dpi */ 9235141cc406Sopenharmony_ci if ((op[8] == 0x17) && (op[9] != 0x05)) 9236141cc406Sopenharmony_ci dpi = 150; 9237141cc406Sopenharmony_ci if ((op[8] == 0x17) && (op[9] == 0x05)) 9238141cc406Sopenharmony_ci dpi = 300; 9239141cc406Sopenharmony_ci if ((op[9] == 0x05) && (op[14] & 0x08)) 9240141cc406Sopenharmony_ci dpi = 1200; 9241141cc406Sopenharmony_ci if ((dpi == 0) && ((op[14] & 0x08) == 0)) 9242141cc406Sopenharmony_ci dpi = 600; 9243141cc406Sopenharmony_ci 9244141cc406Sopenharmony_ci 9245141cc406Sopenharmony_ci 9246141cc406Sopenharmony_ci DBG (0, "\t->scan height =0x%04X (%d)\n", scanh, scanh); 9247141cc406Sopenharmony_ci DBG (0, "\t->skip height =0x%04X (%d)\n", skiph, skiph); 9248141cc406Sopenharmony_ci DBG (0, "\t->y dpi =0x%04X (%d)\n", dpi, dpi); 9249141cc406Sopenharmony_ci decodeVGA (op); 9250141cc406Sopenharmony_ci decodeDC (op); 9251141cc406Sopenharmony_ci if (dir) 9252141cc406Sopenharmony_ci DBG (0, "\t->forward direction\n"); 9253141cc406Sopenharmony_ci else 9254141cc406Sopenharmony_ci DBG (0, "\t->reverse direction\n"); 9255141cc406Sopenharmony_ci if (color) 9256141cc406Sopenharmony_ci DBG (0, "\t->color scan \n"); 9257141cc406Sopenharmony_ci else 9258141cc406Sopenharmony_ci DBG (0, "\t->no color scan \n"); 9259141cc406Sopenharmony_ci 9260141cc406Sopenharmony_ci /* byte 14 */ 9261141cc406Sopenharmony_ci if (op[14] & 0x20) 9262141cc406Sopenharmony_ci { 9263141cc406Sopenharmony_ci DBG (0, "\t->lamp on \n"); 9264141cc406Sopenharmony_ci } 9265141cc406Sopenharmony_ci else 9266141cc406Sopenharmony_ci { 9267141cc406Sopenharmony_ci DBG (0, "\t->lamp off \n"); 9268141cc406Sopenharmony_ci } 9269141cc406Sopenharmony_ci if (op[14] & 0x04) 9270141cc406Sopenharmony_ci { 9271141cc406Sopenharmony_ci DBG (0, "\t->normal scan (head stops at each row) \n"); 9272141cc406Sopenharmony_ci } 9273141cc406Sopenharmony_ci else 9274141cc406Sopenharmony_ci { 9275141cc406Sopenharmony_ci DBG (0, "\t->move and scan (head doesn't stop at each row) \n"); 9276141cc406Sopenharmony_ci } 9277141cc406Sopenharmony_ci DBG (0, "\n"); 9278141cc406Sopenharmony_ci} 9279141cc406Sopenharmony_ci 9280141cc406Sopenharmony_ci 9281141cc406Sopenharmony_cistatic void 9282141cc406Sopenharmony_cibloc8Decode (int *op) 9283141cc406Sopenharmony_ci{ 9284141cc406Sopenharmony_ci int i, bpl; 9285141cc406Sopenharmony_ci int xskip; 9286141cc406Sopenharmony_ci int xend, len; 9287141cc406Sopenharmony_ci char str[128]; 9288141cc406Sopenharmony_ci 9289141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1220) 9290141cc406Sopenharmony_ci len = 34; 9291141cc406Sopenharmony_ci else 9292141cc406Sopenharmony_ci len = 36; 9293141cc406Sopenharmony_ci for (i = 0; i < len; i++) 9294141cc406Sopenharmony_ci sprintf (str + 3 * i, "%02X ", (unsigned char) op[i]); 9295141cc406Sopenharmony_ci str[3 * i] = 0x00; 9296141cc406Sopenharmony_ci DBG (0, "Command block 8: %s\n", str); 9297141cc406Sopenharmony_ci 9298141cc406Sopenharmony_ci xskip = op[17] + 256 * (op[18] & 0x0F); 9299141cc406Sopenharmony_ci if (op[33] & 0x40) 9300141cc406Sopenharmony_ci xskip += 0x1000; 9301141cc406Sopenharmony_ci xend = (op[18] & 0xF0) / 16 + 16 * op[19]; 9302141cc406Sopenharmony_ci if (op[33] & 0x80) 9303141cc406Sopenharmony_ci xend += 0x1000; 9304141cc406Sopenharmony_ci if (len > 34) 9305141cc406Sopenharmony_ci bpl = (op[24] - 0x41) * 256 + 8192 * (op[34] & 0x01) + op[23]; 9306141cc406Sopenharmony_ci else 9307141cc406Sopenharmony_ci bpl = (op[24] - 0x41) * 256 + op[23]; 9308141cc406Sopenharmony_ci 9309141cc406Sopenharmony_ci DBG (0, "\t->xskip =0x%X (%d)\n", xskip, xskip); 9310141cc406Sopenharmony_ci DBG (0, "\t->xend =0x%X (%d)\n", xend, xend); 9311141cc406Sopenharmony_ci DBG (0, "\t->scan width=0x%X (%d)\n", xend - xskip - 1, xend - xskip - 1); 9312141cc406Sopenharmony_ci DBG (0, "\t->bytes/line=0x%X (%d)\n", bpl, bpl); 9313141cc406Sopenharmony_ci DBG (0, "\t->raw =0x%X (%d)\n", op[24] * 256 + op[23], 9314141cc406Sopenharmony_ci op[24] * 256 + op[23]); 9315141cc406Sopenharmony_ci DBG (0, "\n"); 9316141cc406Sopenharmony_ci} 9317141cc406Sopenharmony_cistatic int 9318141cc406Sopenharmony_cicompletionWait (void) 9319141cc406Sopenharmony_ci{ 9320141cc406Sopenharmony_ci /* for 610P, wait and sync is done while 9321141cc406Sopenharmony_ci * reading data from the scanner */ 9322141cc406Sopenharmony_ci CMDSYNC (0x40); 9323141cc406Sopenharmony_ci usleep (100000); 9324141cc406Sopenharmony_ci CMDSYNC (0xC2); 9325141cc406Sopenharmony_ci if ((sanei_umax_pp_getastra () == 610) 9326141cc406Sopenharmony_ci || ((sanei_umax_pp_scannerStatus () & 0x90) == 0x90)) 9327141cc406Sopenharmony_ci return 1; 9328141cc406Sopenharmony_ci do 9329141cc406Sopenharmony_ci { 9330141cc406Sopenharmony_ci usleep (100000); 9331141cc406Sopenharmony_ci CMDSYNC (0xC2); 9332141cc406Sopenharmony_ci } 9333141cc406Sopenharmony_ci while ((sanei_umax_pp_scannerStatus () & 0x90) != 0x90); 9334141cc406Sopenharmony_ci CMDSYNC (0xC2); 9335141cc406Sopenharmony_ci return 1; 9336141cc406Sopenharmony_ci} 9337141cc406Sopenharmony_ci 9338141cc406Sopenharmony_ciint 9339141cc406Sopenharmony_cisanei_umax_pp_setLamp (int on) 9340141cc406Sopenharmony_ci{ 9341141cc406Sopenharmony_ci int buffer[17]; 9342141cc406Sopenharmony_ci int state; 9343141cc406Sopenharmony_ci 9344141cc406Sopenharmony_ci /* reset? */ 9345141cc406Sopenharmony_ci sanei_umax_pp_cmdSync (0x00); 9346141cc406Sopenharmony_ci sanei_umax_pp_cmdSync (0xC2); 9347141cc406Sopenharmony_ci sanei_umax_pp_cmdSync (0x00); 9348141cc406Sopenharmony_ci 9349141cc406Sopenharmony_ci /* get status */ 9350141cc406Sopenharmony_ci cmdGet (0x02, 16, buffer); 9351141cc406Sopenharmony_ci state = buffer[14] & LAMP_STATE; 9352141cc406Sopenharmony_ci buffer[16] = -1; 9353141cc406Sopenharmony_ci if ((state == 0) && (on == 0)) 9354141cc406Sopenharmony_ci { 9355141cc406Sopenharmony_ci DBG (0, "Lamp already off ... (%s:%d)\n", __FILE__, __LINE__); 9356141cc406Sopenharmony_ci return 1; 9357141cc406Sopenharmony_ci } 9358141cc406Sopenharmony_ci if ((state) && (on)) 9359141cc406Sopenharmony_ci { 9360141cc406Sopenharmony_ci DBG (2, "Lamp already on ... (%s:%d)\n", __FILE__, __LINE__); 9361141cc406Sopenharmony_ci return 1; 9362141cc406Sopenharmony_ci } 9363141cc406Sopenharmony_ci 9364141cc406Sopenharmony_ci /* set lamp state */ 9365141cc406Sopenharmony_ci if (on) 9366141cc406Sopenharmony_ci buffer[14] = buffer[14] | LAMP_STATE; 9367141cc406Sopenharmony_ci else 9368141cc406Sopenharmony_ci buffer[14] = buffer[14] & ~LAMP_STATE; 9369141cc406Sopenharmony_ci CMDSETGET (0x02, 16, buffer); 9370141cc406Sopenharmony_ci TRACE (16, "setLamp passed ..."); 9371141cc406Sopenharmony_ci return 1; 9372141cc406Sopenharmony_ci} 9373141cc406Sopenharmony_ci 9374141cc406Sopenharmony_cistatic int num = 0; 9375141cc406Sopenharmony_cistatic void 9376141cc406Sopenharmony_ciDump (int len, unsigned char *data, char *name) 9377141cc406Sopenharmony_ci{ 9378141cc406Sopenharmony_ci FILE *fic; 9379141cc406Sopenharmony_ci char titre[80]; 9380141cc406Sopenharmony_ci 9381141cc406Sopenharmony_ci if (name == NULL) 9382141cc406Sopenharmony_ci { 9383141cc406Sopenharmony_ci sprintf (titre, "dump%04d.bin", num); 9384141cc406Sopenharmony_ci num++; 9385141cc406Sopenharmony_ci } 9386141cc406Sopenharmony_ci else 9387141cc406Sopenharmony_ci { 9388141cc406Sopenharmony_ci sprintf (titre, "%s", name); 9389141cc406Sopenharmony_ci } 9390141cc406Sopenharmony_ci fic = fopen (titre, "wb"); 9391141cc406Sopenharmony_ci if (fic == NULL) 9392141cc406Sopenharmony_ci { 9393141cc406Sopenharmony_ci DBG (0, "could not open %s for writing\n", titre); 9394141cc406Sopenharmony_ci return; 9395141cc406Sopenharmony_ci } 9396141cc406Sopenharmony_ci fwrite (data, 1, len, fic); 9397141cc406Sopenharmony_ci fclose (fic); 9398141cc406Sopenharmony_ci} 9399141cc406Sopenharmony_ci 9400141cc406Sopenharmony_ci 9401141cc406Sopenharmony_cistatic void 9402141cc406Sopenharmony_ciDumpNB (int width, int height, unsigned char *data, char *name) 9403141cc406Sopenharmony_ci{ 9404141cc406Sopenharmony_ci FILE *fic; 9405141cc406Sopenharmony_ci char titre[80]; 9406141cc406Sopenharmony_ci 9407141cc406Sopenharmony_ci if (name == NULL) 9408141cc406Sopenharmony_ci { 9409141cc406Sopenharmony_ci sprintf (titre, "dump%04d.pnm", num); 9410141cc406Sopenharmony_ci num++; 9411141cc406Sopenharmony_ci } 9412141cc406Sopenharmony_ci else 9413141cc406Sopenharmony_ci { 9414141cc406Sopenharmony_ci sprintf (titre, "%s", name); 9415141cc406Sopenharmony_ci } 9416141cc406Sopenharmony_ci fic = fopen (titre, "wb"); 9417141cc406Sopenharmony_ci if (fic == NULL) 9418141cc406Sopenharmony_ci { 9419141cc406Sopenharmony_ci DBG (0, "could not open %s for writing\n", titre); 9420141cc406Sopenharmony_ci return; 9421141cc406Sopenharmony_ci } 9422141cc406Sopenharmony_ci fprintf (fic, "P5\n%d %d\n255\n", width, height); 9423141cc406Sopenharmony_ci fwrite (data, width, height, fic); 9424141cc406Sopenharmony_ci fclose (fic); 9425141cc406Sopenharmony_ci} 9426141cc406Sopenharmony_ci 9427141cc406Sopenharmony_ci 9428141cc406Sopenharmony_ci/* dump data has received from scanner (red line/green line/blue line) 9429141cc406Sopenharmony_ci to a color pnm file */ 9430141cc406Sopenharmony_cistatic void 9431141cc406Sopenharmony_ciDumpRVB (int width, int height, unsigned char *data, char *name) 9432141cc406Sopenharmony_ci{ 9433141cc406Sopenharmony_ci FILE *fic; 9434141cc406Sopenharmony_ci char titre[80]; 9435141cc406Sopenharmony_ci int y, x; 9436141cc406Sopenharmony_ci 9437141cc406Sopenharmony_ci if (name == NULL) 9438141cc406Sopenharmony_ci { 9439141cc406Sopenharmony_ci sprintf (titre, "dump%04d.pnm", num); 9440141cc406Sopenharmony_ci num++; 9441141cc406Sopenharmony_ci } 9442141cc406Sopenharmony_ci else 9443141cc406Sopenharmony_ci { 9444141cc406Sopenharmony_ci sprintf (titre, "%s", name); 9445141cc406Sopenharmony_ci } 9446141cc406Sopenharmony_ci fic = fopen (titre, "wb"); 9447141cc406Sopenharmony_ci if (fic == NULL) 9448141cc406Sopenharmony_ci { 9449141cc406Sopenharmony_ci DBG (0, "could not open %s for writing\n", titre); 9450141cc406Sopenharmony_ci return; 9451141cc406Sopenharmony_ci } 9452141cc406Sopenharmony_ci fprintf (fic, "P6\n%d %d\n255\n", width, height); 9453141cc406Sopenharmony_ci for (y = 0; y < height; y++) 9454141cc406Sopenharmony_ci { 9455141cc406Sopenharmony_ci for (x = 0; x < width; x++) 9456141cc406Sopenharmony_ci { 9457141cc406Sopenharmony_ci fputc (data[3 * y * width + 2 * width + x], fic); 9458141cc406Sopenharmony_ci fputc (data[3 * y * width + width + x], fic); 9459141cc406Sopenharmony_ci fputc (data[3 * y * width + x], fic); 9460141cc406Sopenharmony_ci } 9461141cc406Sopenharmony_ci } 9462141cc406Sopenharmony_ci fclose (fic); 9463141cc406Sopenharmony_ci} 9464141cc406Sopenharmony_ci 9465141cc406Sopenharmony_ci/* dump a color buffer in a color PNM */ 9466141cc406Sopenharmony_cistatic void 9467141cc406Sopenharmony_ciDumpRGB (int width, int height, unsigned char *data, char *name) 9468141cc406Sopenharmony_ci{ 9469141cc406Sopenharmony_ci FILE *fic; 9470141cc406Sopenharmony_ci char titre[80]; 9471141cc406Sopenharmony_ci int y, x; 9472141cc406Sopenharmony_ci 9473141cc406Sopenharmony_ci if (name == NULL) 9474141cc406Sopenharmony_ci { 9475141cc406Sopenharmony_ci sprintf (titre, "dump%04d.pnm", num); 9476141cc406Sopenharmony_ci num++; 9477141cc406Sopenharmony_ci } 9478141cc406Sopenharmony_ci else 9479141cc406Sopenharmony_ci { 9480141cc406Sopenharmony_ci sprintf (titre, "%s", name); 9481141cc406Sopenharmony_ci } 9482141cc406Sopenharmony_ci fic = fopen (titre, "wb"); 9483141cc406Sopenharmony_ci fprintf (fic, "P6\n%d %d\n255\n", width, height); 9484141cc406Sopenharmony_ci if (fic == NULL) 9485141cc406Sopenharmony_ci { 9486141cc406Sopenharmony_ci DBG (0, "could not open %s for writing\n", titre); 9487141cc406Sopenharmony_ci return; 9488141cc406Sopenharmony_ci } 9489141cc406Sopenharmony_ci for (y = 0; y < height; y++) 9490141cc406Sopenharmony_ci { 9491141cc406Sopenharmony_ci for (x = 0; x < width; x++) 9492141cc406Sopenharmony_ci { 9493141cc406Sopenharmony_ci fputc (data[3 * y * width + x * 3], fic); 9494141cc406Sopenharmony_ci fputc (data[3 * y * width + x * 3 + 1], fic); 9495141cc406Sopenharmony_ci fputc (data[3 * y * width + x * 3 + 2], fic); 9496141cc406Sopenharmony_ci } 9497141cc406Sopenharmony_ci } 9498141cc406Sopenharmony_ci fclose (fic); 9499141cc406Sopenharmony_ci} 9500141cc406Sopenharmony_ci 9501141cc406Sopenharmony_cistatic int 9502141cc406Sopenharmony_cievalGain (int sum, int count) 9503141cc406Sopenharmony_ci{ 9504141cc406Sopenharmony_ci int gn; 9505141cc406Sopenharmony_ci float pct; 9506141cc406Sopenharmony_ci float avg; 9507141cc406Sopenharmony_ci float area=50; 9508141cc406Sopenharmony_ci float coeff=2.5; 9509141cc406Sopenharmony_ci float cnst=0.9; 9510141cc406Sopenharmony_ci 9511141cc406Sopenharmony_ci 9512141cc406Sopenharmony_ci /* after ~ 60 * 10 scans , it looks like 1 step is a 0.57% increase */ 9513141cc406Sopenharmony_ci /* so we take the value and compute the percent increase to reach 250 */ 9514141cc406Sopenharmony_ci /* (target code) not 255, because we want some room for inaccuracy */ 9515141cc406Sopenharmony_ci /* pct=100-(value*100)/250 */ 9516141cc406Sopenharmony_ci /* then correction is pct/0.57 */ 9517141cc406Sopenharmony_ci avg = (float) (sum) / (float) (count); 9518141cc406Sopenharmony_ci pct = 100.0 - (avg * 100.0) / targetCode; 9519141cc406Sopenharmony_ci gn = (int) (pct / 0.57); 9520141cc406Sopenharmony_ci 9521141cc406Sopenharmony_ci /* give gain for dark areas a boost */ 9522141cc406Sopenharmony_ci#ifdef UMAX_PP_DANGEROUS_EXPERIMENT 9523141cc406Sopenharmony_ci if(getenv("AREA")!=NULL) 9524141cc406Sopenharmony_ci cnst=atol(getenv("AREA")); 9525141cc406Sopenharmony_ci if(getenv("COEFF")!=NULL) 9526141cc406Sopenharmony_ci cnst=atol(getenv("COEFF")); 9527141cc406Sopenharmony_ci if(getenv("CNST")!=NULL) 9528141cc406Sopenharmony_ci cnst=atol(getenv("CNST")); 9529141cc406Sopenharmony_ci#endif 9530141cc406Sopenharmony_ci 9531141cc406Sopenharmony_ci pct = gn; 9532141cc406Sopenharmony_ci avg = exp((-pct)/area)*coeff+cnst; 9533141cc406Sopenharmony_ci gn = gn * avg; 9534141cc406Sopenharmony_ci 9535141cc406Sopenharmony_ci /* bound checking : there are sightings of >127 values being negative */ 9536141cc406Sopenharmony_ci if (gn < 0) 9537141cc406Sopenharmony_ci gn = 0; 9538141cc406Sopenharmony_ci else if (gn > 127) 9539141cc406Sopenharmony_ci gn = 127; 9540141cc406Sopenharmony_ci return gn; 9541141cc406Sopenharmony_ci} 9542141cc406Sopenharmony_ci 9543141cc406Sopenharmony_cistatic void 9544141cc406Sopenharmony_cicomputeCalibrationData (int color, int width, unsigned char *source, 9545141cc406Sopenharmony_ci int *data) 9546141cc406Sopenharmony_ci{ 9547141cc406Sopenharmony_ci int p, i, l; 9548141cc406Sopenharmony_ci int sum; 9549141cc406Sopenharmony_ci 9550141cc406Sopenharmony_ci 9551141cc406Sopenharmony_ci memset (data, 0, (3 * 5100 + 768 + 3) * sizeof (int)); 9552141cc406Sopenharmony_ci 9553141cc406Sopenharmony_ci 9554141cc406Sopenharmony_ci /* 0 -> 5099 */ 9555141cc406Sopenharmony_ci for (i = 0; i < width; i++) 9556141cc406Sopenharmony_ci { /* red calibration data */ 9557141cc406Sopenharmony_ci if (color >= RGB_MODE) 9558141cc406Sopenharmony_ci { 9559141cc406Sopenharmony_ci /* compute average */ 9560141cc406Sopenharmony_ci sum = 0; 9561141cc406Sopenharmony_ci for (l = 0; l < 66; l++) 9562141cc406Sopenharmony_ci sum += source[i + l * 5100 * 3]; 9563141cc406Sopenharmony_ci data[i] = evalGain (sum, l); 9564141cc406Sopenharmony_ci } 9565141cc406Sopenharmony_ci else 9566141cc406Sopenharmony_ci data[i] = 0x00; 9567141cc406Sopenharmony_ci } 9568141cc406Sopenharmony_ci 9569141cc406Sopenharmony_ci 9570141cc406Sopenharmony_ci /* 5100 -> 10199: green data */ 9571141cc406Sopenharmony_ci p = 5100; 9572141cc406Sopenharmony_ci for (i = 0; i < width; i++) 9573141cc406Sopenharmony_ci { 9574141cc406Sopenharmony_ci /* compute average */ 9575141cc406Sopenharmony_ci sum = 0; 9576141cc406Sopenharmony_ci for (l = 0; l < 66; l++) 9577141cc406Sopenharmony_ci sum += source[i + l * 5100 * 3 + 5100]; 9578141cc406Sopenharmony_ci data[p + i] = evalGain (sum, l); 9579141cc406Sopenharmony_ci } 9580141cc406Sopenharmony_ci 9581141cc406Sopenharmony_ci 9582141cc406Sopenharmony_ci /* 10200 -> 15299: blue */ 9583141cc406Sopenharmony_ci p = 10200; 9584141cc406Sopenharmony_ci for (i = 0; i < width; i++) 9585141cc406Sopenharmony_ci { 9586141cc406Sopenharmony_ci if (color >= RGB_MODE) 9587141cc406Sopenharmony_ci { 9588141cc406Sopenharmony_ci /* compute average */ 9589141cc406Sopenharmony_ci sum = 0; 9590141cc406Sopenharmony_ci for (l = 0; l < 66; l++) 9591141cc406Sopenharmony_ci sum += source[i + l * 5100 * 3 + 5100 * 2]; 9592141cc406Sopenharmony_ci data[p + i] = evalGain (sum, l); 9593141cc406Sopenharmony_ci } 9594141cc406Sopenharmony_ci else 9595141cc406Sopenharmony_ci data[p + i] = 0x00; 9596141cc406Sopenharmony_ci } 9597141cc406Sopenharmony_ci 9598141cc406Sopenharmony_ci 9599141cc406Sopenharmony_ci /* gamma tables */ 9600141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 9601141cc406Sopenharmony_ci data[15300 + i] = ggRed[i]; 9602141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 9603141cc406Sopenharmony_ci data[15300 + 256 + i] = ggGreen[i]; 9604141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 9605141cc406Sopenharmony_ci data[15300 + 512 + i] = ggBlue[i]; 9606141cc406Sopenharmony_ci data[16070] = -1; 9607141cc406Sopenharmony_ci} 9608141cc406Sopenharmony_ci 9609141cc406Sopenharmony_ci 9610141cc406Sopenharmony_ci 9611141cc406Sopenharmony_ci/* move head by the distance given using precision or not */ 9612141cc406Sopenharmony_ci/* 0: failed 9613141cc406Sopenharmony_ci 1: success */ 9614141cc406Sopenharmony_cistatic int 9615141cc406Sopenharmony_cimove (int distance, int precision, unsigned char *buffer) 9616141cc406Sopenharmony_ci{ 9617141cc406Sopenharmony_ci int header[17] = { 9618141cc406Sopenharmony_ci 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x2F, 9619141cc406Sopenharmony_ci 0x2F, 0x01, 0x00, 0x00, 0x00, 0x80, 0xA4, 0x00, 9620141cc406Sopenharmony_ci -1 9621141cc406Sopenharmony_ci }; 9622141cc406Sopenharmony_ci int body[37] = { 9623141cc406Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9624141cc406Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 9625141cc406Sopenharmony_ci 0x6E, 0xF6, 0x79, 0xBF, 0x01, 0x00, 0x00, 0x00, 9626141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 9627141cc406Sopenharmony_ci 0xDF, 0x13, 0x1A, 0x00, 9628141cc406Sopenharmony_ci -1 9629141cc406Sopenharmony_ci }; 9630141cc406Sopenharmony_ci int end[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, -1 }; 9631141cc406Sopenharmony_ci int steps, len, cmdlen; 9632141cc406Sopenharmony_ci unsigned char tmp[0x200]; 9633141cc406Sopenharmony_ci unsigned char *ptr; 9634141cc406Sopenharmony_ci 9635141cc406Sopenharmony_ci if (distance == 0) 9636141cc406Sopenharmony_ci return 0; 9637141cc406Sopenharmony_ci 9638141cc406Sopenharmony_ci if (buffer == NULL) 9639141cc406Sopenharmony_ci ptr = tmp; 9640141cc406Sopenharmony_ci else 9641141cc406Sopenharmony_ci ptr = buffer; 9642141cc406Sopenharmony_ci 9643141cc406Sopenharmony_ci /* build commands */ 9644141cc406Sopenharmony_ci if (distance < 0) 9645141cc406Sopenharmony_ci { 9646141cc406Sopenharmony_ci /* header */ 9647141cc406Sopenharmony_ci steps = -distance - 1; 9648141cc406Sopenharmony_ci header[3] = 0x20; 9649141cc406Sopenharmony_ci header[9] = 0x01; 9650141cc406Sopenharmony_ci 9651141cc406Sopenharmony_ci /* reverse direction body by default */ 9652141cc406Sopenharmony_ci 9653141cc406Sopenharmony_ci /* end */ 9654141cc406Sopenharmony_ci end[1] = 0xFF; 9655141cc406Sopenharmony_ci end[2] = 0xFF; 9656141cc406Sopenharmony_ci end[3] = -1; 9657141cc406Sopenharmony_ci len = 3; 9658141cc406Sopenharmony_ci } 9659141cc406Sopenharmony_ci else 9660141cc406Sopenharmony_ci { 9661141cc406Sopenharmony_ci /* header */ 9662141cc406Sopenharmony_ci steps = distance - 1; 9663141cc406Sopenharmony_ci header[3] = 0x70; 9664141cc406Sopenharmony_ci header[9] = 0x05; 9665141cc406Sopenharmony_ci 9666141cc406Sopenharmony_ci /* body */ 9667141cc406Sopenharmony_ci body[2] = 0x04; 9668141cc406Sopenharmony_ci body[4] = 0x02; 9669141cc406Sopenharmony_ci body[7] = 0x0C; 9670141cc406Sopenharmony_ci body[9] = 0x04; 9671141cc406Sopenharmony_ci body[10] = 0x40; 9672141cc406Sopenharmony_ci body[11] = 0x01; 9673141cc406Sopenharmony_ci /* end */ 9674141cc406Sopenharmony_ci len = 8; 9675141cc406Sopenharmony_ci } 9676141cc406Sopenharmony_ci if (steps > 0) 9677141cc406Sopenharmony_ci { 9678141cc406Sopenharmony_ci encodeHY (1, steps, header); 9679141cc406Sopenharmony_ci } 9680141cc406Sopenharmony_ci 9681141cc406Sopenharmony_ci 9682141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1220) 9683141cc406Sopenharmony_ci { 9684141cc406Sopenharmony_ci header[6] = 0xC0; 9685141cc406Sopenharmony_ci 9686141cc406Sopenharmony_ci body[16] = 0x76; /* encodeWX */ 9687141cc406Sopenharmony_ci body[17] = 0x00; 9688141cc406Sopenharmony_ci body[18] = 0x15; 9689141cc406Sopenharmony_ci body[19] = 0x70; 9690141cc406Sopenharmony_ci body[20] = 0x01; 9691141cc406Sopenharmony_ci body[21] = 0x00; 9692141cc406Sopenharmony_ci 9693141cc406Sopenharmony_ci body[28] = 0x4D; 9694141cc406Sopenharmony_ci body[29] = 0x4B; 9695141cc406Sopenharmony_ci body[30] = 0xD0; 9696141cc406Sopenharmony_ci 9697141cc406Sopenharmony_ci cmdlen = 0x22; 9698141cc406Sopenharmony_ci } 9699141cc406Sopenharmony_ci else 9700141cc406Sopenharmony_ci cmdlen = 0x24; 9701141cc406Sopenharmony_ci 9702141cc406Sopenharmony_ci /* precision: default header set to precision on */ 9703141cc406Sopenharmony_ci if (precision == PRECISION_OFF) 9704141cc406Sopenharmony_ci { 9705141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 9706141cc406Sopenharmony_ci header[8] = 0x15; 9707141cc406Sopenharmony_ci else 9708141cc406Sopenharmony_ci header[8] = 0x17; 9709141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () > 610) 9710141cc406Sopenharmony_ci header[14] = 0xAC; 9711141cc406Sopenharmony_ci body[20] = 0x06; 9712141cc406Sopenharmony_ci } 9713141cc406Sopenharmony_ci CMDSETGET (0x02, 16, header); 9714141cc406Sopenharmony_ci CMDSETGET (0x08, cmdlen, body); 9715141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 9716141cc406Sopenharmony_ci { 9717141cc406Sopenharmony_ci bloc2Decode (header); 9718141cc406Sopenharmony_ci bloc8Decode (body); 9719141cc406Sopenharmony_ci } 9720141cc406Sopenharmony_ci CMDSYNC (0xC2); 9721141cc406Sopenharmony_ci if ((sanei_umax_pp_scannerStatus () & 0x80) 9722141cc406Sopenharmony_ci || (sanei_umax_pp_getastra () < 1220)) 9723141cc406Sopenharmony_ci { 9724141cc406Sopenharmony_ci CMDSYNC (0x00); 9725141cc406Sopenharmony_ci } 9726141cc406Sopenharmony_ci CMDSETGET (4, len, end); 9727141cc406Sopenharmony_ci COMPLETIONWAIT; 9728141cc406Sopenharmony_ci CMDGETBUF (4, 0x200, ptr); 9729141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 9730141cc406Sopenharmony_ci { 9731141cc406Sopenharmony_ci Dump (0x200, ptr, NULL); 9732141cc406Sopenharmony_ci } 9733141cc406Sopenharmony_ci DBG (16, "MOVE STATUS IS 0x%02X (%s:%d)\n", sanei_umax_pp_scannerStatus (), 9734141cc406Sopenharmony_ci __FILE__, __LINE__); 9735141cc406Sopenharmony_ci CMDSYNC (0x00); 9736141cc406Sopenharmony_ci return 1; 9737141cc406Sopenharmony_ci} 9738141cc406Sopenharmony_ci 9739141cc406Sopenharmony_ci 9740141cc406Sopenharmony_ci 9741141cc406Sopenharmony_ci/* for each column, finds the row where white/black transition occurs 9742141cc406Sopenharmony_ci then returns the average */ 9743141cc406Sopenharmony_cistatic float 9744141cc406Sopenharmony_ciedgePosition (int width, int height, unsigned char *data) 9745141cc406Sopenharmony_ci{ 9746141cc406Sopenharmony_ci int ecnt, x, y; 9747141cc406Sopenharmony_ci float epos; 9748141cc406Sopenharmony_ci int d, dmax, dpos, i; 9749141cc406Sopenharmony_ci unsigned char *dbuffer = NULL; 9750141cc406Sopenharmony_ci 9751141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 9752141cc406Sopenharmony_ci { 9753141cc406Sopenharmony_ci dbuffer = (unsigned char *) malloc (3 * width * height); 9754141cc406Sopenharmony_ci memset (dbuffer, 0x00, 3 * width * height); 9755141cc406Sopenharmony_ci } 9756141cc406Sopenharmony_ci epos = 0; 9757141cc406Sopenharmony_ci ecnt = 0; 9758141cc406Sopenharmony_ci for (x = 0; x < width; x++) 9759141cc406Sopenharmony_ci { 9760141cc406Sopenharmony_ci /* edge: white->black drop */ 9761141cc406Sopenharmony_ci /* loop stops on black area */ 9762141cc406Sopenharmony_ci dmax = 0; 9763141cc406Sopenharmony_ci dpos = 0; 9764141cc406Sopenharmony_ci d = 0; 9765141cc406Sopenharmony_ci i = 0; 9766141cc406Sopenharmony_ci for (y = 10; (y < height) && (data[i] > 10); y++) 9767141cc406Sopenharmony_ci { 9768141cc406Sopenharmony_ci i = x + y * width; 9769141cc406Sopenharmony_ci d = data[i - width] - data[i]; 9770141cc406Sopenharmony_ci if (d > dmax) 9771141cc406Sopenharmony_ci { 9772141cc406Sopenharmony_ci dmax = d; 9773141cc406Sopenharmony_ci dpos = y; 9774141cc406Sopenharmony_ci } 9775141cc406Sopenharmony_ci if ((DBG_LEVEL > 128) && (dbuffer != NULL)) 9776141cc406Sopenharmony_ci { 9777141cc406Sopenharmony_ci dbuffer[i * 3] = data[i]; 9778141cc406Sopenharmony_ci dbuffer[i * 3 + 1] = data[i]; 9779141cc406Sopenharmony_ci dbuffer[i * 3 + 2] = data[i]; 9780141cc406Sopenharmony_ci } 9781141cc406Sopenharmony_ci } 9782141cc406Sopenharmony_ci epos += dpos; 9783141cc406Sopenharmony_ci ecnt++; 9784141cc406Sopenharmony_ci if ((DBG_LEVEL > 128) && (dbuffer != NULL)) 9785141cc406Sopenharmony_ci { 9786141cc406Sopenharmony_ci dbuffer[(x + dpos * width) * 3] = 0xFF; 9787141cc406Sopenharmony_ci dbuffer[(x + dpos * width) * 3 + 1] = 0x00; 9788141cc406Sopenharmony_ci dbuffer[(x + dpos * width) * 3 + 2] = 0x00; 9789141cc406Sopenharmony_ci } 9790141cc406Sopenharmony_ci } 9791141cc406Sopenharmony_ci if (ecnt == 0) 9792141cc406Sopenharmony_ci epos = 70; 9793141cc406Sopenharmony_ci else 9794141cc406Sopenharmony_ci epos = epos / ecnt; 9795141cc406Sopenharmony_ci if ((DBG_LEVEL > 128) && (dbuffer != NULL)) 9796141cc406Sopenharmony_ci { 9797141cc406Sopenharmony_ci i = ((int) epos) * width; 9798141cc406Sopenharmony_ci for (x = 0; x < width; x++) 9799141cc406Sopenharmony_ci { 9800141cc406Sopenharmony_ci dbuffer[(x + i) * 3] = 0x00; 9801141cc406Sopenharmony_ci dbuffer[(x + i) * 3 + 1] = 0xFF; 9802141cc406Sopenharmony_ci dbuffer[(x + i) * 3 + 2] = 0xFF; 9803141cc406Sopenharmony_ci } 9804141cc406Sopenharmony_ci for (y = 0; y < height; y++) 9805141cc406Sopenharmony_ci { 9806141cc406Sopenharmony_ci dbuffer[(width / 2 + y * width) * 3] = 0x00; 9807141cc406Sopenharmony_ci dbuffer[(width / 2 + y * width) * 3 + 1] = 0xFF; 9808141cc406Sopenharmony_ci dbuffer[(width / 2 + y * width) * 3 + 2] = 0x00; 9809141cc406Sopenharmony_ci } 9810141cc406Sopenharmony_ci DumpRGB (width, height, dbuffer, NULL); 9811141cc406Sopenharmony_ci free (dbuffer); 9812141cc406Sopenharmony_ci } 9813141cc406Sopenharmony_ci return epos; 9814141cc406Sopenharmony_ci} 9815141cc406Sopenharmony_ci 9816141cc406Sopenharmony_ci 9817141cc406Sopenharmony_ci 9818141cc406Sopenharmony_cistatic int 9819141cc406Sopenharmony_cimoveToOrigin (void) 9820141cc406Sopenharmony_ci{ 9821141cc406Sopenharmony_ci unsigned char buffer[54000]; 9822141cc406Sopenharmony_ci float edge; 9823141cc406Sopenharmony_ci int val, delta = 188; 9824141cc406Sopenharmony_ci int header[17] = { 9825141cc406Sopenharmony_ci 0xB4, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x2F, 9826141cc406Sopenharmony_ci 0x2F, 0x05, 0x00, 0x00, 0x00, 0x80, 0xA4, 0x00, -1 9827141cc406Sopenharmony_ci }; 9828141cc406Sopenharmony_ci 9829141cc406Sopenharmony_ci int body[37] = { 9830141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 9831141cc406Sopenharmony_ci 0x00, 0x04, 0x40, 0x01, 0x00, 0x00, 0x04, 0x00, 9832141cc406Sopenharmony_ci 0x6E, 0xFB, 0xC4, 0xE5, 0x06, 0x00, 0x00, 0x60, 9833141cc406Sopenharmony_ci 0x4D, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 9834141cc406Sopenharmony_ci 0xDF, 0x13, 0x1A, 0x00, -1 9835141cc406Sopenharmony_ci }; 9836141cc406Sopenharmony_ci 9837141cc406Sopenharmony_ci int end[9] = { 9838141cc406Sopenharmony_ci 0x06, 0xF4, 0xFF, 0x81, 0x1B, 0x00, 0x08, 0x00, 9839141cc406Sopenharmony_ci -1 9840141cc406Sopenharmony_ci }; 9841141cc406Sopenharmony_ci int opsc03[9] = { 9842141cc406Sopenharmony_ci 0x00, 0x00, 0x00, 0xAA, 0xCC, 0xEE, 0x80, 0xFF, 9843141cc406Sopenharmony_ci -1 9844141cc406Sopenharmony_ci }; 9845141cc406Sopenharmony_ci int w = 300, h = 180, len = 36; 9846141cc406Sopenharmony_ci 9847141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 9848141cc406Sopenharmony_ci { 9849141cc406Sopenharmony_ci case 1600: 9850141cc406Sopenharmony_ci header[8] = 0x2B; 9851141cc406Sopenharmony_ci 9852141cc406Sopenharmony_ci body[29] = 0x1A; 9853141cc406Sopenharmony_ci body[30] = 0xEE; 9854141cc406Sopenharmony_ci 9855141cc406Sopenharmony_ci end[0] = 0x19; 9856141cc406Sopenharmony_ci end[1] = 0xD5; 9857141cc406Sopenharmony_ci end[4] = 0x1B; 9858141cc406Sopenharmony_ci // fall through 9859141cc406Sopenharmony_ci case 1220: 9860141cc406Sopenharmony_ci case 2000: 9861141cc406Sopenharmony_ci w = 300; 9862141cc406Sopenharmony_ci h = 180; 9863141cc406Sopenharmony_ci len = 36; 9864141cc406Sopenharmony_ci delta = -188; 9865141cc406Sopenharmony_ci CMDSYNC (0x00); 9866141cc406Sopenharmony_ci CMDSYNC (0xC2); 9867141cc406Sopenharmony_ci CMDSYNC (0x00); 9868141cc406Sopenharmony_ci MOVE (196, PRECISION_OFF, NULL); 9869141cc406Sopenharmony_ci break; 9870141cc406Sopenharmony_ci 9871141cc406Sopenharmony_ci case 610: 9872141cc406Sopenharmony_ci 9873141cc406Sopenharmony_ci w = 512; 9874141cc406Sopenharmony_ci h = 90; 9875141cc406Sopenharmony_ci len = 34; 9876141cc406Sopenharmony_ci delta = -81; 9877141cc406Sopenharmony_ci 9878141cc406Sopenharmony_ci opsc03[6] = 0xFF; /* instead of 0x80 */ 9879141cc406Sopenharmony_ci 9880141cc406Sopenharmony_ci encodeHY (h, 60, header); 9881141cc406Sopenharmony_ci 9882141cc406Sopenharmony_ci /* will add encodeDpi(dpi,cmd) */ 9883141cc406Sopenharmony_ci header[6] = 0xC0; 9884141cc406Sopenharmony_ci header[8] = 0x17; 9885141cc406Sopenharmony_ci 9886141cc406Sopenharmony_ci body[13] = 0x20; 9887141cc406Sopenharmony_ci body[14] = 0x02; 9888141cc406Sopenharmony_ci 9889141cc406Sopenharmony_ci body[16] = 0x76; 9890141cc406Sopenharmony_ci 9891141cc406Sopenharmony_ci encodeWX (0x200, 0x501, 300, 0, body, 0x500); 9892141cc406Sopenharmony_ci 9893141cc406Sopenharmony_ci /* fixed values for all 610p commands */ 9894141cc406Sopenharmony_ci body[28] = 0x4D; 9895141cc406Sopenharmony_ci body[29] = 0x4B; 9896141cc406Sopenharmony_ci body[30] = 0xD0; 9897141cc406Sopenharmony_ci 9898141cc406Sopenharmony_ci /* LM9811 command block ? */ 9899141cc406Sopenharmony_ci end[0] = 0x88; 9900141cc406Sopenharmony_ci end[1] = 0xE6; 9901141cc406Sopenharmony_ci end[2] = 0xFD; 9902141cc406Sopenharmony_ci end[3] = 0x8E; 9903141cc406Sopenharmony_ci end[4] = 0x30; 9904141cc406Sopenharmony_ci 9905141cc406Sopenharmony_ci break; 9906141cc406Sopenharmony_ci } 9907141cc406Sopenharmony_ci 9908141cc406Sopenharmony_ci 9909141cc406Sopenharmony_ci /* scan an area where is a white and a black regions, which */ 9910141cc406Sopenharmony_ci /* can be detected and gives this offset to the origin of the */ 9911141cc406Sopenharmony_ci /* scanning windows */ 9912141cc406Sopenharmony_ci CMDSETGET (2, 0x10, header); 9913141cc406Sopenharmony_ci CMDSETGET (8, len, body); 9914141cc406Sopenharmony_ci CMDSETGET (1, 0x08, end); 9915141cc406Sopenharmony_ci 9916141cc406Sopenharmony_ci CMDSYNC (0xC2); 9917141cc406Sopenharmony_ci CMDSYNC (0x00); 9918141cc406Sopenharmony_ci /* signals black & white ? */ 9919141cc406Sopenharmony_ci CMDSETGET (4, 8, opsc03); 9920141cc406Sopenharmony_ci COMPLETIONWAIT; 9921141cc406Sopenharmony_ci CMDGETBUF (4, w * h, buffer); /* get find position data */ 9922141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 9923141cc406Sopenharmony_ci { 9924141cc406Sopenharmony_ci DumpNB (w, h, buffer, NULL); 9925141cc406Sopenharmony_ci } 9926141cc406Sopenharmony_ci 9927141cc406Sopenharmony_ci /* detection of 1600P is a by product of origin finding */ 9928141cc406Sopenharmony_ci edge = 0.0; 9929141cc406Sopenharmony_ci for (val = 0; val < w * h; val++) 9930141cc406Sopenharmony_ci if (buffer[val] > edge) 9931141cc406Sopenharmony_ci edge = buffer[val]; 9932141cc406Sopenharmony_ci DBG (32, "MAX VALUE=%f (%s:%d)\n", edge, __FILE__, __LINE__); 9933141cc406Sopenharmony_ci if ((edge <= 30) && (sanei_umax_pp_getastra () != 1600)) 9934141cc406Sopenharmony_ci { 9935141cc406Sopenharmony_ci DBG (2, "moveToOrigin() detected a 1600P"); 9936141cc406Sopenharmony_ci sanei_umax_pp_setastra (1600); 9937141cc406Sopenharmony_ci } 9938141cc406Sopenharmony_ci edge = edgePosition (w, h, buffer); 9939141cc406Sopenharmony_ci /* rounded to lowest integer, since upping origin might lead */ 9940141cc406Sopenharmony_ci /* to bump in the other side if doing a full size preview */ 9941141cc406Sopenharmony_ci val = (int) (edge); 9942141cc406Sopenharmony_ci 9943141cc406Sopenharmony_ci delta += val; 9944141cc406Sopenharmony_ci DBG (64, "Edge=%f, val=%d, delta=%d\n", edge, val, delta); 9945141cc406Sopenharmony_ci 9946141cc406Sopenharmony_ci /* move back to y-coordinate origin */ 9947141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1220) 9948141cc406Sopenharmony_ci { 9949141cc406Sopenharmony_ci MOVE (delta, PRECISION_OFF, NULL); 9950141cc406Sopenharmony_ci } 9951141cc406Sopenharmony_ci else 9952141cc406Sopenharmony_ci { 9953141cc406Sopenharmony_ci MOVE (delta, PRECISION_ON, NULL); 9954141cc406Sopenharmony_ci } 9955141cc406Sopenharmony_ci 9956141cc406Sopenharmony_ci /* head successfully set to the origin */ 9957141cc406Sopenharmony_ci return 1; 9958141cc406Sopenharmony_ci} 9959141cc406Sopenharmony_ci 9960141cc406Sopenharmony_ci 9961141cc406Sopenharmony_ci/* park head: returns 1 on success, 0 otherwise */ 9962141cc406Sopenharmony_ciint 9963141cc406Sopenharmony_cisanei_umax_pp_park (void) 9964141cc406Sopenharmony_ci{ 9965141cc406Sopenharmony_ci int header610[17] = { 9966141cc406Sopenharmony_ci 0x01, 0x00, 0x01, 0x40, 0x30, 0x00, 0xC0, 0x2F, 0x17, 0x05, 0x00, 0x00, 9967141cc406Sopenharmony_ci 0x00, 0x80, 0xF4, 0x00, -1 9968141cc406Sopenharmony_ci }; 9969141cc406Sopenharmony_ci int body610[35] = { 9970141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x03, 0xC1, 0x80, 9971141cc406Sopenharmony_ci 0x00, 0x20, 0x02, 0x00, 0x16, 0x80, 0x15, 0x78, 0x03, 0x03, 0x00, 0x00, 9972141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x4D, 0x4B, 0xD0, 0x68, 0xDF, 0x1B, -1 9973141cc406Sopenharmony_ci }; 9974141cc406Sopenharmony_ci 9975141cc406Sopenharmony_ci int header[17] = 9976141cc406Sopenharmony_ci { 0x01, 0x00, 0x01, 0x70, 0x00, 0x00, 0x60, 0x2F, 0x13, 0x05, 0x00, 0x00, 9977141cc406Sopenharmony_ci 0x00, 0x80, 0xF0, 0x00, -1 9978141cc406Sopenharmony_ci }; 9979141cc406Sopenharmony_ci int body[37] = 9980141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x03, 0xC1, 0x80, 9981141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x16, 0x80, 0x15, 0x78, 0x03, 0x03, 0x00, 0x00, 9982141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 0x1B, 0x1A, 0x00, 9983141cc406Sopenharmony_ci -1 9984141cc406Sopenharmony_ci }; 9985141cc406Sopenharmony_ci 9986141cc406Sopenharmony_ci int status = 0x90; 9987141cc406Sopenharmony_ci 9988141cc406Sopenharmony_ci CMDSYNC (0x00); 9989141cc406Sopenharmony_ci 9990141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () > 610) 9991141cc406Sopenharmony_ci { 9992141cc406Sopenharmony_ci CMDSETGET (0x02, 0x10, header); 9993141cc406Sopenharmony_ci CMDSETGET (0x08, 0x24, body); 9994141cc406Sopenharmony_ci } 9995141cc406Sopenharmony_ci else 9996141cc406Sopenharmony_ci { 9997141cc406Sopenharmony_ci CMDSETGET (0x02, 0x10, header610); 9998141cc406Sopenharmony_ci CMDSETGET (0x08, 0x22, body610); 9999141cc406Sopenharmony_ci } 10000141cc406Sopenharmony_ci CMDSYNC (0x40); 10001141cc406Sopenharmony_ci 10002141cc406Sopenharmony_ci 10003141cc406Sopenharmony_ci status = sanei_umax_pp_scannerStatus (); 10004141cc406Sopenharmony_ci DBG (16, "PARKING STATUS is 0x%02X (%s:%d)\n", status, __FILE__, __LINE__); 10005141cc406Sopenharmony_ci DBG (1, "Park command issued ...\n"); 10006141cc406Sopenharmony_ci return 1; 10007141cc406Sopenharmony_ci} 10008141cc406Sopenharmony_ci 10009141cc406Sopenharmony_ci 10010141cc406Sopenharmony_ci/* calibrates CCD: returns 1 on success, 0 on failure */ 10011141cc406Sopenharmony_cistatic int 10012141cc406Sopenharmony_cishadingCalibration1220p (int color, 10013141cc406Sopenharmony_ci int dcRed, int dcGreen, int dcBlue, 10014141cc406Sopenharmony_ci int vgaRed, int vgaGreen, int vgaBlue, 10015141cc406Sopenharmony_ci int *calibration) 10016141cc406Sopenharmony_ci{ 10017141cc406Sopenharmony_ci int opsc32[17] = 10018141cc406Sopenharmony_ci { 0x4A, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x00, 0x17, 0x05, 0xA5, 0x08, 10019141cc406Sopenharmony_ci 0x00, 0x00, 0xAC, 0x00, -1 10020141cc406Sopenharmony_ci }; 10021141cc406Sopenharmony_ci int opsc41[37] = 10022141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x40, 0x01, 10023141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x6E, 0x90, 0xD0, 0x47, 0x06, 0x00, 0x00, 0xC4, 10024141cc406Sopenharmony_ci 0x5C, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 0x93, 0x1B, 0x00, 10025141cc406Sopenharmony_ci -1 10026141cc406Sopenharmony_ci }; 10027141cc406Sopenharmony_ci int opscnb[37] = 10028141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x40, 0x01, 10029141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x6E, 0x90, 0xD0, 0x47, 0x06, 0x00, 0x00, 0xEC, 10030141cc406Sopenharmony_ci 0x54, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 0x93, 0x1A, 0x00, 10031141cc406Sopenharmony_ci -1 10032141cc406Sopenharmony_ci }; 10033141cc406Sopenharmony_ci int opsc04[9] = { 0x06, 0xF4, 0xFF, 0x81, 0x1B, 0x00, 0x00, 0x00, -1 }; 10034141cc406Sopenharmony_ci int commit[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, -1 }; 10035141cc406Sopenharmony_ci int size; 10036141cc406Sopenharmony_ci int width = 5100; /* full usable CCD width */ 10037141cc406Sopenharmony_ci unsigned char buffer[0x105798]; 10038141cc406Sopenharmony_ci 10039141cc406Sopenharmony_ci /* 1600P have a different CCD command block */ 10040141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 10041141cc406Sopenharmony_ci { 10042141cc406Sopenharmony_ci opsc04[0] = 0x19; 10043141cc406Sopenharmony_ci opsc04[1] = 0xD5; 10044141cc406Sopenharmony_ci opsc04[4] = 0x1B; 10045141cc406Sopenharmony_ci 10046141cc406Sopenharmony_ci opsc41[29] = 0x1A; 10047141cc406Sopenharmony_ci opsc41[30] = 0xEE; 10048141cc406Sopenharmony_ci } 10049141cc406Sopenharmony_ci 10050141cc406Sopenharmony_ci /* step back by 67 ticks: */ 10051141cc406Sopenharmony_ci /* since we're going to scan 66 lines of data */ 10052141cc406Sopenharmony_ci /* which are going to be used as calibration */ 10053141cc406Sopenharmony_ci /* data */ 10054141cc406Sopenharmony_ci /* we are on the white area just before */ 10055141cc406Sopenharmony_ci /* the user scan area */ 10056141cc406Sopenharmony_ci MOVE (-67, PRECISION_ON, NULL); 10057141cc406Sopenharmony_ci 10058141cc406Sopenharmony_ci 10059141cc406Sopenharmony_ci CMDSYNC (0x00); 10060141cc406Sopenharmony_ci 10061141cc406Sopenharmony_ci /* get calibration data */ 10062141cc406Sopenharmony_ci /* 10063141cc406Sopenharmony_ci if (sanei_umax_pp_getauto ()) 10064141cc406Sopenharmony_ci { auto settings doesn't use offset 10065141cc406Sopenharmony_ci offset = 0x000; 10066141cc406Sopenharmony_ci } 10067141cc406Sopenharmony_ci else 10068141cc406Sopenharmony_ci { manual settings 10069141cc406Sopenharmony_ci gain = 0x777; 10070141cc406Sopenharmony_ci offset = 0x000; 10071141cc406Sopenharmony_ci } 10072141cc406Sopenharmony_ci */ 10073141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, opsc32); 10074141cc406Sopenharmony_ci encodeVGA (vgaRed, vgaGreen, vgaBlue, opsc32); 10075141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 10076141cc406Sopenharmony_ci { 10077141cc406Sopenharmony_ci opsc32[13] = 0x03; 10078141cc406Sopenharmony_ci } 10079141cc406Sopenharmony_ci 10080141cc406Sopenharmony_ci /* 1220P/2000P shading calibration */ 10081141cc406Sopenharmony_ci if (color < RGB_MODE) 10082141cc406Sopenharmony_ci { 10083141cc406Sopenharmony_ci opsc32[0] -= 4; 10084141cc406Sopenharmony_ci opsc32[13] = 0xC0; 10085141cc406Sopenharmony_ci } 10086141cc406Sopenharmony_ci CMDSETGET (2, 0x10, opsc32); 10087141cc406Sopenharmony_ci if (DBG_LEVEL >= 64) 10088141cc406Sopenharmony_ci { 10089141cc406Sopenharmony_ci bloc2Decode (opsc32); 10090141cc406Sopenharmony_ci } 10091141cc406Sopenharmony_ci if (color < RGB_MODE) 10092141cc406Sopenharmony_ci { 10093141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opscnb); 10094141cc406Sopenharmony_ci if (DBG_LEVEL >= 64) 10095141cc406Sopenharmony_ci { 10096141cc406Sopenharmony_ci bloc8Decode (opscnb); 10097141cc406Sopenharmony_ci } 10098141cc406Sopenharmony_ci opsc04[6] = 0x85; 10099141cc406Sopenharmony_ci } 10100141cc406Sopenharmony_ci else 10101141cc406Sopenharmony_ci { 10102141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opsc41); 10103141cc406Sopenharmony_ci if (DBG_LEVEL >= 64) 10104141cc406Sopenharmony_ci { 10105141cc406Sopenharmony_ci bloc8Decode (opsc41); 10106141cc406Sopenharmony_ci } 10107141cc406Sopenharmony_ci opsc04[6] = 0x0F; 10108141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 10109141cc406Sopenharmony_ci opsc04[7] = 0xC0; 10110141cc406Sopenharmony_ci else 10111141cc406Sopenharmony_ci opsc04[7] = 0x70; 10112141cc406Sopenharmony_ci } 10113141cc406Sopenharmony_ci 10114141cc406Sopenharmony_ci /* BUG BW noisy here */ 10115141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 10116141cc406Sopenharmony_ci CMDSYNC (0xC2); 10117141cc406Sopenharmony_ci CMDSYNC (0x00); 10118141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); /* opsc03 hangs it */ 10119141cc406Sopenharmony_ci COMPLETIONWAIT; 10120141cc406Sopenharmony_ci 10121141cc406Sopenharmony_ci opsc04[0] = 0x06; 10122141cc406Sopenharmony_ci if (color >= RGB_MODE) 10123141cc406Sopenharmony_ci size = 3 * width * 70; 10124141cc406Sopenharmony_ci else 10125141cc406Sopenharmony_ci size = width * 66; 10126141cc406Sopenharmony_ci if (getEPPMode () == 32) 10127141cc406Sopenharmony_ci { 10128141cc406Sopenharmony_ci cmdGetBuffer32 (4, size, buffer); 10129141cc406Sopenharmony_ci } 10130141cc406Sopenharmony_ci else 10131141cc406Sopenharmony_ci { 10132141cc406Sopenharmony_ci CMDGETBUF (4, size, buffer); 10133141cc406Sopenharmony_ci } 10134141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 10135141cc406Sopenharmony_ci { 10136141cc406Sopenharmony_ci Dump (size, buffer, NULL); 10137141cc406Sopenharmony_ci if (color >= RGB_MODE) 10138141cc406Sopenharmony_ci { 10139141cc406Sopenharmony_ci DumpRVB (width, 66, buffer, NULL); 10140141cc406Sopenharmony_ci } 10141141cc406Sopenharmony_ci else 10142141cc406Sopenharmony_ci { 10143141cc406Sopenharmony_ci DumpNB (width, 66, buffer, NULL); 10144141cc406Sopenharmony_ci } 10145141cc406Sopenharmony_ci } 10146141cc406Sopenharmony_ci computeCalibrationData (color, width, buffer, calibration); 10147141cc406Sopenharmony_ci 10148141cc406Sopenharmony_ci DBG (1, "shadingCalibration1220p() done ...\n"); 10149141cc406Sopenharmony_ci return 1; 10150141cc406Sopenharmony_ci} 10151141cc406Sopenharmony_ci 10152141cc406Sopenharmony_ci 10153141cc406Sopenharmony_ci/* returns number of bytes read or 0 on failure */ 10154141cc406Sopenharmony_ciint 10155141cc406Sopenharmony_cisanei_umax_pp_readBlock (long len, int window, int dpi, int last, 10156141cc406Sopenharmony_ci unsigned char *buffer) 10157141cc406Sopenharmony_ci{ 10158141cc406Sopenharmony_ci DBG (8, "readBlock(%ld,%d,%d,%d)\n", len, window, dpi, last); 10159141cc406Sopenharmony_ci /* EPP block reading is available only when dpi >=600 */ 10160141cc406Sopenharmony_ci if ((dpi >= 600) 10161141cc406Sopenharmony_ci && (gMode != UMAX_PP_PARPORT_ECP) && (sanei_umax_pp_getastra () > 610)) 10162141cc406Sopenharmony_ci { 10163141cc406Sopenharmony_ci DBG (8, "cmdGetBlockBuffer(4,%ld,%d);\n", len, window); 10164141cc406Sopenharmony_ci len = cmdGetBlockBuffer (4, len, window, buffer); 10165141cc406Sopenharmony_ci if (len == 0) 10166141cc406Sopenharmony_ci { 10167141cc406Sopenharmony_ci DBG (0, "cmdGetBlockBuffer(4,%ld,%d) failed (%s:%d)\n", len, window, 10168141cc406Sopenharmony_ci __FILE__, __LINE__); 10169141cc406Sopenharmony_ci gCancel = 1; 10170141cc406Sopenharmony_ci } 10171141cc406Sopenharmony_ci } 10172141cc406Sopenharmony_ci else 10173141cc406Sopenharmony_ci { 10174141cc406Sopenharmony_ci if ((sanei_umax_pp_getastra () < 1210) && (len > 0xFDCE)) 10175141cc406Sopenharmony_ci { 10176141cc406Sopenharmony_ci len = 0xFDCE; 10177141cc406Sopenharmony_ci last = 0; 10178141cc406Sopenharmony_ci } 10179141cc406Sopenharmony_ci DBG (8, "cmdGetBuffer(4,%ld);\n", len); 10180141cc406Sopenharmony_ci if (cmdGetBuffer (4, len, buffer) != 1) 10181141cc406Sopenharmony_ci { 10182141cc406Sopenharmony_ci DBG (0, "cmdGetBuffer(4,%ld) failed (%s:%d)\n", len, __FILE__, 10183141cc406Sopenharmony_ci __LINE__); 10184141cc406Sopenharmony_ci gCancel = 1; 10185141cc406Sopenharmony_ci } 10186141cc406Sopenharmony_ci } 10187141cc406Sopenharmony_ci if (!last) 10188141cc406Sopenharmony_ci { 10189141cc406Sopenharmony_ci /* sync with scanner */ 10190141cc406Sopenharmony_ci if (sanei_umax_pp_cmdSync (0xC2) == 0) 10191141cc406Sopenharmony_ci { 10192141cc406Sopenharmony_ci DBG (0, "Warning cmdSync(0xC2) failed! (%s:%d)\n", __FILE__, 10193141cc406Sopenharmony_ci __LINE__); 10194141cc406Sopenharmony_ci DBG (0, "Trying again ...\n"); 10195141cc406Sopenharmony_ci if (sanei_umax_pp_cmdSync (0xC2) == 0) 10196141cc406Sopenharmony_ci { 10197141cc406Sopenharmony_ci DBG (0, " failed again! (%s:%d)\n", __FILE__, __LINE__); 10198141cc406Sopenharmony_ci DBG (0, "Aborting ...\n"); 10199141cc406Sopenharmony_ci gCancel = 1; 10200141cc406Sopenharmony_ci } 10201141cc406Sopenharmony_ci else 10202141cc406Sopenharmony_ci DBG (0, " success ...\n"); 10203141cc406Sopenharmony_ci } 10204141cc406Sopenharmony_ci } 10205141cc406Sopenharmony_ci return len; 10206141cc406Sopenharmony_ci} 10207141cc406Sopenharmony_ci 10208141cc406Sopenharmony_ciint 10209141cc406Sopenharmony_cisanei_umax_pp_scan (int x, int y, int width, int height, int dpi, int color, 10210141cc406Sopenharmony_ci int gain, int offset) 10211141cc406Sopenharmony_ci{ 10212141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 10213141cc406Sopenharmony_ci struct timeval td, tf; 10214141cc406Sopenharmony_ci float elapsed; 10215141cc406Sopenharmony_ci#endif 10216141cc406Sopenharmony_ci unsigned char *buffer; 10217141cc406Sopenharmony_ci long int somme, len, read, blocksize; 10218141cc406Sopenharmony_ci FILE *fout = NULL; 10219141cc406Sopenharmony_ci int *dest = NULL; 10220141cc406Sopenharmony_ci int bpl, hp; 10221141cc406Sopenharmony_ci int th, tw, bpp; 10222141cc406Sopenharmony_ci int nb; 10223141cc406Sopenharmony_ci int bx, by, delta; 10224141cc406Sopenharmony_ci int reserve, rc, remain, dataoffset; 10225141cc406Sopenharmony_ci 10226141cc406Sopenharmony_ci if (gain != 0 || offset != 0) 10227141cc406Sopenharmony_ci sanei_umax_pp_setauto (0); 10228141cc406Sopenharmony_ci 10229141cc406Sopenharmony_ci 10230141cc406Sopenharmony_ci /* colors don't come in sync, so we must increase y */ 10231141cc406Sopenharmony_ci /* to have extra lines to reorder data */ 10232141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () > 610) 10233141cc406Sopenharmony_ci { 10234141cc406Sopenharmony_ci switch (dpi) 10235141cc406Sopenharmony_ci { 10236141cc406Sopenharmony_ci case 1200: 10237141cc406Sopenharmony_ci delta = 8; 10238141cc406Sopenharmony_ci break; 10239141cc406Sopenharmony_ci case 600: 10240141cc406Sopenharmony_ci delta = 4; 10241141cc406Sopenharmony_ci break; 10242141cc406Sopenharmony_ci case 300: 10243141cc406Sopenharmony_ci delta = 2; 10244141cc406Sopenharmony_ci break; 10245141cc406Sopenharmony_ci case 150: 10246141cc406Sopenharmony_ci delta = 1; 10247141cc406Sopenharmony_ci break; 10248141cc406Sopenharmony_ci default: 10249141cc406Sopenharmony_ci delta = 0; 10250141cc406Sopenharmony_ci break; 10251141cc406Sopenharmony_ci } 10252141cc406Sopenharmony_ci } 10253141cc406Sopenharmony_ci else 10254141cc406Sopenharmony_ci { 10255141cc406Sopenharmony_ci if (color >= RGB_MODE) 10256141cc406Sopenharmony_ci { 10257141cc406Sopenharmony_ci switch (dpi) 10258141cc406Sopenharmony_ci { 10259141cc406Sopenharmony_ci case 600: 10260141cc406Sopenharmony_ci delta = 16; 10261141cc406Sopenharmony_ci break; 10262141cc406Sopenharmony_ci case 300: 10263141cc406Sopenharmony_ci delta = 8; 10264141cc406Sopenharmony_ci break; 10265141cc406Sopenharmony_ci case 150: 10266141cc406Sopenharmony_ci delta = 4; 10267141cc406Sopenharmony_ci break; 10268141cc406Sopenharmony_ci default: 10269141cc406Sopenharmony_ci delta = 2; 10270141cc406Sopenharmony_ci break; 10271141cc406Sopenharmony_ci } 10272141cc406Sopenharmony_ci } 10273141cc406Sopenharmony_ci else 10274141cc406Sopenharmony_ci delta = 0; 10275141cc406Sopenharmony_ci } 10276141cc406Sopenharmony_ci 10277141cc406Sopenharmony_ci /* in color mode, we need extra lines to reorder data */ 10278141cc406Sopenharmony_ci if (color >= RGB_MODE) 10279141cc406Sopenharmony_ci { 10280141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 10281141cc406Sopenharmony_ci dataoffset = 4 * delta; 10282141cc406Sopenharmony_ci else 10283141cc406Sopenharmony_ci dataoffset = 2 * delta; 10284141cc406Sopenharmony_ci } 10285141cc406Sopenharmony_ci else 10286141cc406Sopenharmony_ci dataoffset = 0; 10287141cc406Sopenharmony_ci 10288141cc406Sopenharmony_ci rc = sanei_umax_pp_startScan 10289141cc406Sopenharmony_ci (x, y - dataoffset, width, height + dataoffset, dpi, color, gain, 10290141cc406Sopenharmony_ci offset, &bpp, &tw, &th); 10291141cc406Sopenharmony_ci if (rc == 1) 10292141cc406Sopenharmony_ci { 10293141cc406Sopenharmony_ci /* blocksize must be multiple of the number of bytes per line */ 10294141cc406Sopenharmony_ci /* max is 2096100 */ 10295141cc406Sopenharmony_ci /* so blocksize will hold a round number of lines, easing the */ 10296141cc406Sopenharmony_ci /* write data to file operation */ 10297141cc406Sopenharmony_ci bpl = bpp * tw; 10298141cc406Sopenharmony_ci hp = 2096100 / bpl; 10299141cc406Sopenharmony_ci blocksize = hp * bpl; 10300141cc406Sopenharmony_ci nb = 0; 10301141cc406Sopenharmony_ci somme = bpl * th; 10302141cc406Sopenharmony_ci DBG (8, "Getting buffer %d*%d*%d=%ld=0x%lX (%s:%d) \n", bpp, tw, th, 10303141cc406Sopenharmony_ci somme, somme, __FILE__, __LINE__); 10304141cc406Sopenharmony_ci 10305141cc406Sopenharmony_ci /* correct th to be usable scan height */ 10306141cc406Sopenharmony_ci th -= dataoffset; 10307141cc406Sopenharmony_ci 10308141cc406Sopenharmony_ci /* we need a 2 * delta lines reserve to reorder data */ 10309141cc406Sopenharmony_ci if (color >= RGB_MODE) 10310141cc406Sopenharmony_ci { 10311141cc406Sopenharmony_ci reserve = 2 * delta * bpl; 10312141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1210) 10313141cc406Sopenharmony_ci dataoffset = reserve; 10314141cc406Sopenharmony_ci else 10315141cc406Sopenharmony_ci dataoffset = 0; 10316141cc406Sopenharmony_ci } 10317141cc406Sopenharmony_ci else 10318141cc406Sopenharmony_ci { 10319141cc406Sopenharmony_ci reserve = 0; 10320141cc406Sopenharmony_ci dataoffset = 0; 10321141cc406Sopenharmony_ci } 10322141cc406Sopenharmony_ci 10323141cc406Sopenharmony_ci /* get scanned data */ 10324141cc406Sopenharmony_ci 10325141cc406Sopenharmony_ci /* allocate memory */ 10326141cc406Sopenharmony_ci buffer = (unsigned char *) malloc (blocksize + reserve); 10327141cc406Sopenharmony_ci if (buffer == NULL) 10328141cc406Sopenharmony_ci { 10329141cc406Sopenharmony_ci DBG (0, "Failed to allocate %ld bytes, giving up....\n", 10330141cc406Sopenharmony_ci blocksize + reserve); 10331141cc406Sopenharmony_ci DBG (0, "Try to scan at lower resolution, or a smaller area.\n"); 10332141cc406Sopenharmony_ci gCancel = 1; 10333141cc406Sopenharmony_ci } 10334141cc406Sopenharmony_ci 10335141cc406Sopenharmony_ci /* open output file */ 10336141cc406Sopenharmony_ci fout = fopen ("out.pnm", "wb"); 10337141cc406Sopenharmony_ci if (fout == NULL) 10338141cc406Sopenharmony_ci { 10339141cc406Sopenharmony_ci DBG (0, "Failed to open 'out.pnm', giving up....\n"); 10340141cc406Sopenharmony_ci gCancel = 1; 10341141cc406Sopenharmony_ci } 10342141cc406Sopenharmony_ci else 10343141cc406Sopenharmony_ci { 10344141cc406Sopenharmony_ci /* write pnm header */ 10345141cc406Sopenharmony_ci if (color >= RGB_MODE) 10346141cc406Sopenharmony_ci fprintf (fout, "P6\n%d %d\n255\n", tw, th - 2 * delta); 10347141cc406Sopenharmony_ci else 10348141cc406Sopenharmony_ci fprintf (fout, "P5\n%d %d\n255\n", tw, th); 10349141cc406Sopenharmony_ci } 10350141cc406Sopenharmony_ci 10351141cc406Sopenharmony_ci /* read some line first until we got clean data */ 10352141cc406Sopenharmony_ci read = 0; 10353141cc406Sopenharmony_ci remain = 0; 10354141cc406Sopenharmony_ci while (read < dataoffset) 10355141cc406Sopenharmony_ci { 10356141cc406Sopenharmony_ci if (read == 0) 10357141cc406Sopenharmony_ci len = dataoffset; 10358141cc406Sopenharmony_ci else 10359141cc406Sopenharmony_ci len = dataoffset - read; 10360141cc406Sopenharmony_ci len = sanei_umax_pp_readBlock (len, tw, dpi, 0, buffer + read); 10361141cc406Sopenharmony_ci if (len == 0) 10362141cc406Sopenharmony_ci { 10363141cc406Sopenharmony_ci DBG (0, 10364141cc406Sopenharmony_ci "sanei_umax_pp_readBlock failed, cancelling scan ...\n"); 10365141cc406Sopenharmony_ci gCancel = 1; 10366141cc406Sopenharmony_ci } 10367141cc406Sopenharmony_ci read += len; 10368141cc406Sopenharmony_ci } 10369141cc406Sopenharmony_ci 10370141cc406Sopenharmony_ci /* in color mode we have to fill the 'reserve' area 10371141cc406Sopenharmony_ci * so that we can reorder data lines */ 10372141cc406Sopenharmony_ci while ((read - dataoffset < reserve) && (!gCancel)) 10373141cc406Sopenharmony_ci { 10374141cc406Sopenharmony_ci len = reserve - read + dataoffset; 10375141cc406Sopenharmony_ci len = 10376141cc406Sopenharmony_ci sanei_umax_pp_readBlock (len, tw, dpi, 0, 10377141cc406Sopenharmony_ci buffer + read - dataoffset); 10378141cc406Sopenharmony_ci if (len == 0) 10379141cc406Sopenharmony_ci { 10380141cc406Sopenharmony_ci DBG (0, 10381141cc406Sopenharmony_ci "sanei_umax_pp_readBlock failed, cancelling scan ...\n"); 10382141cc406Sopenharmony_ci gCancel = 1; 10383141cc406Sopenharmony_ci } 10384141cc406Sopenharmony_ci read += len; 10385141cc406Sopenharmony_ci } 10386141cc406Sopenharmony_ci 10387141cc406Sopenharmony_ci /* data reading loop */ 10388141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 10389141cc406Sopenharmony_ci gettimeofday (&td, NULL); 10390141cc406Sopenharmony_ci#endif 10391141cc406Sopenharmony_ci while ((read < somme) && (!gCancel)) 10392141cc406Sopenharmony_ci { 10393141cc406Sopenharmony_ci /* 2096100 max */ 10394141cc406Sopenharmony_ci if (somme - read > blocksize - remain) 10395141cc406Sopenharmony_ci len = blocksize - remain; 10396141cc406Sopenharmony_ci else 10397141cc406Sopenharmony_ci len = somme - read; 10398141cc406Sopenharmony_ci len = 10399141cc406Sopenharmony_ci sanei_umax_pp_readBlock (len, tw, dpi, (len < blocksize), 10400141cc406Sopenharmony_ci buffer + reserve + remain); 10401141cc406Sopenharmony_ci if (len == 0) 10402141cc406Sopenharmony_ci { 10403141cc406Sopenharmony_ci DBG (0, 10404141cc406Sopenharmony_ci "sanei_umax_pp_readBlock failed, cancelling scan ...\n"); 10405141cc406Sopenharmony_ci gCancel = 1; 10406141cc406Sopenharmony_ci } 10407141cc406Sopenharmony_ci 10408141cc406Sopenharmony_ci read += len; 10409141cc406Sopenharmony_ci nb++; 10410141cc406Sopenharmony_ci DBG (8, "Read %ld bytes out of %ld ...\n", read, somme); 10411141cc406Sopenharmony_ci DBG (8, "Read %d blocks ... \n", nb); 10412141cc406Sopenharmony_ci 10413141cc406Sopenharmony_ci /* write partial buffer to file */ 10414141cc406Sopenharmony_ci if (len) 10415141cc406Sopenharmony_ci { 10416141cc406Sopenharmony_ci if (color >= RGB_MODE) 10417141cc406Sopenharmony_ci { 10418141cc406Sopenharmony_ci /* using an image format that doesn't need */ 10419141cc406Sopenharmony_ci /* reordering would speed up write operation */ 10420141cc406Sopenharmony_ci 10421141cc406Sopenharmony_ci /* don't forget remaining bytes from previous block */ 10422141cc406Sopenharmony_ci hp = (len + remain) / bpl; 10423141cc406Sopenharmony_ci remain = (len + remain) - hp * bpl; 10424141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 10425141cc406Sopenharmony_ci { 10426141cc406Sopenharmony_ci case 610: 10427141cc406Sopenharmony_ci /* first comes RED 10428141cc406Sopenharmony_ci * then BLUE 10429141cc406Sopenharmony_ci * and finally GREEN */ 10430141cc406Sopenharmony_ci for (by = 0; by < hp; by++) 10431141cc406Sopenharmony_ci { 10432141cc406Sopenharmony_ci for (bx = 0; bx < tw; bx++) 10433141cc406Sopenharmony_ci { 10434141cc406Sopenharmony_ci /* scanner data: red line, blue line then green line */ 10435141cc406Sopenharmony_ci /* red */ 10436141cc406Sopenharmony_ci fputc (buffer 10437141cc406Sopenharmony_ci [3 * (by - 2 * delta) * tw + bx + 10438141cc406Sopenharmony_ci reserve], fout); 10439141cc406Sopenharmony_ci /* green */ 10440141cc406Sopenharmony_ci fputc (buffer 10441141cc406Sopenharmony_ci [3 * by * tw + 2 * tw + 10442141cc406Sopenharmony_ci bx + reserve], fout); 10443141cc406Sopenharmony_ci /* blue */ 10444141cc406Sopenharmony_ci fputc (buffer 10445141cc406Sopenharmony_ci [3 * (by - delta) * tw + tw + bx + 10446141cc406Sopenharmony_ci reserve], fout); 10447141cc406Sopenharmony_ci } 10448141cc406Sopenharmony_ci } 10449141cc406Sopenharmony_ci /* copy tail lines for next block */ 10450141cc406Sopenharmony_ci /* memcpy (buffer, 10451141cc406Sopenharmony_ci * (buffer + reserve) + (hp * bpl - reserve), 10452141cc406Sopenharmony_ci * reserve + remain); */ 10453141cc406Sopenharmony_ci memcpy (buffer, buffer + hp * bpl, reserve + remain); 10454141cc406Sopenharmony_ci break; 10455141cc406Sopenharmony_ci case 1600: 10456141cc406Sopenharmony_ci for (by = 0; by < hp; by++) 10457141cc406Sopenharmony_ci { 10458141cc406Sopenharmony_ci for (bx = 0; bx < tw; bx++) 10459141cc406Sopenharmony_ci { 10460141cc406Sopenharmony_ci fputc (buffer[3 * by * tw + 2 * tw + bx], fout); 10461141cc406Sopenharmony_ci fputc (buffer[3 * by * tw + bx], fout); 10462141cc406Sopenharmony_ci fputc (buffer[3 * by * tw + tw + bx], fout); 10463141cc406Sopenharmony_ci } 10464141cc406Sopenharmony_ci } 10465141cc406Sopenharmony_ci break; 10466141cc406Sopenharmony_ci default: 10467141cc406Sopenharmony_ci for (by = 0; by < hp; by++) 10468141cc406Sopenharmony_ci { 10469141cc406Sopenharmony_ci for (bx = 0; bx < tw; bx++) 10470141cc406Sopenharmony_ci { 10471141cc406Sopenharmony_ci fputc (buffer[3 * by * tw + 2 * tw + bx], fout); 10472141cc406Sopenharmony_ci fputc (buffer[3 * by * tw + tw + bx], fout); 10473141cc406Sopenharmony_ci fputc (buffer[3 * by * tw + bx], fout); 10474141cc406Sopenharmony_ci } 10475141cc406Sopenharmony_ci } 10476141cc406Sopenharmony_ci /* put remaining partial lines at start of buffer */ 10477141cc406Sopenharmony_ci memcpy (buffer, buffer + hp * bpl, remain); 10478141cc406Sopenharmony_ci break; 10479141cc406Sopenharmony_ci } 10480141cc406Sopenharmony_ci } 10481141cc406Sopenharmony_ci else 10482141cc406Sopenharmony_ci fwrite (buffer, len, 1, fout); 10483141cc406Sopenharmony_ci } 10484141cc406Sopenharmony_ci } 10485141cc406Sopenharmony_ci 10486141cc406Sopenharmony_ci#ifdef HAVE_SYS_TIME_H 10487141cc406Sopenharmony_ci gettimeofday (&tf, NULL); 10488141cc406Sopenharmony_ci 10489141cc406Sopenharmony_ci /* scan time are high enough to forget about usec */ 10490141cc406Sopenharmony_ci elapsed = tf.tv_sec - td.tv_sec; 10491141cc406Sopenharmony_ci DBG (8, "%ld bytes transferred in %f seconds ( %.2f Kb/s)\n", somme, 10492141cc406Sopenharmony_ci elapsed, (somme / elapsed) / 1024.0); 10493141cc406Sopenharmony_ci#endif 10494141cc406Sopenharmony_ci 10495141cc406Sopenharmony_ci /* release resources */ 10496141cc406Sopenharmony_ci if (fout != NULL) 10497141cc406Sopenharmony_ci fclose (fout); 10498141cc406Sopenharmony_ci free (dest); 10499141cc406Sopenharmony_ci free (buffer); 10500141cc406Sopenharmony_ci } /* if start scan OK */ 10501141cc406Sopenharmony_ci else 10502141cc406Sopenharmony_ci { 10503141cc406Sopenharmony_ci DBG (0, "startScan failed..... \n"); 10504141cc406Sopenharmony_ci } 10505141cc406Sopenharmony_ci 10506141cc406Sopenharmony_ci /* terminate any pending command */ 10507141cc406Sopenharmony_ci if (sanei_umax_pp_cmdSync (0x00) == 0) 10508141cc406Sopenharmony_ci { 10509141cc406Sopenharmony_ci DBG (0, "Warning cmdSync(0x00) failed! (%s:%d)\n", __FILE__, __LINE__); 10510141cc406Sopenharmony_ci DBG (0, "Trying again ... "); 10511141cc406Sopenharmony_ci if (sanei_umax_pp_cmdSync (0x00) == 0) 10512141cc406Sopenharmony_ci { 10513141cc406Sopenharmony_ci DBG (0, " failed again! (%s:%d)\n", __FILE__, __LINE__); 10514141cc406Sopenharmony_ci DBG (0, "Blindly going on ...\n"); 10515141cc406Sopenharmony_ci } 10516141cc406Sopenharmony_ci else 10517141cc406Sopenharmony_ci DBG (0, " success ...\n"); 10518141cc406Sopenharmony_ci 10519141cc406Sopenharmony_ci } 10520141cc406Sopenharmony_ci 10521141cc406Sopenharmony_ci /* parking */ 10522141cc406Sopenharmony_ci if (sanei_umax_pp_park () == 0) 10523141cc406Sopenharmony_ci DBG (0, "Park failed !!! (%s:%d)\n", __FILE__, __LINE__); 10524141cc406Sopenharmony_ci 10525141cc406Sopenharmony_ci 10526141cc406Sopenharmony_ci /* end ... */ 10527141cc406Sopenharmony_ci DBG (16, "Scan done ...\n"); 10528141cc406Sopenharmony_ci return 1; 10529141cc406Sopenharmony_ci} 10530141cc406Sopenharmony_ci 10531141cc406Sopenharmony_ci 10532141cc406Sopenharmony_ci 10533141cc406Sopenharmony_ci 10534141cc406Sopenharmony_ci 10535141cc406Sopenharmony_ci/* 10536141cc406Sopenharmony_ci * returns 0 on error, 1 on success: ie head parked 10537141cc406Sopenharmony_ci */ 10538141cc406Sopenharmony_ciint 10539141cc406Sopenharmony_cisanei_umax_pp_parkWait (void) 10540141cc406Sopenharmony_ci{ 10541141cc406Sopenharmony_ci int status; 10542141cc406Sopenharmony_ci 10543141cc406Sopenharmony_ci /* check if head is at home */ 10544141cc406Sopenharmony_ci DBG (16, "entering parkWait ...\n"); 10545141cc406Sopenharmony_ci do 10546141cc406Sopenharmony_ci { 10547141cc406Sopenharmony_ci usleep (1000); 10548141cc406Sopenharmony_ci CMDSYNC (0x40); 10549141cc406Sopenharmony_ci status = sanei_umax_pp_scannerStatus (); 10550141cc406Sopenharmony_ci } 10551141cc406Sopenharmony_ci while ((status & MOTOR_BIT) == 0x00); 10552141cc406Sopenharmony_ci DBG (16, "parkWait done ...\n"); 10553141cc406Sopenharmony_ci return 1; 10554141cc406Sopenharmony_ci} 10555141cc406Sopenharmony_ci 10556141cc406Sopenharmony_ci 10557141cc406Sopenharmony_ci 10558141cc406Sopenharmony_ci 10559141cc406Sopenharmony_ci 10560141cc406Sopenharmony_ci 10561141cc406Sopenharmony_ci/* starts scan: return 1 on success */ 10562141cc406Sopenharmony_ciint 10563141cc406Sopenharmony_cisanei_umax_pp_startScan (int x, int y, int width, int height, int dpi, 10564141cc406Sopenharmony_ci int color, int gain, int offset, int *rbpp, 10565141cc406Sopenharmony_ci int *rtw, int *rth) 10566141cc406Sopenharmony_ci{ 10567141cc406Sopenharmony_ci unsigned char *buffer; 10568141cc406Sopenharmony_ci int rc = 0; 10569141cc406Sopenharmony_ci int calibration[3 * 5100 + 768 + 2 + 1]; 10570141cc406Sopenharmony_ci int xdpi, ydpi, h; 10571141cc406Sopenharmony_ci int th, tw, bpp; 10572141cc406Sopenharmony_ci int hwdpi = 600; /* CCD hardware dpi */ 10573141cc406Sopenharmony_ci /* DC offsets */ 10574141cc406Sopenharmony_ci int dcRed, dcGreen, dcBlue; 10575141cc406Sopenharmony_ci int vgaRed, vgaGreen, vgaBlue; 10576141cc406Sopenharmony_ci int len, delta; 10577141cc406Sopenharmony_ci 10578141cc406Sopenharmony_ci int lm9811[9] = { 10579141cc406Sopenharmony_ci 0x06, 0xF4, 0xFF, 0x81, 0x1B, 0x00, 0x00, 0x00, 10580141cc406Sopenharmony_ci -1 10581141cc406Sopenharmony_ci }; 10582141cc406Sopenharmony_ci 10583141cc406Sopenharmony_ci int motor[17] = { 10584141cc406Sopenharmony_ci 0xA4, 0x80, 0x07, 0x50, 0xEC, 0x03, 0x00, 0x2F, 10585141cc406Sopenharmony_ci 0x17, 0x07, 0x84, 0x08, 0x90, 0x00, 0xAC, 0x00, 10586141cc406Sopenharmony_ci -1 10587141cc406Sopenharmony_ci }; 10588141cc406Sopenharmony_ci 10589141cc406Sopenharmony_ci int ccd[37] = 10590141cc406Sopenharmony_ci { 0x00, 0x00, 0xB0, 0x4F, 0xD8, 0xE7, 0xFA, 0x10, 0xEF, 0xC4, 0x3C, 0x71, 10591141cc406Sopenharmony_ci 0x0F, 0x00, 0x04, 0x00, 0x6E, 0x61, 0xA1, 0x24, 0xC4, 0x7E, 0x00, 0xAE, 10592141cc406Sopenharmony_ci 0x41, 0xA0, 0x0A, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 0x33, 0x1A, 0x00, 10593141cc406Sopenharmony_ci -1 10594141cc406Sopenharmony_ci }; 10595141cc406Sopenharmony_ci 10596141cc406Sopenharmony_ci 10597141cc406Sopenharmony_ci#ifdef UMAX_PP_DANGEROUS_EXPERIMENT 10598141cc406Sopenharmony_ci FILE *f = NULL; 10599141cc406Sopenharmony_ci char line[1024], *ptr; 10600141cc406Sopenharmony_ci int *base = NULL; 10601141cc406Sopenharmony_ci int channel; 10602141cc406Sopenharmony_ci int max = 0; 10603141cc406Sopenharmony_ci#endif 10604141cc406Sopenharmony_ci 10605141cc406Sopenharmony_ci 10606141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 610) 10607141cc406Sopenharmony_ci { 10608141cc406Sopenharmony_ci hwdpi = 300; 10609141cc406Sopenharmony_ci len = 0x22; 10610141cc406Sopenharmony_ci 10611141cc406Sopenharmony_ci lm9811[0] = 0x88; 10612141cc406Sopenharmony_ci lm9811[1] = 0xE6; 10613141cc406Sopenharmony_ci lm9811[2] = 0xFD; 10614141cc406Sopenharmony_ci lm9811[3] = 0x8E; 10615141cc406Sopenharmony_ci lm9811[4] = 0x30; 10616141cc406Sopenharmony_ci lm9811[5] = 0x00; 10617141cc406Sopenharmony_ci lm9811[6] = 0x8F; 10618141cc406Sopenharmony_ci lm9811[7] = 0x80; 10619141cc406Sopenharmony_ci 10620141cc406Sopenharmony_ci motor[3] = 0x30; 10621141cc406Sopenharmony_ci motor[4] = 0x0E; 10622141cc406Sopenharmony_ci motor[5] = 0x02; 10623141cc406Sopenharmony_ci motor[12] = 0xAA; 10624141cc406Sopenharmony_ci 10625141cc406Sopenharmony_ci ccd[0] = 0x00; 10626141cc406Sopenharmony_ci ccd[1] = 0x00; 10627141cc406Sopenharmony_ci ccd[2] = 0xD8; 10628141cc406Sopenharmony_ci ccd[3] = 0x27; 10629141cc406Sopenharmony_ci ccd[4] = 0xEC; 10630141cc406Sopenharmony_ci ccd[5] = 0x53; 10631141cc406Sopenharmony_ci ccd[6] = 0x7D; 10632141cc406Sopenharmony_ci ccd[7] = 0x8A; 10633141cc406Sopenharmony_ci ccd[8] = 0x77; 10634141cc406Sopenharmony_ci ccd[9] = 0xE2; 10635141cc406Sopenharmony_ci ccd[10] = 0x9E; 10636141cc406Sopenharmony_ci ccd[11] = 0xF8; 10637141cc406Sopenharmony_ci ccd[12] = 0x07; 10638141cc406Sopenharmony_ci ccd[13] = 0x20; 10639141cc406Sopenharmony_ci ccd[14] = 0x02; 10640141cc406Sopenharmony_ci ccd[15] = 0x00; 10641141cc406Sopenharmony_ci ccd[16] = 0x76; 10642141cc406Sopenharmony_ci ccd[17] = 0x5D; 10643141cc406Sopenharmony_ci ccd[18] = 0xE0; 10644141cc406Sopenharmony_ci ccd[19] = 0x13; 10645141cc406Sopenharmony_ci ccd[20] = 0xE2; 10646141cc406Sopenharmony_ci ccd[21] = 0x20; 10647141cc406Sopenharmony_ci ccd[22] = 0x00; 10648141cc406Sopenharmony_ci ccd[23] = 0xA8; 10649141cc406Sopenharmony_ci ccd[24] = 0x41; 10650141cc406Sopenharmony_ci ccd[25] = 0xA0; 10651141cc406Sopenharmony_ci ccd[26] = 0x0A; 10652141cc406Sopenharmony_ci ccd[27] = 0x8B; 10653141cc406Sopenharmony_ci ccd[28] = 0x4D; 10654141cc406Sopenharmony_ci ccd[29] = 0x4B; 10655141cc406Sopenharmony_ci ccd[30] = 0xD0; 10656141cc406Sopenharmony_ci ccd[31] = 0x68; 10657141cc406Sopenharmony_ci ccd[32] = 0xDF; 10658141cc406Sopenharmony_ci ccd[33] = 0x13; 10659141cc406Sopenharmony_ci } 10660141cc406Sopenharmony_ci else 10661141cc406Sopenharmony_ci { 10662141cc406Sopenharmony_ci len = 0x24; 10663141cc406Sopenharmony_ci hwdpi = 600; 10664141cc406Sopenharmony_ci } 10665141cc406Sopenharmony_ci DBG (8, "startScan(%d,%d,%d,%d,%d,%d,%X);\n", x, y, width, height, dpi, 10666141cc406Sopenharmony_ci color, gain); 10667141cc406Sopenharmony_ci buffer = (unsigned char *) malloc (2096100); 10668141cc406Sopenharmony_ci if (buffer == NULL) 10669141cc406Sopenharmony_ci { 10670141cc406Sopenharmony_ci DBG (0, "Failed to allocate 2096100 bytes... (%s:%d)\n", __FILE__, 10671141cc406Sopenharmony_ci __LINE__); 10672141cc406Sopenharmony_ci return 0; 10673141cc406Sopenharmony_ci } 10674141cc406Sopenharmony_ci 10675141cc406Sopenharmony_ci /* 1600P have a different CCD command block */ 10676141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 10677141cc406Sopenharmony_ci { 10678141cc406Sopenharmony_ci lm9811[0] = 0x19; 10679141cc406Sopenharmony_ci lm9811[1] = 0xD5; 10680141cc406Sopenharmony_ci lm9811[4] = 0x1B; 10681141cc406Sopenharmony_ci lm9811[7] = 0x70; 10682141cc406Sopenharmony_ci 10683141cc406Sopenharmony_ci ccd[29] = 0x1A; 10684141cc406Sopenharmony_ci ccd[30] = 0xEE; 10685141cc406Sopenharmony_ci 10686141cc406Sopenharmony_ci motor[13] = 0x03; /* may be blur filter */ 10687141cc406Sopenharmony_ci } 10688141cc406Sopenharmony_ci 10689141cc406Sopenharmony_ci /* matches intTransport610P */ 10690141cc406Sopenharmony_ci /* get scanner status */ 10691141cc406Sopenharmony_ci rc = inquire (); 10692141cc406Sopenharmony_ci if (rc == 0) 10693141cc406Sopenharmony_ci { 10694141cc406Sopenharmony_ci DBG (0, "inquire() failed ! (%s:%d) \n", __FILE__, __LINE__); 10695141cc406Sopenharmony_ci return 0; 10696141cc406Sopenharmony_ci } 10697141cc406Sopenharmony_ci DBG (16, "inquire() passed ... (%s:%d)\n", __FILE__, __LINE__); 10698141cc406Sopenharmony_ci 10699141cc406Sopenharmony_ci rc = loadDefaultTables (); 10700141cc406Sopenharmony_ci if (rc == 0) 10701141cc406Sopenharmony_ci { 10702141cc406Sopenharmony_ci DBG (0, "loadDefaultTables() failed ! (%s:%d) \n", __FILE__, __LINE__); 10703141cc406Sopenharmony_ci return 0; 10704141cc406Sopenharmony_ci } 10705141cc406Sopenharmony_ci DBG (16, "loadDefaultTables() passed ... (%s:%d)\n", __FILE__, __LINE__); 10706141cc406Sopenharmony_ci 10707141cc406Sopenharmony_ci /* find and move to zero */ 10708141cc406Sopenharmony_ci if (moveToOrigin () == 0) 10709141cc406Sopenharmony_ci { 10710141cc406Sopenharmony_ci DBG (0, "moveToOrigin() failed ... (%s:%d)\n", __FILE__, __LINE__); 10711141cc406Sopenharmony_ci } 10712141cc406Sopenharmony_ci else 10713141cc406Sopenharmony_ci { 10714141cc406Sopenharmony_ci DBG (16, "moveToOrigin() passed ... (%s:%d)\n", __FILE__, __LINE__); 10715141cc406Sopenharmony_ci } 10716141cc406Sopenharmony_ci 10717141cc406Sopenharmony_ci /* 1600P have a different CCD command block */ 10718141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 10719141cc406Sopenharmony_ci { 10720141cc406Sopenharmony_ci lm9811[0] = 0x19; 10721141cc406Sopenharmony_ci lm9811[1] = 0xD5; 10722141cc406Sopenharmony_ci lm9811[4] = 0x1B; 10723141cc406Sopenharmony_ci lm9811[7] = 0x70; 10724141cc406Sopenharmony_ci 10725141cc406Sopenharmony_ci ccd[29] = 0x1A; 10726141cc406Sopenharmony_ci ccd[30] = 0xEE; 10727141cc406Sopenharmony_ci 10728141cc406Sopenharmony_ci motor[13] = 0x03; /* may be blur filter */ 10729141cc406Sopenharmony_ci } 10730141cc406Sopenharmony_ci 10731141cc406Sopenharmony_ci /* XXX STEF XXX : done even is manual settings, some day skip it 10732141cc406Sopenharmony_ci * and move head the right amount */ 10733141cc406Sopenharmony_ci if (offsetCalibration (color, &dcRed, &dcGreen, &dcBlue) == 0) 10734141cc406Sopenharmony_ci { 10735141cc406Sopenharmony_ci DBG (0, "offsetCalibration failed !!! (%s:%d)\n", __FILE__, __LINE__); 10736141cc406Sopenharmony_ci return 0; 10737141cc406Sopenharmony_ci } 10738141cc406Sopenharmony_ci DBG (16, "offsetCalibration(%d=>%d,%d,%d) passed ... (%s:%d)\n", 10739141cc406Sopenharmony_ci color, dcRed, dcGreen, dcBlue, __FILE__, __LINE__); 10740141cc406Sopenharmony_ci 10741141cc406Sopenharmony_ci if (coarseGainCalibration 10742141cc406Sopenharmony_ci (color, dcRed, dcGreen, dcBlue, &vgaRed, &vgaGreen, &vgaBlue) == 0) 10743141cc406Sopenharmony_ci { 10744141cc406Sopenharmony_ci DBG (0, "coarseGainCalibration failed !!! (%s:%d)\n", __FILE__, 10745141cc406Sopenharmony_ci __LINE__); 10746141cc406Sopenharmony_ci return 0; 10747141cc406Sopenharmony_ci } 10748141cc406Sopenharmony_ci DBG (16, 10749141cc406Sopenharmony_ci "coarseGainCalibration(%d,%d,%d,%d=>%d,%d,%d) passed ... (%s:%d)\n", 10750141cc406Sopenharmony_ci color, dcRed, dcGreen, dcBlue, vgaRed, vgaGreen, vgaBlue, 10751141cc406Sopenharmony_ci __FILE__, __LINE__); 10752141cc406Sopenharmony_ci 10753141cc406Sopenharmony_ci /* manual setting overrides evaluated values */ 10754141cc406Sopenharmony_ci if (!sanei_umax_pp_getauto ()) 10755141cc406Sopenharmony_ci { 10756141cc406Sopenharmony_ci dcRed = (offset & 0xF00) >> 8; 10757141cc406Sopenharmony_ci dcGreen = (offset & 0x0F0) >> 4; 10758141cc406Sopenharmony_ci dcBlue = offset & 0x00F; 10759141cc406Sopenharmony_ci vgaRed = (gain & 0xF00) >> 8; 10760141cc406Sopenharmony_ci vgaGreen = (gain & 0x0F0) >> 4; 10761141cc406Sopenharmony_ci vgaBlue = gain & 0x00F; 10762141cc406Sopenharmony_ci } 10763141cc406Sopenharmony_ci 10764141cc406Sopenharmony_ci /* ccd calibration is always done */ 10765141cc406Sopenharmony_ci /* with final dc and vga */ 10766141cc406Sopenharmony_ci if (shadingCalibration 10767141cc406Sopenharmony_ci (color, dcRed, dcGreen, dcBlue, vgaRed, vgaGreen, vgaBlue, 10768141cc406Sopenharmony_ci calibration) == 0) 10769141cc406Sopenharmony_ci { 10770141cc406Sopenharmony_ci DBG (0, "shadingCalibration failed !!! (%s:%d)\n", __FILE__, __LINE__); 10771141cc406Sopenharmony_ci return 0; 10772141cc406Sopenharmony_ci } 10773141cc406Sopenharmony_ci DBG (16, 10774141cc406Sopenharmony_ci "shadingCalibration(%d,%d,%d,%d,%d,%d,%d) passed ... (%s:%d)\n", 10775141cc406Sopenharmony_ci color, dcRed, dcGreen, dcBlue, vgaRed, vgaGreen, vgaBlue, __FILE__, 10776141cc406Sopenharmony_ci __LINE__); 10777141cc406Sopenharmony_ci 10778141cc406Sopenharmony_ci /* gamma or left shading calibration ? */ 10779141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 10780141cc406Sopenharmony_ci { 10781141cc406Sopenharmony_ci if (leftShadingCalibration610p 10782141cc406Sopenharmony_ci (color, dcRed, dcGreen, dcBlue, vgaRed, vgaGreen, vgaBlue, 10783141cc406Sopenharmony_ci calibration) == 0) 10784141cc406Sopenharmony_ci { 10785141cc406Sopenharmony_ci DBG (0, "leftShadingCalibration610p failed !!! (%s:%d)\n", __FILE__, 10786141cc406Sopenharmony_ci __LINE__); 10787141cc406Sopenharmony_ci return 0; 10788141cc406Sopenharmony_ci } 10789141cc406Sopenharmony_ci DBG (16, 10790141cc406Sopenharmony_ci "leftShadingCalibration610p(%d,%d,%d,%d,%d,%d,%d) passed ... (%s:%d)\n", 10791141cc406Sopenharmony_ci color, dcRed, dcGreen, dcBlue, vgaRed, vgaGreen, vgaBlue, __FILE__, 10792141cc406Sopenharmony_ci __LINE__); 10793141cc406Sopenharmony_ci } 10794141cc406Sopenharmony_ci 10795141cc406Sopenharmony_ci /* 1220P: x dpi is from 75 to 600 max, any modes */ 10796141cc406Sopenharmony_ci /* 610P: x dpi is from 75 to 300 max, any modes */ 10797141cc406Sopenharmony_ci if (dpi > hwdpi) 10798141cc406Sopenharmony_ci xdpi = hwdpi; 10799141cc406Sopenharmony_ci else 10800141cc406Sopenharmony_ci xdpi = dpi; 10801141cc406Sopenharmony_ci 10802141cc406Sopenharmony_ci 10803141cc406Sopenharmony_ci /* EPPRead32Buffer does not work */ 10804141cc406Sopenharmony_ci /* with length not multiple of four bytes, so we enlarge */ 10805141cc406Sopenharmony_ci /* width to meet this criteria ... */ 10806141cc406Sopenharmony_ci if ((getEPPMode () == 32) && (xdpi >= 600) && (width & 0x03) 10807141cc406Sopenharmony_ci && (sanei_umax_pp_getastra () > 610)) 10808141cc406Sopenharmony_ci { 10809141cc406Sopenharmony_ci width += (4 - (width & 0x03)); 10810141cc406Sopenharmony_ci /* in case we go too far on the right */ 10811141cc406Sopenharmony_ci if (x + width > 5100) 10812141cc406Sopenharmony_ci { 10813141cc406Sopenharmony_ci x = 5100 - width; 10814141cc406Sopenharmony_ci } 10815141cc406Sopenharmony_ci } 10816141cc406Sopenharmony_ci 10817141cc406Sopenharmony_ci /* compute target size */ 10818141cc406Sopenharmony_ci th = (height * dpi) / hwdpi; 10819141cc406Sopenharmony_ci tw = (width * xdpi) / hwdpi; 10820141cc406Sopenharmony_ci 10821141cc406Sopenharmony_ci /* corrects y to match exact scan area start 10822141cc406Sopenharmony_ci * and lets room for a leading zone so that 10823141cc406Sopenharmony_ci * we can reorder data */ 10824141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 10825141cc406Sopenharmony_ci { 10826141cc406Sopenharmony_ci case 610: 10827141cc406Sopenharmony_ci if (color >= RGB_MODE) 10828141cc406Sopenharmony_ci switch (dpi) 10829141cc406Sopenharmony_ci { 10830141cc406Sopenharmony_ci case 600: 10831141cc406Sopenharmony_ci y += 64; 10832141cc406Sopenharmony_ci break; 10833141cc406Sopenharmony_ci case 300: 10834141cc406Sopenharmony_ci y += 32; 10835141cc406Sopenharmony_ci break; 10836141cc406Sopenharmony_ci case 150: 10837141cc406Sopenharmony_ci y += 16; 10838141cc406Sopenharmony_ci break; 10839141cc406Sopenharmony_ci case 75: 10840141cc406Sopenharmony_ci y += 8; 10841141cc406Sopenharmony_ci break; 10842141cc406Sopenharmony_ci } 10843141cc406Sopenharmony_ci else 10844141cc406Sopenharmony_ci y += 80; 10845141cc406Sopenharmony_ci // fall through 10846141cc406Sopenharmony_ci default: 10847141cc406Sopenharmony_ci y += 8; 10848141cc406Sopenharmony_ci break; 10849141cc406Sopenharmony_ci } 10850141cc406Sopenharmony_ci 10851141cc406Sopenharmony_ci /* for 1220P/2000P move fast to scan target if possible */ 10852141cc406Sopenharmony_ci /* it is faster to move at low resolution, then scan */ 10853141cc406Sopenharmony_ci /* than scan & move at high resolution */ 10854141cc406Sopenharmony_ci if ((sanei_umax_pp_getastra () > 610 && (dpi > 300)) && (y > 100)) 10855141cc406Sopenharmony_ci { 10856141cc406Sopenharmony_ci /* move at 150 dpi resolution */ 10857141cc406Sopenharmony_ci move (y / 2, PRECISION_OFF, NULL); 10858141cc406Sopenharmony_ci 10859141cc406Sopenharmony_ci /* keep the remainder for scan */ 10860141cc406Sopenharmony_ci y = y % 4; 10861141cc406Sopenharmony_ci } 10862141cc406Sopenharmony_ci 10863141cc406Sopenharmony_ci /* build final scan command */ 10864141cc406Sopenharmony_ci 10865141cc406Sopenharmony_ci /* round width and height */ 10866141cc406Sopenharmony_ci width = (tw * hwdpi) / xdpi; 10867141cc406Sopenharmony_ci height = (th * hwdpi) / dpi; 10868141cc406Sopenharmony_ci 10869141cc406Sopenharmony_ci ydpi = dpi; 10870141cc406Sopenharmony_ci if (ydpi < 300) 10871141cc406Sopenharmony_ci { 10872141cc406Sopenharmony_ci if ((color >= RGB_MODE) && (sanei_umax_pp_getastra () > 610)) 10873141cc406Sopenharmony_ci { 10874141cc406Sopenharmony_ci if (dpi < 150) 10875141cc406Sopenharmony_ci ydpi = 150; 10876141cc406Sopenharmony_ci } 10877141cc406Sopenharmony_ci else 10878141cc406Sopenharmony_ci ydpi = 300; 10879141cc406Sopenharmony_ci } 10880141cc406Sopenharmony_ci if ((color < RGB_MODE) && (sanei_umax_pp_getastra () <= 610)) 10881141cc406Sopenharmony_ci ydpi = 600; 10882141cc406Sopenharmony_ci 10883141cc406Sopenharmony_ci /* at maximum resolution */ 10884141cc406Sopenharmony_ci if (color >= RGB_MODE) 10885141cc406Sopenharmony_ci { 10886141cc406Sopenharmony_ci h = ((height * ydpi) / hwdpi) + 8; 10887141cc406Sopenharmony_ci bpp = 3; 10888141cc406Sopenharmony_ci } 10889141cc406Sopenharmony_ci else 10890141cc406Sopenharmony_ci { 10891141cc406Sopenharmony_ci h = ((height * ydpi) / hwdpi) + 4; 10892141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 10893141cc406Sopenharmony_ci h += 16; 10894141cc406Sopenharmony_ci bpp = 1; 10895141cc406Sopenharmony_ci } 10896141cc406Sopenharmony_ci 10897141cc406Sopenharmony_ci /* sets y resolution */ 10898141cc406Sopenharmony_ci switch (ydpi) 10899141cc406Sopenharmony_ci { 10900141cc406Sopenharmony_ci case 1200: 10901141cc406Sopenharmony_ci motor[6] = 0x60; 10902141cc406Sopenharmony_ci motor[8] = 0x5E; /* *WORKING* value */ 10903141cc406Sopenharmony_ci motor[8] = 0x5F; /* 5F gives wrong colors ? */ 10904141cc406Sopenharmony_ci motor[8] = 0x58; 10905141cc406Sopenharmony_ci motor[9] = 0x05; 10906141cc406Sopenharmony_ci /* XXX test value XXX motor[14] = motor[14] & 0xF0; ~ 0x08 -> scan AND move */ 10907141cc406Sopenharmony_ci /* XXX test value XXX motor[14] = (motor[14] & 0xF0) | 0x04; -> 600 dpi ? */ 10908141cc406Sopenharmony_ci /* XXX test value XXX motor[14] = (motor[14] & 0xF0) | 0x0C; */ 10909141cc406Sopenharmony_ci motor[14] = motor[14] & 0xF0; /* *WORKING* 1200 dpi */ 10910141cc406Sopenharmony_ci break; 10911141cc406Sopenharmony_ci 10912141cc406Sopenharmony_ci case 600: 10913141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 10914141cc406Sopenharmony_ci { 10915141cc406Sopenharmony_ci motor[6] = 0xC0; 10916141cc406Sopenharmony_ci motor[7] = 0x2F; 10917141cc406Sopenharmony_ci motor[14] = motor[14] & 0xF0; 10918141cc406Sopenharmony_ci /* if (color >= RGB_MODE) 10919141cc406Sopenharmony_ci motor[14] |= 0x04; XXX STEF XXX */ 10920141cc406Sopenharmony_ci } 10921141cc406Sopenharmony_ci else 10922141cc406Sopenharmony_ci { 10923141cc406Sopenharmony_ci motor[6] = 0x60; 10924141cc406Sopenharmony_ci motor[14] = (motor[14] & 0xF0) | 0x04; 10925141cc406Sopenharmony_ci } 10926141cc406Sopenharmony_ci motor[8] = 0x2F; 10927141cc406Sopenharmony_ci motor[9] = 0x05; 10928141cc406Sopenharmony_ci break; 10929141cc406Sopenharmony_ci 10930141cc406Sopenharmony_ci case 300: 10931141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 10932141cc406Sopenharmony_ci { 10933141cc406Sopenharmony_ci motor[6] = 0xC0; 10934141cc406Sopenharmony_ci motor[14] = motor[14] & 0xF0; 10935141cc406Sopenharmony_ci if (color >= RGB_MODE) 10936141cc406Sopenharmony_ci motor[14] |= 0x04; 10937141cc406Sopenharmony_ci } 10938141cc406Sopenharmony_ci else 10939141cc406Sopenharmony_ci { 10940141cc406Sopenharmony_ci motor[6] = 0x00; 10941141cc406Sopenharmony_ci motor[14] = (motor[14] & 0xF0) | 0x0C; 10942141cc406Sopenharmony_ci } 10943141cc406Sopenharmony_ci motor[8] = 0x17; 10944141cc406Sopenharmony_ci motor[9] = 0x05; 10945141cc406Sopenharmony_ci 10946141cc406Sopenharmony_ci /* si | 0C h=2*w, si | 04 h=w ? */ 10947141cc406Sopenharmony_ci 10948141cc406Sopenharmony_ci break; 10949141cc406Sopenharmony_ci 10950141cc406Sopenharmony_ci case 150: 10951141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 10952141cc406Sopenharmony_ci { 10953141cc406Sopenharmony_ci motor[6] = 0xC0; 10954141cc406Sopenharmony_ci motor[9] = 0x05; 10955141cc406Sopenharmony_ci motor[14] = motor[14] & 0xF0; 10956141cc406Sopenharmony_ci if (color >= RGB_MODE) 10957141cc406Sopenharmony_ci motor[14] |= 0x04; 10958141cc406Sopenharmony_ci } 10959141cc406Sopenharmony_ci else 10960141cc406Sopenharmony_ci { 10961141cc406Sopenharmony_ci motor[6] = 0x00; 10962141cc406Sopenharmony_ci motor[9] = 0x07; 10963141cc406Sopenharmony_ci motor[14] = (motor[14] & 0xF0) | 0x0C; 10964141cc406Sopenharmony_ci } 10965141cc406Sopenharmony_ci motor[8] = 0x17; 10966141cc406Sopenharmony_ci break; 10967141cc406Sopenharmony_ci } 10968141cc406Sopenharmony_ci 10969141cc406Sopenharmony_ci /* different values for 610P in B&W */ 10970141cc406Sopenharmony_ci if ((sanei_umax_pp_getastra () <= 610) && (color < RGB_MODE)) 10971141cc406Sopenharmony_ci { 10972141cc406Sopenharmony_ci motor[7] = 0xC8; 10973141cc406Sopenharmony_ci motor[8] = 0x2F; 10974141cc406Sopenharmony_ci motor[9] = 0x05; 10975141cc406Sopenharmony_ci } 10976141cc406Sopenharmony_ci 10977141cc406Sopenharmony_ci /* y start -1 */ 10978141cc406Sopenharmony_ci y = (y * ydpi) / hwdpi; 10979141cc406Sopenharmony_ci 10980141cc406Sopenharmony_ci if (color >= RGB_MODE) 10981141cc406Sopenharmony_ci { 10982141cc406Sopenharmony_ci /* 00 seems to give better results ? */ 10983141cc406Sopenharmony_ci /* 80 some more gain, lamp power level ? */ 10984141cc406Sopenharmony_ci /* 8x does not make much difference */ 10985141cc406Sopenharmony_ci lm9811[6] = 0x8F; 10986141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 10987141cc406Sopenharmony_ci { 10988141cc406Sopenharmony_ci case 610: 10989141cc406Sopenharmony_ci lm9811[7] = 0x80; 10990141cc406Sopenharmony_ci motor[13] = 0x20; 10991141cc406Sopenharmony_ci break; 10992141cc406Sopenharmony_ci case 1600: 10993141cc406Sopenharmony_ci lm9811[7] = 0x70; 10994141cc406Sopenharmony_ci motor[13] = 0x03; 10995141cc406Sopenharmony_ci break; 10996141cc406Sopenharmony_ci default: 10997141cc406Sopenharmony_ci lm9811[7] = 0xF0; 10998141cc406Sopenharmony_ci motor[13] = 0x09; 10999141cc406Sopenharmony_ci } 11000141cc406Sopenharmony_ci } 11001141cc406Sopenharmony_ci else 11002141cc406Sopenharmony_ci { 11003141cc406Sopenharmony_ci motor[13] = 0xC0; 11004141cc406Sopenharmony_ci lm9811[6] = 0x80 | vgaGreen; 11005141cc406Sopenharmony_ci switch (sanei_umax_pp_getastra ()) 11006141cc406Sopenharmony_ci { 11007141cc406Sopenharmony_ci case 610: 11008141cc406Sopenharmony_ci lm9811[7] = 0xA0; 11009141cc406Sopenharmony_ci lm9811[6] = lm9811[6] | 0x40; 11010141cc406Sopenharmony_ci motor[13] = 0x6F; 11011141cc406Sopenharmony_ci break; 11012141cc406Sopenharmony_ci case 1600: 11013141cc406Sopenharmony_ci lm9811[7] = 0x20; 11014141cc406Sopenharmony_ci motor[13] = 0xC3; 11015141cc406Sopenharmony_ci break; 11016141cc406Sopenharmony_ci default: 11017141cc406Sopenharmony_ci lm9811[7] = 0xA0; 11018141cc406Sopenharmony_ci motor[13] = 0xC9; 11019141cc406Sopenharmony_ci } 11020141cc406Sopenharmony_ci } 11021141cc406Sopenharmony_ci 11022141cc406Sopenharmony_ci encodeCoefficient (color, dpi, calibration); 11023141cc406Sopenharmony_ci encodeWX (width, x, dpi, color, ccd, 0); 11024141cc406Sopenharmony_ci encodeHY (h, y, motor); 11025141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 11026141cc406Sopenharmony_ci encodeVGA (vgaRed, vgaGreen, vgaBlue, motor); 11027141cc406Sopenharmony_ci 11028141cc406Sopenharmony_ci#ifdef UMAX_PP_DANGEROUS_EXPERIMENT 11029141cc406Sopenharmony_ci /*motor[13] = 0x80; B&W bit */ 11030141cc406Sopenharmony_ci /*motor[13] = 0x40; green bit */ 11031141cc406Sopenharmony_ci /*motor[13] = 0x20; red bit */ 11032141cc406Sopenharmony_ci /*motor[13] = 0x10; blue bit */ 11033141cc406Sopenharmony_ci /* with cmd 01, may be use to do 3 pass scanning ? */ 11034141cc406Sopenharmony_ci /* bits 0 to 3 seem related to sharpness */ 11035141cc406Sopenharmony_ci f = fopen ("/tmp/dangerous.params", "rb"); 11036141cc406Sopenharmony_ci if (f != NULL) 11037141cc406Sopenharmony_ci { 11038141cc406Sopenharmony_ci fgets (line, 1024, f); 11039141cc406Sopenharmony_ci while (!feof (f)) 11040141cc406Sopenharmony_ci { 11041141cc406Sopenharmony_ci channel = 0; 11042141cc406Sopenharmony_ci if (sscanf (line, "CMD%1d", &channel) != 1) 11043141cc406Sopenharmony_ci channel = 0; 11044141cc406Sopenharmony_ci switch (channel) 11045141cc406Sopenharmony_ci { 11046141cc406Sopenharmony_ci case 0: 11047141cc406Sopenharmony_ci break; 11048141cc406Sopenharmony_ci case 1: 11049141cc406Sopenharmony_ci base = lm9811; 11050141cc406Sopenharmony_ci max = 8; 11051141cc406Sopenharmony_ci break; 11052141cc406Sopenharmony_ci case 2: 11053141cc406Sopenharmony_ci base = motor; 11054141cc406Sopenharmony_ci max = 16; 11055141cc406Sopenharmony_ci break; 11056141cc406Sopenharmony_ci case 8: 11057141cc406Sopenharmony_ci base = ccd; 11058141cc406Sopenharmony_ci max = 36; 11059141cc406Sopenharmony_ci break; 11060141cc406Sopenharmony_ci default: 11061141cc406Sopenharmony_ci channel = 0; 11062141cc406Sopenharmony_ci } 11063141cc406Sopenharmony_ci printf ("CMD%d BEFORE: ", channel); 11064141cc406Sopenharmony_ci for (i = 0; i < max; i++) 11065141cc406Sopenharmony_ci printf ("%02X ", base[i]); 11066141cc406Sopenharmony_ci printf ("\n"); 11067141cc406Sopenharmony_ci if (channel > 0) 11068141cc406Sopenharmony_ci { 11069141cc406Sopenharmony_ci ptr = line + 6; 11070141cc406Sopenharmony_ci for (i = 0; (i < max) && ((ptr - line) < strlen (line)); i++) 11071141cc406Sopenharmony_ci { 11072141cc406Sopenharmony_ci if (ptr[0] != '-') 11073141cc406Sopenharmony_ci { 11074141cc406Sopenharmony_ci sscanf (ptr, "%X", base + i); 11075141cc406Sopenharmony_ci } 11076141cc406Sopenharmony_ci ptr += 3; 11077141cc406Sopenharmony_ci } 11078141cc406Sopenharmony_ci } 11079141cc406Sopenharmony_ci printf ("CMD%d AFTER : ", channel); 11080141cc406Sopenharmony_ci for (i = 0; i < max; i++) 11081141cc406Sopenharmony_ci printf ("%02X ", base[i]); 11082141cc406Sopenharmony_ci printf ("\n"); 11083141cc406Sopenharmony_ci fgets (line, 1024, f); 11084141cc406Sopenharmony_ci } 11085141cc406Sopenharmony_ci fclose (f); 11086141cc406Sopenharmony_ci } 11087141cc406Sopenharmony_ci#endif 11088141cc406Sopenharmony_ci 11089141cc406Sopenharmony_ci if (DBG_LEVEL >= 64) 11090141cc406Sopenharmony_ci { 11091141cc406Sopenharmony_ci bloc2Decode (motor); 11092141cc406Sopenharmony_ci bloc8Decode (ccd); 11093141cc406Sopenharmony_ci } 11094141cc406Sopenharmony_ci 11095141cc406Sopenharmony_ci CMDSYNC (0x00); 11096141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 11097141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 11098141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 11099141cc406Sopenharmony_ci CMDSYNC (0xC2); 11100141cc406Sopenharmony_ci 11101141cc406Sopenharmony_ci /* 3 ccd lines + 3 gamma tables + end tag */ 11102141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 11103141cc406Sopenharmony_ci { 11104141cc406Sopenharmony_ci /* XXX STEF XXX : there is a 4 pixels shift to the right 11105141cc406Sopenharmony_ci * the first shading correction value applies to the forth 11106141cc406Sopenharmony_ci * pixel of scan (at 300 dpi), we already shift to the left 11107141cc406Sopenharmony_ci * when doing shadingCalibration, but now we have to move coeffs 11108141cc406Sopenharmony_ci * to match x coordinate */ 11109141cc406Sopenharmony_ci delta = x - sanei_umax_pp_getLeft (); 11110141cc406Sopenharmony_ci if (delta) 11111141cc406Sopenharmony_ci { 11112141cc406Sopenharmony_ci memcpy (calibration, 11113141cc406Sopenharmony_ci calibration + delta, (7650 - delta) * sizeof (int)); 11114141cc406Sopenharmony_ci } 11115141cc406Sopenharmony_ci CMDSET (4, 0x20E4, calibration); 11116141cc406Sopenharmony_ci } 11117141cc406Sopenharmony_ci else 11118141cc406Sopenharmony_ci { 11119141cc406Sopenharmony_ci CMDSET (4, 0x3EC6, calibration); 11120141cc406Sopenharmony_ci } 11121141cc406Sopenharmony_ci 11122141cc406Sopenharmony_ci COMPLETIONWAIT; 11123141cc406Sopenharmony_ci 11124141cc406Sopenharmony_ci *rbpp = bpp; 11125141cc406Sopenharmony_ci *rtw = tw; 11126141cc406Sopenharmony_ci *rth = th; 11127141cc406Sopenharmony_ci 11128141cc406Sopenharmony_ci free (buffer); 11129141cc406Sopenharmony_ci return 1; 11130141cc406Sopenharmony_ci} 11131141cc406Sopenharmony_ci 11132141cc406Sopenharmony_ci/* 11133141cc406Sopenharmony_ci * check the scanner model. Return 1220 for 11134141cc406Sopenharmony_ci * a 1220P, or 2000 for a 2000P. 11135141cc406Sopenharmony_ci * and 610 for a 610p 11136141cc406Sopenharmony_ci * values less than 610 are errors 11137141cc406Sopenharmony_ci */ 11138141cc406Sopenharmony_ciint 11139141cc406Sopenharmony_cisanei_umax_pp_checkModel (void) 11140141cc406Sopenharmony_ci{ 11141141cc406Sopenharmony_ci int *dest = NULL; 11142141cc406Sopenharmony_ci int state[16]; 11143141cc406Sopenharmony_ci int err = 0; 11144141cc406Sopenharmony_ci int i; 11145141cc406Sopenharmony_ci 11146141cc406Sopenharmony_ci int opsc35[37] = 11147141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x03, 0xC1, 0x80, 11148141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x16, 0x41, 0xE0, 0xAC, 0x03, 0x03, 0x00, 0x00, 11149141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 0x13, 0x1A, 0x00, 11150141cc406Sopenharmony_ci -1 11151141cc406Sopenharmony_ci }; 11152141cc406Sopenharmony_ci 11153141cc406Sopenharmony_ci /* if we have already detected a scanner different from */ 11154141cc406Sopenharmony_ci /* default type, no need to check again */ 11155141cc406Sopenharmony_ci if (sanei_umax_pp_getastra ()) 11156141cc406Sopenharmony_ci return sanei_umax_pp_getastra (); 11157141cc406Sopenharmony_ci 11158141cc406Sopenharmony_ci /* get scanner status */ 11159141cc406Sopenharmony_ci CMDGET (0x02, 16, state); 11160141cc406Sopenharmony_ci CMDSETGET (0x08, 36, opsc35); 11161141cc406Sopenharmony_ci CMDSYNC (0xC2); 11162141cc406Sopenharmony_ci 11163141cc406Sopenharmony_ci dest = (int *) malloc (65536 * sizeof (int)); 11164141cc406Sopenharmony_ci if (dest == NULL) 11165141cc406Sopenharmony_ci { 11166141cc406Sopenharmony_ci DBG (0, "%s:%d failed to allocate 256 Ko !\n", __FILE__, __LINE__); 11167141cc406Sopenharmony_ci return 0; 11168141cc406Sopenharmony_ci } 11169141cc406Sopenharmony_ci 11170141cc406Sopenharmony_ci /* init some buffer : default calibration data ? */ 11171141cc406Sopenharmony_ci dest[0] = 0x00; 11172141cc406Sopenharmony_ci dest[1] = 0x00; 11173141cc406Sopenharmony_ci dest[2] = 0x00; 11174141cc406Sopenharmony_ci for (i = 0; i < 768; i++) 11175141cc406Sopenharmony_ci dest[i + 3] = i % 256; 11176141cc406Sopenharmony_ci dest[768 + 3] = 0xAA; 11177141cc406Sopenharmony_ci dest[768 + 4] = 0xAA; 11178141cc406Sopenharmony_ci dest[768 + 5] = -1; 11179141cc406Sopenharmony_ci CMDSETGET (0x04, 768 + 5, dest); 11180141cc406Sopenharmony_ci 11181141cc406Sopenharmony_ci 11182141cc406Sopenharmony_ci /* check buffer returned */ 11183141cc406Sopenharmony_ci for (i = 0; i < 768; i++) 11184141cc406Sopenharmony_ci { 11185141cc406Sopenharmony_ci if (dest[i + 3] != (i % 256)) 11186141cc406Sopenharmony_ci { 11187141cc406Sopenharmony_ci DBG 11188141cc406Sopenharmony_ci (0, 11189141cc406Sopenharmony_ci "Error data altered: byte %d=0x%02X, should be 0x%02X ! (%s:%d)\n", 11190141cc406Sopenharmony_ci i, dest[i + 3], i % 256, __FILE__, __LINE__); 11191141cc406Sopenharmony_ci err = 1; 11192141cc406Sopenharmony_ci } 11193141cc406Sopenharmony_ci } 11194141cc406Sopenharmony_ci if (err) 11195141cc406Sopenharmony_ci return 0; 11196141cc406Sopenharmony_ci 11197141cc406Sopenharmony_ci 11198141cc406Sopenharmony_ci /* new part of buffer ... */ 11199141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 11200141cc406Sopenharmony_ci { 11201141cc406Sopenharmony_ci dest[i * 2] = i; 11202141cc406Sopenharmony_ci dest[i * 2 + 1] = 0x00; 11203141cc406Sopenharmony_ci } 11204141cc406Sopenharmony_ci CMDSETGET (0x08, 36, opsc35); 11205141cc406Sopenharmony_ci CMDSYNC (0xC2); 11206141cc406Sopenharmony_ci CMDSET (0x04, 512, dest); 11207141cc406Sopenharmony_ci 11208141cc406Sopenharmony_ci /* another new part ... */ 11209141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 11210141cc406Sopenharmony_ci { 11211141cc406Sopenharmony_ci dest[i * 2] = i; 11212141cc406Sopenharmony_ci dest[i * 2 + 1] = 0x04; /* instead of 0x00 */ 11213141cc406Sopenharmony_ci } 11214141cc406Sopenharmony_ci opsc35[2] = 0x06; /* instead of 0x04, write flag ? */ 11215141cc406Sopenharmony_ci CMDSETGET (0x08, 36, opsc35); 11216141cc406Sopenharmony_ci CMDSYNC (0xC2); 11217141cc406Sopenharmony_ci CMDSET (0x04, 512, dest); 11218141cc406Sopenharmony_ci 11219141cc406Sopenharmony_ci opsc35[2] = 0x04; /* return to initial value, read flag? */ 11220141cc406Sopenharmony_ci CMDSETGET (0x08, 36, opsc35); 11221141cc406Sopenharmony_ci CMDGET (0x04, 512, dest); 11222141cc406Sopenharmony_ci 11223141cc406Sopenharmony_ci /* check buffer returned */ 11224141cc406Sopenharmony_ci /* if 0x4 are still 0x04, we got a 1220P, else it is a 2000P */ 11225141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 11226141cc406Sopenharmony_ci { 11227141cc406Sopenharmony_ci if ((dest[2 * i] != i) 11228141cc406Sopenharmony_ci || ((dest[2 * i + 1] != 0x04) && (dest[2 * i + 1] != 0x00))) 11229141cc406Sopenharmony_ci { 11230141cc406Sopenharmony_ci DBG 11231141cc406Sopenharmony_ci (0, 11232141cc406Sopenharmony_ci "Error data altered: expected %d=(0x%02X,0x04), found (0x%02X,0x%02X) ! (%s:%d)\n", 11233141cc406Sopenharmony_ci i, i, dest[i * 2], dest[i * 2 + 1], __FILE__, __LINE__); 11234141cc406Sopenharmony_ci err = 0; 11235141cc406Sopenharmony_ci } 11236141cc406Sopenharmony_ci } 11237141cc406Sopenharmony_ci 11238141cc406Sopenharmony_ci /* if buffer unchanged, we have a 1600P, or a 1220P */ 11239141cc406Sopenharmony_ci /* if data has turned into 0, we have a 2000P */ 11240141cc406Sopenharmony_ci if (dest[1] == 0x00) 11241141cc406Sopenharmony_ci { 11242141cc406Sopenharmony_ci sanei_umax_pp_setastra (2000); 11243141cc406Sopenharmony_ci err = 2000; 11244141cc406Sopenharmony_ci } 11245141cc406Sopenharmony_ci else 11246141cc406Sopenharmony_ci { 11247141cc406Sopenharmony_ci /* detects 1600 by finding black scans */ 11248141cc406Sopenharmony_ci /* we defaults to 1220 */ 11249141cc406Sopenharmony_ci sanei_umax_pp_setastra (1220); 11250141cc406Sopenharmony_ci moveToOrigin (); 11251141cc406Sopenharmony_ci err = sanei_umax_pp_getastra (); 11252141cc406Sopenharmony_ci 11253141cc406Sopenharmony_ci /* parking */ 11254141cc406Sopenharmony_ci CMDSYNC (0xC2); 11255141cc406Sopenharmony_ci CMDSYNC (0x00); 11256141cc406Sopenharmony_ci if (sanei_umax_pp_park () == 0) 11257141cc406Sopenharmony_ci DBG (0, "Park failed !!! (%s:%d)\n", __FILE__, __LINE__); 11258141cc406Sopenharmony_ci 11259141cc406Sopenharmony_ci /* poll parking */ 11260141cc406Sopenharmony_ci do 11261141cc406Sopenharmony_ci { 11262141cc406Sopenharmony_ci sleep (1); 11263141cc406Sopenharmony_ci CMDSYNC (0x40); 11264141cc406Sopenharmony_ci } 11265141cc406Sopenharmony_ci while ((sanei_umax_pp_scannerStatus () & MOTOR_BIT) == 0x00); 11266141cc406Sopenharmony_ci } 11267141cc406Sopenharmony_ci 11268141cc406Sopenharmony_ci /* return guessed model number */ 11269141cc406Sopenharmony_ci CMDSYNC (0x00); 11270141cc406Sopenharmony_ci return err; 11271141cc406Sopenharmony_ci} 11272141cc406Sopenharmony_ci 11273141cc406Sopenharmony_ci 11274141cc406Sopenharmony_ci 11275141cc406Sopenharmony_ci/* sets, resets gamma tables */ 11276141cc406Sopenharmony_ci 11277141cc406Sopenharmony_civoid 11278141cc406Sopenharmony_cisanei_umax_pp_gamma (int *red, int *green, int *blue) 11279141cc406Sopenharmony_ci{ 11280141cc406Sopenharmony_ci if (red != NULL) 11281141cc406Sopenharmony_ci { 11282141cc406Sopenharmony_ci ggRed = red; 11283141cc406Sopenharmony_ci } 11284141cc406Sopenharmony_ci else 11285141cc406Sopenharmony_ci { 11286141cc406Sopenharmony_ci ggRed = ggamma; 11287141cc406Sopenharmony_ci } 11288141cc406Sopenharmony_ci 11289141cc406Sopenharmony_ci if (green != NULL) 11290141cc406Sopenharmony_ci { 11291141cc406Sopenharmony_ci ggGreen = green; 11292141cc406Sopenharmony_ci } 11293141cc406Sopenharmony_ci else 11294141cc406Sopenharmony_ci { 11295141cc406Sopenharmony_ci ggGreen = ggamma; 11296141cc406Sopenharmony_ci } 11297141cc406Sopenharmony_ci 11298141cc406Sopenharmony_ci if (blue != NULL) 11299141cc406Sopenharmony_ci { 11300141cc406Sopenharmony_ci ggBlue = blue; 11301141cc406Sopenharmony_ci } 11302141cc406Sopenharmony_ci else 11303141cc406Sopenharmony_ci { 11304141cc406Sopenharmony_ci ggBlue = ggamma; 11305141cc406Sopenharmony_ci } 11306141cc406Sopenharmony_ci} 11307141cc406Sopenharmony_ci 11308141cc406Sopenharmony_ci/* initialize scanner by loading default transformation table */ 11309141cc406Sopenharmony_ci/* O: failure 11310141cc406Sopenharmony_ci * 1: OK 11311141cc406Sopenharmony_ci */ 11312141cc406Sopenharmony_ciint 11313141cc406Sopenharmony_ciloadDefaultTables (void) 11314141cc406Sopenharmony_ci{ 11315141cc406Sopenharmony_ci int cmd01[36] = { 11316141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 11317141cc406Sopenharmony_ci 0x00, 0x03, 0xC1, 0x80, 0x60, 0x20, 0x00, 0x00, 11318141cc406Sopenharmony_ci 0x16, 0x41, 0xE0, 0xAC, 0x03, 0x03, 0x00, 0x00, 11319141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11320141cc406Sopenharmony_ci 0x00, 0xF0, 0x13, -1 11321141cc406Sopenharmony_ci }; 11322141cc406Sopenharmony_ci int opsc35[37] = { 11323141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 11324141cc406Sopenharmony_ci 0x00, 0x03, 0xC1, 0x80, 0x00, 0x00, 0x04, 0x00, 11325141cc406Sopenharmony_ci 0x16, 0x41, 0xE0, 0xAC, 0x03, 0x03, 0x00, 0x00, 11326141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 11327141cc406Sopenharmony_ci 0xDF, 0x13, 0x1A, 0x00, 11328141cc406Sopenharmony_ci -1 11329141cc406Sopenharmony_ci }; 11330141cc406Sopenharmony_ci int i, len, *cmd, err; 11331141cc406Sopenharmony_ci int buffer[774]; 11332141cc406Sopenharmony_ci int rc = 1; 11333141cc406Sopenharmony_ci 11334141cc406Sopenharmony_ci 11335141cc406Sopenharmony_ci /* 1600P have a different CCD command block */ 11336141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 11337141cc406Sopenharmony_ci { 11338141cc406Sopenharmony_ci opsc35[29] = 0x1A; 11339141cc406Sopenharmony_ci opsc35[30] = 0xEE; 11340141cc406Sopenharmony_ci } 11341141cc406Sopenharmony_ci 11342141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 11343141cc406Sopenharmony_ci { 11344141cc406Sopenharmony_ci len = 0x22; 11345141cc406Sopenharmony_ci cmd = cmd01; 11346141cc406Sopenharmony_ci /* XXX STEF XXX if we send F0, we get 0x10 back */ 11347141cc406Sopenharmony_ci cmd[0x21] = 0x10; 11348141cc406Sopenharmony_ci } 11349141cc406Sopenharmony_ci else 11350141cc406Sopenharmony_ci { 11351141cc406Sopenharmony_ci len = 0x24; 11352141cc406Sopenharmony_ci cmd = opsc35; 11353141cc406Sopenharmony_ci } 11354141cc406Sopenharmony_ci 11355141cc406Sopenharmony_ci /* set and reread first table */ 11356141cc406Sopenharmony_ci /* since 1660P seems to have another type of CCD 11357141cc406Sopenharmony_ci * this table is not sent/needed 11358141cc406Sopenharmony_ci */ 11359141cc406Sopenharmony_ci err = 0; 11360141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () != 1600) 11361141cc406Sopenharmony_ci { 11362141cc406Sopenharmony_ci CMDSETGET (8, len, cmd); 11363141cc406Sopenharmony_ci CMDSYNC (0xC2); 11364141cc406Sopenharmony_ci buffer[0] = 0x00; 11365141cc406Sopenharmony_ci buffer[1] = 0x00; 11366141cc406Sopenharmony_ci buffer[2] = 0x00; 11367141cc406Sopenharmony_ci for (i = 0; i < 768; i++) 11368141cc406Sopenharmony_ci buffer[i + 3] = i % 256; 11369141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 11370141cc406Sopenharmony_ci { 11371141cc406Sopenharmony_ci buffer[768 + 3] = 0xFF; 11372141cc406Sopenharmony_ci buffer[768 + 4] = 0xFF; 11373141cc406Sopenharmony_ci } 11374141cc406Sopenharmony_ci else 11375141cc406Sopenharmony_ci { 11376141cc406Sopenharmony_ci buffer[768 + 3] = 0xAA; 11377141cc406Sopenharmony_ci buffer[768 + 4] = 0xAA; 11378141cc406Sopenharmony_ci } 11379141cc406Sopenharmony_ci buffer[768 + 5] = -1; 11380141cc406Sopenharmony_ci CMDSETGET (4, 0x305, buffer); 11381141cc406Sopenharmony_ci 11382141cc406Sopenharmony_ci 11383141cc406Sopenharmony_ci /* check buffer returned */ 11384141cc406Sopenharmony_ci for (i = 0; i < 768; i++) 11385141cc406Sopenharmony_ci { 11386141cc406Sopenharmony_ci if (buffer[i + 3] != (i % 256)) 11387141cc406Sopenharmony_ci { 11388141cc406Sopenharmony_ci DBG 11389141cc406Sopenharmony_ci (0, 11390141cc406Sopenharmony_ci "Error data altered: byte %d=0x%02X, should be 0x%02X ! (%s:%d)\n", 11391141cc406Sopenharmony_ci i, buffer[i + 3], i % 256, __FILE__, __LINE__); 11392141cc406Sopenharmony_ci err = 1; 11393141cc406Sopenharmony_ci } 11394141cc406Sopenharmony_ci } 11395141cc406Sopenharmony_ci if (err) 11396141cc406Sopenharmony_ci return 0; 11397141cc406Sopenharmony_ci } 11398141cc406Sopenharmony_ci 11399141cc406Sopenharmony_ci /* second table ... */ 11400141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 11401141cc406Sopenharmony_ci { 11402141cc406Sopenharmony_ci buffer[i * 2] = i; 11403141cc406Sopenharmony_ci buffer[i * 2 + 1] = 0; 11404141cc406Sopenharmony_ci } 11405141cc406Sopenharmony_ci CMDSETGET (8, len, cmd); 11406141cc406Sopenharmony_ci CMDSYNC (0xC2); 11407141cc406Sopenharmony_ci CMDSET (4, 0x200, buffer); 11408141cc406Sopenharmony_ci 11409141cc406Sopenharmony_ci /* third table ... */ 11410141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 11411141cc406Sopenharmony_ci { 11412141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 11413141cc406Sopenharmony_ci { 11414141cc406Sopenharmony_ci buffer[i * 2] = i; 11415141cc406Sopenharmony_ci buffer[i * 2 + 1] = 0x01; /* instead of 0x00 */ 11416141cc406Sopenharmony_ci } 11417141cc406Sopenharmony_ci } 11418141cc406Sopenharmony_ci else 11419141cc406Sopenharmony_ci { 11420141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 11421141cc406Sopenharmony_ci { 11422141cc406Sopenharmony_ci buffer[i * 2] = i; 11423141cc406Sopenharmony_ci buffer[i * 2 + 1] = 0x04; /* instead of 0x00 */ 11424141cc406Sopenharmony_ci } 11425141cc406Sopenharmony_ci } 11426141cc406Sopenharmony_ci opsc35[2] = 0x06; 11427141cc406Sopenharmony_ci cmd01[1] = 0x80; 11428141cc406Sopenharmony_ci CMDSETGET (8, len, cmd); 11429141cc406Sopenharmony_ci CMDSYNC (0xC2); 11430141cc406Sopenharmony_ci CMDSET (4, 0x200, buffer); 11431141cc406Sopenharmony_ci 11432141cc406Sopenharmony_ci opsc35[2] = 0x04; 11433141cc406Sopenharmony_ci cmd01[1] = 0x00; 11434141cc406Sopenharmony_ci CMDSETGET (8, len, cmd); 11435141cc406Sopenharmony_ci CMDGET (4, 0x200, buffer); 11436141cc406Sopenharmony_ci /* check buffer returned */ 11437141cc406Sopenharmony_ci /* if 0x4 are still 0x0 (hum..), we got a 1220P, else it is a 2000P */ 11438141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 11439141cc406Sopenharmony_ci { 11440141cc406Sopenharmony_ci if ((buffer[2 * i] != i) 11441141cc406Sopenharmony_ci || ((buffer[2 * i + 1] != 0x04) && (buffer[2 * i + 1] != 0x01) 11442141cc406Sopenharmony_ci && (buffer[2 * i + 1] != 0x00))) 11443141cc406Sopenharmony_ci { 11444141cc406Sopenharmony_ci DBG 11445141cc406Sopenharmony_ci (0, 11446141cc406Sopenharmony_ci "Error data altered: expected %d=(0x%02X,0x04), found (0x%02X,0x%02X) ! (%s:%d)\n", 11447141cc406Sopenharmony_ci i, i, buffer[i * 2], buffer[i * 2 + 1], __FILE__, __LINE__); 11448141cc406Sopenharmony_ci err = 1; 11449141cc406Sopenharmony_ci } 11450141cc406Sopenharmony_ci } 11451141cc406Sopenharmony_ci if (err) 11452141cc406Sopenharmony_ci return 0; 11453141cc406Sopenharmony_ci 11454141cc406Sopenharmony_ci return rc; 11455141cc406Sopenharmony_ci} 11456141cc406Sopenharmony_ci 11457141cc406Sopenharmony_ci/* inquire scanner status 11458141cc406Sopenharmony_ci * O: failure 11459141cc406Sopenharmony_ci * 1: OK 11460141cc406Sopenharmony_ci * 2: first scanner init, needs re-homing 11461141cc406Sopenharmony_ci */ 11462141cc406Sopenharmony_ciint 11463141cc406Sopenharmony_ciinquire (void) 11464141cc406Sopenharmony_ci{ 11465141cc406Sopenharmony_ci int cmd01[36] = { 11466141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 11467141cc406Sopenharmony_ci 0x00, 0x03, 0xC1, 0x80, 0x60, 0x20, 0x00, 0x00, 11468141cc406Sopenharmony_ci 0x16, 0x41, 0xE0, 0xAC, 0x03, 0x03, 0x00, 0x00, 11469141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11470141cc406Sopenharmony_ci 0x00, 0xF0, 0x1B, -1 11471141cc406Sopenharmony_ci }; 11472141cc406Sopenharmony_ci int buffer[37]; 11473141cc406Sopenharmony_ci int rc = 1, first, i; 11474141cc406Sopenharmony_ci char str[106]; 11475141cc406Sopenharmony_ci 11476141cc406Sopenharmony_ci 11477141cc406Sopenharmony_ci /* inquiry: ask for RAM, CCD, ... */ 11478141cc406Sopenharmony_ci CMDSET (8, 0x23, cmd01); 11479141cc406Sopenharmony_ci CMDGET (8, 0x23, buffer); 11480141cc406Sopenharmony_ci 11481141cc406Sopenharmony_ci if (DBG_LEVEL > 8) 11482141cc406Sopenharmony_ci { 11483141cc406Sopenharmony_ci for (i = 0; i < 35; i++) 11484141cc406Sopenharmony_ci sprintf (str + 3 * i, "%02X ", buffer[i]); 11485141cc406Sopenharmony_ci str[105] = 0x00; 11486141cc406Sopenharmony_ci DBG (8, "SCANNER INFORMATION=%s\n", str); 11487141cc406Sopenharmony_ci } 11488141cc406Sopenharmony_ci 11489141cc406Sopenharmony_ci /* get state */ 11490141cc406Sopenharmony_ci CMDGET (2, 0x10, buffer); 11491141cc406Sopenharmony_ci first = 1; 11492141cc406Sopenharmony_ci for (i = 0; i < 14; i++) 11493141cc406Sopenharmony_ci { 11494141cc406Sopenharmony_ci if (buffer[i] != 0) 11495141cc406Sopenharmony_ci first = 0; 11496141cc406Sopenharmony_ci } 11497141cc406Sopenharmony_ci if (buffer[15] != 0) 11498141cc406Sopenharmony_ci first = 0; 11499141cc406Sopenharmony_ci if (first) 11500141cc406Sopenharmony_ci rc = 2; 11501141cc406Sopenharmony_ci 11502141cc406Sopenharmony_ci if (DBG_LEVEL > 8) 11503141cc406Sopenharmony_ci { 11504141cc406Sopenharmony_ci for (i = 0; i < 16; i++) 11505141cc406Sopenharmony_ci sprintf (str + 3 * i, "%02X ", buffer[i]); 11506141cc406Sopenharmony_ci str[48] = 0x00; 11507141cc406Sopenharmony_ci DBG (8, "SCANNER STATE=%s\n", str); 11508141cc406Sopenharmony_ci } 11509141cc406Sopenharmony_ci 11510141cc406Sopenharmony_ci return rc; 11511141cc406Sopenharmony_ci} 11512141cc406Sopenharmony_ci 11513141cc406Sopenharmony_ci/* 11514141cc406Sopenharmony_ci * computes DC offset to have black pixel really black out of 11515141cc406Sopenharmony_ci * CCD ie black gives 0 11516141cc406Sopenharmony_ci * 1220P implements the method described in LM9811 datasheet 11517141cc406Sopenharmony_ci * returns 1 and DC offsets in the corresponding vars on success . 11518141cc406Sopenharmony_ci * On failure, returns 0. 11519141cc406Sopenharmony_ci */ 11520141cc406Sopenharmony_cistatic int 11521141cc406Sopenharmony_cioffsetCalibration1220p (int color, int *offRed, int *offGreen, int *offBlue) 11522141cc406Sopenharmony_ci{ 11523141cc406Sopenharmony_ci unsigned char buffer[5300]; 11524141cc406Sopenharmony_ci int i, val; 11525141cc406Sopenharmony_ci int commit[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, -1 }; 11526141cc406Sopenharmony_ci int opsc04[9] = { 0x06, 0xF4, 0xFF, 0x81, 0x1B, 0x00, 0x00, 0x00, -1 }; 11527141cc406Sopenharmony_ci int opsc38[37] = 11528141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x40, 0x01, 11529141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x6E, 0x18, 0x10, 0x03, 0x06, 0x00, 0x00, 0x00, 11530141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 0x13, 0x1A, 0x00, 11531141cc406Sopenharmony_ci -1 11532141cc406Sopenharmony_ci }; 11533141cc406Sopenharmony_ci int opsc48[17] = 11534141cc406Sopenharmony_ci { 0x09, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x2F, 0x2F, 0x00, 0x00, 0x00, 11535141cc406Sopenharmony_ci 0x00, 0x40, 0xA4, 0x00, -1 11536141cc406Sopenharmony_ci }; 11537141cc406Sopenharmony_ci float low, high; 11538141cc406Sopenharmony_ci DBG (16, "entering offsetCalibration1220p() ... (%s:%d)\n", __FILE__, 11539141cc406Sopenharmony_ci __LINE__); 11540141cc406Sopenharmony_ci 11541141cc406Sopenharmony_ci /* really dirty hack: something is buggy in BW mode */ 11542141cc406Sopenharmony_ci /* we override mode with color until the bug is found */ 11543141cc406Sopenharmony_ci /* color = RGB_MODE; */ 11544141cc406Sopenharmony_ci 11545141cc406Sopenharmony_ci /* 1600P have a different CCD command block */ 11546141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 11547141cc406Sopenharmony_ci { 11548141cc406Sopenharmony_ci opsc04[0] = 0x19; 11549141cc406Sopenharmony_ci opsc04[1] = 0xD5; 11550141cc406Sopenharmony_ci opsc04[4] = 0x1B; 11551141cc406Sopenharmony_ci opsc04[7] = 0x20; 11552141cc406Sopenharmony_ci 11553141cc406Sopenharmony_ci opsc48[8] = 0x2B; 11554141cc406Sopenharmony_ci opsc48[11] = 0x20; 11555141cc406Sopenharmony_ci opsc48[12] = 0x08; 11556141cc406Sopenharmony_ci opsc48[13] = 0x42; 11557141cc406Sopenharmony_ci } 11558141cc406Sopenharmony_ci 11559141cc406Sopenharmony_ci /* offset calibration, scan 24 bytes of black in each color */ 11560141cc406Sopenharmony_ci /* component see section 5.1 of LM9811 datasheet */ 11561141cc406Sopenharmony_ci if (color >= RGB_MODE) 11562141cc406Sopenharmony_ci { 11563141cc406Sopenharmony_ci CMDSETGET (2, 0x10, opsc48); 11564141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opsc38); 11565141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); /* scan std, no 'enhancing' */ 11566141cc406Sopenharmony_ci CMDSYNC (0xC2); 11567141cc406Sopenharmony_ci if (sanei_umax_pp_scannerStatus () & 0x80) 11568141cc406Sopenharmony_ci { 11569141cc406Sopenharmony_ci CMDSYNC (0x00); 11570141cc406Sopenharmony_ci } 11571141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); /* commit ? */ 11572141cc406Sopenharmony_ci COMPLETIONWAIT; 11573141cc406Sopenharmony_ci CMDGETBUF (4, 0x18, buffer); 11574141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 11575141cc406Sopenharmony_ci Dump (0x18, buffer, NULL); 11576141cc406Sopenharmony_ci val = 0; 11577141cc406Sopenharmony_ci for (i = 0; i < 24; i++) 11578141cc406Sopenharmony_ci val += buffer[i]; 11579141cc406Sopenharmony_ci low = (float) val / i; /* Vadc1 */ 11580141cc406Sopenharmony_ci 11581141cc406Sopenharmony_ci 11582141cc406Sopenharmony_ci CMDSYNC (0x00); 11583141cc406Sopenharmony_ci opsc04[7] = opsc04[7] | 0x10; /* enhanced ? */ 11584141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 11585141cc406Sopenharmony_ci COMPLETIONWAIT; 11586141cc406Sopenharmony_ci CMDGETBUF (4, 0x18, buffer); 11587141cc406Sopenharmony_ci val = 0; 11588141cc406Sopenharmony_ci for (i = 0; i < 24; i++) 11589141cc406Sopenharmony_ci val += buffer[i]; 11590141cc406Sopenharmony_ci high = (float) val / i; /* Vadc2 */ 11591141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 11592141cc406Sopenharmony_ci Dump (0x18, buffer, NULL); 11593141cc406Sopenharmony_ci *offRed = 15.0 - ((high - low) * 2); 11594141cc406Sopenharmony_ci 11595141cc406Sopenharmony_ci /* block that repeats */ 11596141cc406Sopenharmony_ci /* must be monochrome since hscan=1 */ 11597141cc406Sopenharmony_ci opsc48[0] = 0x01; 11598141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 11599141cc406Sopenharmony_ci { 11600141cc406Sopenharmony_ci opsc48[12] = 0x0C; 11601141cc406Sopenharmony_ci opsc48[13] = 0x82; 11602141cc406Sopenharmony_ci } 11603141cc406Sopenharmony_ci else 11604141cc406Sopenharmony_ci { 11605141cc406Sopenharmony_ci opsc48[12] = 0x04; 11606141cc406Sopenharmony_ci opsc48[13] = 0x80; 11607141cc406Sopenharmony_ci } 11608141cc406Sopenharmony_ci CMDSETGET (2, 0x10, opsc48); 11609141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opsc38); 11610141cc406Sopenharmony_ci opsc04[7] = opsc04[7] & 0x20; 11611141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 11612141cc406Sopenharmony_ci CMDSYNC (0xC2); 11613141cc406Sopenharmony_ci if (sanei_umax_pp_scannerStatus () & 0x80) 11614141cc406Sopenharmony_ci { 11615141cc406Sopenharmony_ci CMDSYNC (0x00); 11616141cc406Sopenharmony_ci } 11617141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 11618141cc406Sopenharmony_ci COMPLETIONWAIT; 11619141cc406Sopenharmony_ci CMDGETBUF (4, 0x18, buffer); 11620141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 11621141cc406Sopenharmony_ci Dump (0x18, buffer, NULL); 11622141cc406Sopenharmony_ci val = 0; 11623141cc406Sopenharmony_ci for (i = 0; i < 24; i++) 11624141cc406Sopenharmony_ci val += buffer[i]; 11625141cc406Sopenharmony_ci low = (float) val / i; 11626141cc406Sopenharmony_ci 11627141cc406Sopenharmony_ci CMDSYNC (0x00); 11628141cc406Sopenharmony_ci opsc04[7] = opsc04[7] | 0x10; /* gain ? */ 11629141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 11630141cc406Sopenharmony_ci COMPLETIONWAIT; 11631141cc406Sopenharmony_ci CMDGETBUF (4, 0x18, buffer); 11632141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 11633141cc406Sopenharmony_ci Dump (0x18, buffer, NULL); 11634141cc406Sopenharmony_ci val = 0; 11635141cc406Sopenharmony_ci for (i = 0; i < 24; i++) 11636141cc406Sopenharmony_ci val += buffer[i]; 11637141cc406Sopenharmony_ci high = (float) val / i; 11638141cc406Sopenharmony_ci 11639141cc406Sopenharmony_ci *offBlue = 15.0 - ((high - low) * 2); 11640141cc406Sopenharmony_ci } 11641141cc406Sopenharmony_ci 11642141cc406Sopenharmony_ci /* block that repeats */ 11643141cc406Sopenharmony_ci if (color < RGB_MODE) 11644141cc406Sopenharmony_ci { 11645141cc406Sopenharmony_ci opsc48[0] = 0x05; /* B&H height is 5 */ 11646141cc406Sopenharmony_ci opsc48[13] = 0xC0; /* B&W mode */ 11647141cc406Sopenharmony_ci } 11648141cc406Sopenharmony_ci else 11649141cc406Sopenharmony_ci { 11650141cc406Sopenharmony_ci opsc48[0] = 0x05; /* color height is 5 (+4 ?) */ 11651141cc406Sopenharmony_ci opsc48[13] = 0xC1; /* some strange mode ? */ 11652141cc406Sopenharmony_ci } 11653141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 11654141cc406Sopenharmony_ci opsc48[13] = opsc48[13] | 0x02; 11655141cc406Sopenharmony_ci CMDSETGET (2, 0x10, opsc48); 11656141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opsc38); 11657141cc406Sopenharmony_ci opsc04[7] = opsc04[7] & 0x20; 11658141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 11659141cc406Sopenharmony_ci CMDSYNC (0xC2); 11660141cc406Sopenharmony_ci if (sanei_umax_pp_scannerStatus () & 0x80) 11661141cc406Sopenharmony_ci { 11662141cc406Sopenharmony_ci CMDSYNC (0x00); 11663141cc406Sopenharmony_ci } 11664141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 11665141cc406Sopenharmony_ci COMPLETIONWAIT; 11666141cc406Sopenharmony_ci CMDGETBUF (4, 0x18, buffer); 11667141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 11668141cc406Sopenharmony_ci Dump (0x18, buffer, NULL); 11669141cc406Sopenharmony_ci val = 0; 11670141cc406Sopenharmony_ci for (i = 0; i < 24; i++) 11671141cc406Sopenharmony_ci val += buffer[i]; 11672141cc406Sopenharmony_ci low = (float) val / i; 11673141cc406Sopenharmony_ci 11674141cc406Sopenharmony_ci CMDSYNC (0x00); 11675141cc406Sopenharmony_ci opsc04[7] = opsc04[7] | 0x10; 11676141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 11677141cc406Sopenharmony_ci COMPLETIONWAIT; 11678141cc406Sopenharmony_ci CMDGETBUF (4, 0x18, buffer); 11679141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 11680141cc406Sopenharmony_ci Dump (0x18, buffer, NULL); 11681141cc406Sopenharmony_ci val = 0; 11682141cc406Sopenharmony_ci for (i = 0; i < 24; i++) 11683141cc406Sopenharmony_ci val += buffer[i]; 11684141cc406Sopenharmony_ci high = (float) val / i; 11685141cc406Sopenharmony_ci 11686141cc406Sopenharmony_ci *offGreen = 15.0 - ((high - low) * 2); 11687141cc406Sopenharmony_ci 11688141cc406Sopenharmony_ci /*DBG (1, "STEF: offsets(RED,GREEN,BLUE=(%d,%d,%d)\n", *offRed, *offGreen, 11689141cc406Sopenharmony_ci *offBlue);*/ 11690141cc406Sopenharmony_ci DBG (16, "offsetCalibration1220p() done ...\n"); 11691141cc406Sopenharmony_ci return 1; 11692141cc406Sopenharmony_ci} 11693141cc406Sopenharmony_ci 11694141cc406Sopenharmony_ci/* 11695141cc406Sopenharmony_ci * computes DC offset to have black pixel really black out of 11696141cc406Sopenharmony_ci * CCD ie black gives 0 11697141cc406Sopenharmony_ci * 610P doesn't implement method described in LM9811 datasheet 11698141cc406Sopenharmony_ci * but scan a black line with decreasing offsets until the 11699141cc406Sopenharmony_ci * scanned data reach a 'good black level'. 11700141cc406Sopenharmony_ci * returns 1 and DC offsets in the corresponding vars on success . 11701141cc406Sopenharmony_ci * On failure, returns 0. 11702141cc406Sopenharmony_ci */ 11703141cc406Sopenharmony_cistatic int 11704141cc406Sopenharmony_cioffsetCalibration610p (int color, int *offRed, int *offGreen, int *offBlue) 11705141cc406Sopenharmony_ci{ 11706141cc406Sopenharmony_ci int motor[17] = { 11707141cc406Sopenharmony_ci 0x11, 0x00, 0x00, 0x70, 0x00, 0x00, 0xC0, 0x2F, 11708141cc406Sopenharmony_ci 0x17, 0x00, 0x00, 0xF0, 0x7D, 0x5F, 0xA4, 0x00, 11709141cc406Sopenharmony_ci -1 11710141cc406Sopenharmony_ci }; 11711141cc406Sopenharmony_ci 11712141cc406Sopenharmony_ci int ccd[37] = { 11713141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 11714141cc406Sopenharmony_ci 0x00, 0x04, 0x40, 0x01, 0x00, 0x20, 0x02, 0x00, 11715141cc406Sopenharmony_ci 0x76, 0x12, 0xB0, 0x03, 0x06, 0x00, 0x00, 0x00, 11716141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x4D, 0x4B, 0xD0, 0x68, 11717141cc406Sopenharmony_ci 0xDF, 0x13, 0x1A, 0x00, 11718141cc406Sopenharmony_ci -1 11719141cc406Sopenharmony_ci }; 11720141cc406Sopenharmony_ci 11721141cc406Sopenharmony_ci int lm9811[9] = { 11722141cc406Sopenharmony_ci 0x88, 0xE6, 0xFD, 0x8E, 0x30, 0x00, 0x40, 0xF0, 11723141cc406Sopenharmony_ci -1 11724141cc406Sopenharmony_ci }; 11725141cc406Sopenharmony_ci 11726141cc406Sopenharmony_ci int commit[9] = { 11727141cc406Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 11728141cc406Sopenharmony_ci -1 11729141cc406Sopenharmony_ci }; 11730141cc406Sopenharmony_ci 11731141cc406Sopenharmony_ci 11732141cc406Sopenharmony_ci int offset; 11733141cc406Sopenharmony_ci int level; 11734141cc406Sopenharmony_ci unsigned char data[40]; 11735141cc406Sopenharmony_ci int i; 11736141cc406Sopenharmony_ci int len; 11737141cc406Sopenharmony_ci int w; 11738141cc406Sopenharmony_ci 11739141cc406Sopenharmony_ci DBG (16, "entering offsetCalibration610P() ... (%s:%d)\n", __FILE__, 11740141cc406Sopenharmony_ci __LINE__); 11741141cc406Sopenharmony_ci 11742141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1220) 11743141cc406Sopenharmony_ci { 11744141cc406Sopenharmony_ci len = 0x22; 11745141cc406Sopenharmony_ci w = 40; 11746141cc406Sopenharmony_ci } 11747141cc406Sopenharmony_ci else 11748141cc406Sopenharmony_ci { 11749141cc406Sopenharmony_ci len = 0x24; 11750141cc406Sopenharmony_ci w = 40; 11751141cc406Sopenharmony_ci } 11752141cc406Sopenharmony_ci 11753141cc406Sopenharmony_ci *offRed = 0; 11754141cc406Sopenharmony_ci *offGreen = 0; 11755141cc406Sopenharmony_ci *offBlue = 0; 11756141cc406Sopenharmony_ci 11757141cc406Sopenharmony_ci /* first color channel: used both in color and b&w modes */ 11758141cc406Sopenharmony_ci /* offset to the max */ 11759141cc406Sopenharmony_ci /* supposed to be green component */ 11760141cc406Sopenharmony_ci offset = 0x10; 11761141cc406Sopenharmony_ci do 11762141cc406Sopenharmony_ci { 11763141cc406Sopenharmony_ci offset--; 11764141cc406Sopenharmony_ci 11765141cc406Sopenharmony_ci /* 7D: 0111 1101 */ 11766141cc406Sopenharmony_ci /* sets for the current offset */ 11767141cc406Sopenharmony_ci motor[12] = (offset << 2) | 0x40 | 0x01; 11768141cc406Sopenharmony_ci lm9811[7] = offset << 4; 11769141cc406Sopenharmony_ci 11770141cc406Sopenharmony_ci /* sends commands */ 11771141cc406Sopenharmony_ci CMDSYNC (0x00); 11772141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 11773141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 11774141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 11775141cc406Sopenharmony_ci CMDSYNC (0xC2); 11776141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 11777141cc406Sopenharmony_ci COMPLETIONWAIT; 11778141cc406Sopenharmony_ci CMDGETBUF (4, w, data); 11779141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 11780141cc406Sopenharmony_ci { 11781141cc406Sopenharmony_ci DumpNB (w, 1, data, NULL); 11782141cc406Sopenharmony_ci } 11783141cc406Sopenharmony_ci level = 0; 11784141cc406Sopenharmony_ci for (i = 0; i < w; i++) 11785141cc406Sopenharmony_ci level += data[i]; 11786141cc406Sopenharmony_ci } 11787141cc406Sopenharmony_ci /* loop while average >0.5 */ 11788141cc406Sopenharmony_ci while ((offset > 0) && ((level * 2) / w > 1)); 11789141cc406Sopenharmony_ci *offGreen = offset; 11790141cc406Sopenharmony_ci 11791141cc406Sopenharmony_ci /* offset calibration for the two other channels when in color */ 11792141cc406Sopenharmony_ci if (color >= RGB_MODE) 11793141cc406Sopenharmony_ci { 11794141cc406Sopenharmony_ci motor[0] = 0x01; 11795141cc406Sopenharmony_ci 11796141cc406Sopenharmony_ci offset = 0x10; 11797141cc406Sopenharmony_ci do 11798141cc406Sopenharmony_ci { 11799141cc406Sopenharmony_ci offset--; 11800141cc406Sopenharmony_ci 11801141cc406Sopenharmony_ci /* sets for the current offset */ 11802141cc406Sopenharmony_ci motor[13] = 0x90 | offset; 11803141cc406Sopenharmony_ci lm9811[7] = offset << 4; 11804141cc406Sopenharmony_ci 11805141cc406Sopenharmony_ci /* sends commands */ 11806141cc406Sopenharmony_ci CMDSYNC (0x00); 11807141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 11808141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 11809141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 11810141cc406Sopenharmony_ci CMDSYNC (0xC2); 11811141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 11812141cc406Sopenharmony_ci COMPLETIONWAIT; 11813141cc406Sopenharmony_ci CMDGETBUF (4, w, data); 11814141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 11815141cc406Sopenharmony_ci { 11816141cc406Sopenharmony_ci DumpNB (w, 1, data, NULL); 11817141cc406Sopenharmony_ci } 11818141cc406Sopenharmony_ci level = 0; 11819141cc406Sopenharmony_ci for (i = 0; i < w; i++) 11820141cc406Sopenharmony_ci level += data[i]; 11821141cc406Sopenharmony_ci } 11822141cc406Sopenharmony_ci /* loop while average >0.5 */ 11823141cc406Sopenharmony_ci while ((offset > 0) && ((level * 2) / w > 1)); 11824141cc406Sopenharmony_ci *offBlue = offset; 11825141cc406Sopenharmony_ci 11826141cc406Sopenharmony_ci /* last color component */ 11827141cc406Sopenharmony_ci motor[0] = 0x09; 11828141cc406Sopenharmony_ci ccd[13] = 0xD0 | (ccd[13] & 0x0F); 11829141cc406Sopenharmony_ci 11830141cc406Sopenharmony_ci offset = 0x10; 11831141cc406Sopenharmony_ci do 11832141cc406Sopenharmony_ci { 11833141cc406Sopenharmony_ci offset--; 11834141cc406Sopenharmony_ci 11835141cc406Sopenharmony_ci /* sets for the current offset */ 11836141cc406Sopenharmony_ci motor[11] = offset << 4; 11837141cc406Sopenharmony_ci lm9811[7] = offset << 4; 11838141cc406Sopenharmony_ci 11839141cc406Sopenharmony_ci /* sends commands */ 11840141cc406Sopenharmony_ci CMDSYNC (0x00); 11841141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 11842141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 11843141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 11844141cc406Sopenharmony_ci CMDSYNC (0xC2); 11845141cc406Sopenharmony_ci CMDSYNC (0x00); 11846141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 11847141cc406Sopenharmony_ci 11848141cc406Sopenharmony_ci COMPLETIONWAIT; 11849141cc406Sopenharmony_ci CMDGETBUF (4, w, data); 11850141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 11851141cc406Sopenharmony_ci { 11852141cc406Sopenharmony_ci CMDSYNC (0x00); 11853141cc406Sopenharmony_ci } 11854141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 11855141cc406Sopenharmony_ci { 11856141cc406Sopenharmony_ci DumpNB (w, 1, data, NULL); 11857141cc406Sopenharmony_ci } 11858141cc406Sopenharmony_ci level = 0; 11859141cc406Sopenharmony_ci for (i = 0; i < w; i++) 11860141cc406Sopenharmony_ci level += data[i]; 11861141cc406Sopenharmony_ci } 11862141cc406Sopenharmony_ci /* loop while average >0.5 */ 11863141cc406Sopenharmony_ci while ((offset > 0) && ((level * 2) / w > 1)); 11864141cc406Sopenharmony_ci *offRed = offset; 11865141cc406Sopenharmony_ci } 11866141cc406Sopenharmony_ci else 11867141cc406Sopenharmony_ci { 11868141cc406Sopenharmony_ci *offRed = 0x0F; 11869141cc406Sopenharmony_ci *offBlue = 0x0F; 11870141cc406Sopenharmony_ci } 11871141cc406Sopenharmony_ci 11872141cc406Sopenharmony_ci return 1; 11873141cc406Sopenharmony_ci} 11874141cc406Sopenharmony_ci 11875141cc406Sopenharmony_ci/* 11876141cc406Sopenharmony_ci * generic offset calibration function 11877141cc406Sopenharmony_ci */ 11878141cc406Sopenharmony_cistatic int 11879141cc406Sopenharmony_cioffsetCalibration (int color, int *dcRed, int *dcGreen, int *dcBlue) 11880141cc406Sopenharmony_ci{ 11881141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 11882141cc406Sopenharmony_ci { 11883141cc406Sopenharmony_ci if (offsetCalibration610p (color, dcRed, dcGreen, dcBlue) == 0) 11884141cc406Sopenharmony_ci { 11885141cc406Sopenharmony_ci DBG (0, "offsetCalibration610p failed !!! (%s:%d)\n", __FILE__, 11886141cc406Sopenharmony_ci __LINE__); 11887141cc406Sopenharmony_ci return 0; 11888141cc406Sopenharmony_ci } 11889141cc406Sopenharmony_ci DBG (16, "offsetCalibration610p(%d=>%d,%d,%d) passed ... (%s:%d)\n", 11890141cc406Sopenharmony_ci color, *dcRed, *dcGreen, *dcBlue, __FILE__, __LINE__); 11891141cc406Sopenharmony_ci } 11892141cc406Sopenharmony_ci else 11893141cc406Sopenharmony_ci { 11894141cc406Sopenharmony_ci if (offsetCalibration1220p (color, dcRed, dcGreen, dcBlue) == 0) 11895141cc406Sopenharmony_ci { 11896141cc406Sopenharmony_ci DBG (0, "offsetCalibration1220p failed !!! (%s:%d)\n", __FILE__, 11897141cc406Sopenharmony_ci __LINE__); 11898141cc406Sopenharmony_ci return 0; 11899141cc406Sopenharmony_ci } 11900141cc406Sopenharmony_ci DBG (16, "offsetCalibration1220p(%d=>%d,%d,%d) passed ... (%s:%d)\n", 11901141cc406Sopenharmony_ci color, *dcRed, *dcGreen, *dcBlue, __FILE__, __LINE__); 11902141cc406Sopenharmony_ci } 11903141cc406Sopenharmony_ci return 1; 11904141cc406Sopenharmony_ci} 11905141cc406Sopenharmony_ci 11906141cc406Sopenharmony_ci/* 11907141cc406Sopenharmony_ci * computes Video Gain Amplifier : LM9811 can corrects up to 3dB of 11908141cc406Sopenharmony_ci * light variation. So we must adjust VGA so that dynamic range is 11909141cc406Sopenharmony_ci * within 3db. It is achieved when min white pixel >= max white pixel / 2.8 11910141cc406Sopenharmony_ci * So we scan a white area and decrease gain until this condition is met. 11911141cc406Sopenharmony_ci * returns 1 and VGA values in the corresponding vars on success . 11912141cc406Sopenharmony_ci * On failure, returns 0. 11913141cc406Sopenharmony_ci */ 11914141cc406Sopenharmony_cistatic int 11915141cc406Sopenharmony_cicoarseGainCalibration610p (int color, int dcRed, int dcGreen, int dcBlue, 11916141cc406Sopenharmony_ci int *vgaRed, int *vgaGreen, int *vgaBlue) 11917141cc406Sopenharmony_ci{ 11918141cc406Sopenharmony_ci int motor[17] = { 11919141cc406Sopenharmony_ci 0x11, 0x00, 0x00, 0x70, 0x00, 0x00, 0xC0, 0x2F, 11920141cc406Sopenharmony_ci 0x17, 0x00, 0xFF, 0xAF, 0xAA, 0x6A, 0xA4, 0x00, 11921141cc406Sopenharmony_ci -1 11922141cc406Sopenharmony_ci }; 11923141cc406Sopenharmony_ci 11924141cc406Sopenharmony_ci int ccd[37] = { 11925141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 11926141cc406Sopenharmony_ci 0x00, 0x04, 0x40, 0x01, 0x00, 0x20, 0x02, 0x00, 11927141cc406Sopenharmony_ci 0x76, 0x41, 0xE0, 0xAC, 0x06, 0x00, 0x00, 0x9C, 11928141cc406Sopenharmony_ci 0x4A, 0xA0, 0x00, 0x8B, 0x4D, 0x4B, 0xD0, 0x68, 11929141cc406Sopenharmony_ci 0xDF, 0x13, 0x1A, 0x00, 11930141cc406Sopenharmony_ci -1 11931141cc406Sopenharmony_ci }; 11932141cc406Sopenharmony_ci 11933141cc406Sopenharmony_ci /* 11934141cc406Sopenharmony_ci * lm9811[7]= VGA << 4 11935141cc406Sopenharmony_ci * lm9811[6]= 0x40 | DC offset 11936141cc406Sopenharmony_ci */ 11937141cc406Sopenharmony_ci int lm9811[9] = { 11938141cc406Sopenharmony_ci 0x88, 0xE6, 0xFD, 0x8E, 0x30, 0x00, 0x40, 0xF0, 11939141cc406Sopenharmony_ci -1 11940141cc406Sopenharmony_ci }; 11941141cc406Sopenharmony_ci 11942141cc406Sopenharmony_ci int commit[9] = { 11943141cc406Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 11944141cc406Sopenharmony_ci -1 11945141cc406Sopenharmony_ci }; 11946141cc406Sopenharmony_ci 11947141cc406Sopenharmony_ci unsigned char data[5400]; 11948141cc406Sopenharmony_ci int i, len; 11949141cc406Sopenharmony_ci int w, xstart, xend; 11950141cc406Sopenharmony_ci int min, max; 11951141cc406Sopenharmony_ci 11952141cc406Sopenharmony_ci TRACE (16, "entering coarseGainCalibration610p ...\n"); 11953141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1220) 11954141cc406Sopenharmony_ci { 11955141cc406Sopenharmony_ci w = 2700; 11956141cc406Sopenharmony_ci len = 0x22; 11957141cc406Sopenharmony_ci } 11958141cc406Sopenharmony_ci else 11959141cc406Sopenharmony_ci { 11960141cc406Sopenharmony_ci w = 5400; 11961141cc406Sopenharmony_ci len = 0x24; 11962141cc406Sopenharmony_ci } 11963141cc406Sopenharmony_ci 11964141cc406Sopenharmony_ci /* move back to desired area */ 11965141cc406Sopenharmony_ci MOVE (-69, PRECISION_OFF, NULL); 11966141cc406Sopenharmony_ci 11967141cc406Sopenharmony_ci /* first scan : taking a reference full width scan to 11968141cc406Sopenharmony_ci * find usable full width of the CCD 11969141cc406Sopenharmony_ci */ 11970141cc406Sopenharmony_ci *vgaRed = 0x08; 11971141cc406Sopenharmony_ci *vgaGreen = 0x00; 11972141cc406Sopenharmony_ci *vgaBlue = 0x00; 11973141cc406Sopenharmony_ci 11974141cc406Sopenharmony_ci /* scanning red component -> h=1 */ 11975141cc406Sopenharmony_ci motor[0] = 0x01; 11976141cc406Sopenharmony_ci motor[13] = 0xAA; /* will be 6A below */ 11977141cc406Sopenharmony_ci 11978141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 11979141cc406Sopenharmony_ci encodeVGA (*vgaRed, *vgaGreen, *vgaBlue, motor); 11980141cc406Sopenharmony_ci 11981141cc406Sopenharmony_ci lm9811[7] = dcRed << 4; 11982141cc406Sopenharmony_ci lm9811[6] = 0x40 | *vgaRed; 11983141cc406Sopenharmony_ci 11984141cc406Sopenharmony_ci CMDSYNC (0x00); 11985141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 11986141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 11987141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 11988141cc406Sopenharmony_ci CMDSYNC (0xC2); 11989141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 11990141cc406Sopenharmony_ci 11991141cc406Sopenharmony_ci COMPLETIONWAIT; 11992141cc406Sopenharmony_ci CMDGETBUF (4, w, data); 11993141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 11994141cc406Sopenharmony_ci { 11995141cc406Sopenharmony_ci CMDSYNC (0x00); 11996141cc406Sopenharmony_ci } 11997141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 11998141cc406Sopenharmony_ci { 11999141cc406Sopenharmony_ci DumpNB (w, 1, data, NULL); 12000141cc406Sopenharmony_ci } 12001141cc406Sopenharmony_ci 12002141cc406Sopenharmony_ci /* find usable CCD area */ 12003141cc406Sopenharmony_ci i = 0; 12004141cc406Sopenharmony_ci while ((i < w) && (data[i] <= (targetCode * 2) / 5)) 12005141cc406Sopenharmony_ci i++; 12006141cc406Sopenharmony_ci xstart = i; 12007141cc406Sopenharmony_ci i = w - 1; 12008141cc406Sopenharmony_ci while ((i > 0) && (data[i] <= (targetCode * 2) / 5)) 12009141cc406Sopenharmony_ci i--; 12010141cc406Sopenharmony_ci xend = i; 12011141cc406Sopenharmony_ci DBG (32, "coarseGainCalibration610p: xstart=%d, xend=%d ->left=%d\n", 12012141cc406Sopenharmony_ci xstart, xend, ((xend + xstart - w) / 2)); 12013141cc406Sopenharmony_ci /* choose best 'left' position */ 12014141cc406Sopenharmony_ci sanei_umax_pp_setLeft ((xend + xstart - w) / 2); 12015141cc406Sopenharmony_ci 12016141cc406Sopenharmony_ci /* now do VGA calibration for green (=B&W channel) */ 12017141cc406Sopenharmony_ci motor[0] = 0x11; 12018141cc406Sopenharmony_ci motor[13] = 0x60 | (motor[13] & 0x0F); 12019141cc406Sopenharmony_ci 12020141cc406Sopenharmony_ci *vgaRed = 0x0F; 12021141cc406Sopenharmony_ci *vgaGreen = 0x0F; 12022141cc406Sopenharmony_ci *vgaBlue = 0x0F; 12023141cc406Sopenharmony_ci 12024141cc406Sopenharmony_ci for (*vgaGreen = 0x0F; *vgaGreen > 0; (*vgaGreen)--) 12025141cc406Sopenharmony_ci { 12026141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 12027141cc406Sopenharmony_ci encodeVGA (*vgaRed, *vgaGreen, *vgaBlue, motor); 12028141cc406Sopenharmony_ci 12029141cc406Sopenharmony_ci lm9811[7] = dcGreen << 4; 12030141cc406Sopenharmony_ci lm9811[6] = 0x40 | *vgaGreen; 12031141cc406Sopenharmony_ci 12032141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 12033141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 12034141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 12035141cc406Sopenharmony_ci CMDSYNC (0xC2); 12036141cc406Sopenharmony_ci CMDSYNC (0x00); 12037141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 12038141cc406Sopenharmony_ci 12039141cc406Sopenharmony_ci COMPLETIONWAIT; 12040141cc406Sopenharmony_ci CMDGETBUF (4, w, data); 12041141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 12042141cc406Sopenharmony_ci { 12043141cc406Sopenharmony_ci CMDSYNC (0x00); 12044141cc406Sopenharmony_ci } 12045141cc406Sopenharmony_ci 12046141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 12047141cc406Sopenharmony_ci { 12048141cc406Sopenharmony_ci DumpNB (w, 1, data, NULL); 12049141cc406Sopenharmony_ci } 12050141cc406Sopenharmony_ci 12051141cc406Sopenharmony_ci min = 0xFF; 12052141cc406Sopenharmony_ci max = 0x00; 12053141cc406Sopenharmony_ci for (i = xstart; i <= xend; i++) 12054141cc406Sopenharmony_ci { 12055141cc406Sopenharmony_ci if (data[i] < min) 12056141cc406Sopenharmony_ci min = data[i]; 12057141cc406Sopenharmony_ci if (data[i] > max) 12058141cc406Sopenharmony_ci max = data[i]; 12059141cc406Sopenharmony_ci } 12060141cc406Sopenharmony_ci if ((max <= targetCode) && (min > (((float) targetCode) / 2.8))) 12061141cc406Sopenharmony_ci break; 12062141cc406Sopenharmony_ci DBG (32, "coarseGainCalibration610p, target/2.8=%f\n", 12063141cc406Sopenharmony_ci (((float) targetCode) / 2.8)); 12064141cc406Sopenharmony_ci DBG (32, "coarseGainCalibration610p, green: min=%d, max=%d\n", min, 12065141cc406Sopenharmony_ci max); 12066141cc406Sopenharmony_ci } 12067141cc406Sopenharmony_ci 12068141cc406Sopenharmony_ci if (color >= RGB_MODE) 12069141cc406Sopenharmony_ci { 12070141cc406Sopenharmony_ci motor[0] = 0x01; 12071141cc406Sopenharmony_ci motor[13] = 0xA0 | (motor[13] & 0x0F); 12072141cc406Sopenharmony_ci 12073141cc406Sopenharmony_ci for (*vgaBlue = 0x0F; *vgaBlue > 0; (*vgaBlue)--) 12074141cc406Sopenharmony_ci { 12075141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 12076141cc406Sopenharmony_ci encodeVGA (*vgaRed, *vgaGreen, *vgaBlue, motor); 12077141cc406Sopenharmony_ci 12078141cc406Sopenharmony_ci lm9811[7] = dcBlue << 4; 12079141cc406Sopenharmony_ci lm9811[6] = 0x40 | *vgaBlue; 12080141cc406Sopenharmony_ci 12081141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 12082141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 12083141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 12084141cc406Sopenharmony_ci CMDSYNC (0xC2); 12085141cc406Sopenharmony_ci CMDSYNC (0x00); 12086141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 12087141cc406Sopenharmony_ci 12088141cc406Sopenharmony_ci COMPLETIONWAIT; 12089141cc406Sopenharmony_ci CMDGETBUF (4, w, data); 12090141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 12091141cc406Sopenharmony_ci { 12092141cc406Sopenharmony_ci CMDSYNC (0x00); 12093141cc406Sopenharmony_ci } 12094141cc406Sopenharmony_ci 12095141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 12096141cc406Sopenharmony_ci { 12097141cc406Sopenharmony_ci DumpNB (w, 1, data, NULL); 12098141cc406Sopenharmony_ci } 12099141cc406Sopenharmony_ci 12100141cc406Sopenharmony_ci min = 0xFF; 12101141cc406Sopenharmony_ci max = 0x00; 12102141cc406Sopenharmony_ci for (i = xstart; i <= xend; i++) 12103141cc406Sopenharmony_ci { 12104141cc406Sopenharmony_ci if (data[i] < min) 12105141cc406Sopenharmony_ci min = data[i]; 12106141cc406Sopenharmony_ci if (data[i] > max) 12107141cc406Sopenharmony_ci max = data[i]; 12108141cc406Sopenharmony_ci } 12109141cc406Sopenharmony_ci if ((max <= targetCode) && (min > (((float) targetCode) / 2.8))) 12110141cc406Sopenharmony_ci break; 12111141cc406Sopenharmony_ci DBG (32, "coarseGainCalibration610p, blue: min=%d, max=%d\n", min, 12112141cc406Sopenharmony_ci max); 12113141cc406Sopenharmony_ci } 12114141cc406Sopenharmony_ci 12115141cc406Sopenharmony_ci motor[0] = 0x09; 12116141cc406Sopenharmony_ci motor[13] = 0xE0 | (motor[13] & 0x0F); 12117141cc406Sopenharmony_ci 12118141cc406Sopenharmony_ci for (*vgaRed = 0x0F; *vgaRed > 0; (*vgaRed)--) 12119141cc406Sopenharmony_ci { 12120141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 12121141cc406Sopenharmony_ci encodeVGA (*vgaRed, *vgaGreen, *vgaBlue, motor); 12122141cc406Sopenharmony_ci 12123141cc406Sopenharmony_ci lm9811[7] = dcRed << 4; 12124141cc406Sopenharmony_ci lm9811[6] = 0x40 | *vgaRed; 12125141cc406Sopenharmony_ci 12126141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 12127141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 12128141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 12129141cc406Sopenharmony_ci CMDSYNC (0xC2); 12130141cc406Sopenharmony_ci CMDSYNC (0x00); 12131141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 12132141cc406Sopenharmony_ci 12133141cc406Sopenharmony_ci COMPLETIONWAIT; 12134141cc406Sopenharmony_ci CMDGETBUF (4, w, data); 12135141cc406Sopenharmony_ci if (gMode == UMAX_PP_PARPORT_EPP) 12136141cc406Sopenharmony_ci { 12137141cc406Sopenharmony_ci CMDSYNC (0x00); 12138141cc406Sopenharmony_ci } 12139141cc406Sopenharmony_ci 12140141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 12141141cc406Sopenharmony_ci { 12142141cc406Sopenharmony_ci DumpNB (w, 1, data, NULL); 12143141cc406Sopenharmony_ci } 12144141cc406Sopenharmony_ci 12145141cc406Sopenharmony_ci min = 0xFF; 12146141cc406Sopenharmony_ci max = 0x00; 12147141cc406Sopenharmony_ci for (i = xstart; i <= xend; i++) 12148141cc406Sopenharmony_ci { 12149141cc406Sopenharmony_ci if (data[i] < min) 12150141cc406Sopenharmony_ci min = data[i]; 12151141cc406Sopenharmony_ci if (data[i] > max) 12152141cc406Sopenharmony_ci max = data[i]; 12153141cc406Sopenharmony_ci } 12154141cc406Sopenharmony_ci if ((max <= targetCode) && (min > (((float) targetCode) / 2.8))) 12155141cc406Sopenharmony_ci break; 12156141cc406Sopenharmony_ci DBG (32, "coarseGainCalibration610p, red: min=%d, max=%d\n", min, 12157141cc406Sopenharmony_ci max); 12158141cc406Sopenharmony_ci } 12159141cc406Sopenharmony_ci } 12160141cc406Sopenharmony_ci else 12161141cc406Sopenharmony_ci { 12162141cc406Sopenharmony_ci *vgaRed = 0x0F; 12163141cc406Sopenharmony_ci *vgaBlue = 0x0F; 12164141cc406Sopenharmony_ci } 12165141cc406Sopenharmony_ci 12166141cc406Sopenharmony_ci TRACE (16, "coarseGainCalibration610p end ...\n"); 12167141cc406Sopenharmony_ci return 1; 12168141cc406Sopenharmony_ci} 12169141cc406Sopenharmony_ci 12170141cc406Sopenharmony_ci/* same as above, but for 1220P/1600P/200P */ 12171141cc406Sopenharmony_cistatic int 12172141cc406Sopenharmony_cicoarseGainCalibration1220p (int color, int dcRed, int dcGreen, 12173141cc406Sopenharmony_ci int dcBlue, int *vgaRed, int *vgaGreen, 12174141cc406Sopenharmony_ci int *vgaBlue) 12175141cc406Sopenharmony_ci{ 12176141cc406Sopenharmony_ci unsigned char buffer[5300]; 12177141cc406Sopenharmony_ci int i; 12178141cc406Sopenharmony_ci double sum; 12179141cc406Sopenharmony_ci int xstart = 540; 12180141cc406Sopenharmony_ci int xend = 5100; 12181141cc406Sopenharmony_ci int commit[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, -1 }; 12182141cc406Sopenharmony_ci int opsc04[9] = { 0x06, 0xF4, 0xFF, 0x81, 0x1B, 0x00, 0x00, 0x00, -1 }; 12183141cc406Sopenharmony_ci int opsc10[9] = { 0x06, 0xF4, 0xFF, 0x81, 0x1B, 0x00, 0x08, 0x00, -1 }; 12184141cc406Sopenharmony_ci int opsc18[17] = 12185141cc406Sopenharmony_ci { 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x2F, 0x2F, 0x00, 0x88, 0x08, 12186141cc406Sopenharmony_ci 0x00, 0x80, 0xA4, 0x00, -1 12187141cc406Sopenharmony_ci }; 12188141cc406Sopenharmony_ci int opsc39[37] = 12189141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x40, 0x01, 12190141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x6E, 0x41, 0x20, 0x24, 0x06, 0x00, 0x00, 0x00, 12191141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 0x13, 0x1A, 0x00, 12192141cc406Sopenharmony_ci -1 12193141cc406Sopenharmony_ci }; 12194141cc406Sopenharmony_ci int opsc40[37] = 12195141cc406Sopenharmony_ci { 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x40, 0x01, 12196141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x6E, 0x41, 0x60, 0x4F, 0x06, 0x00, 0x00, 0x00, 12197141cc406Sopenharmony_ci 0x46, 0xA0, 0x00, 0x8B, 0x49, 0x2A, 0xE9, 0x68, 0xDF, 0x93, 0x1A, 0x00, 12198141cc406Sopenharmony_ci -1 12199141cc406Sopenharmony_ci }; 12200141cc406Sopenharmony_ci int motor[17] = 12201141cc406Sopenharmony_ci { 0x09, 0x00, 0x00, 0x70, 0x00, 0x00, 0x60, 0x2F, 0x2F, 0x00, 0xA5, 0x09, 12202141cc406Sopenharmony_ci 0x00, 0x40, 0xA4, 0x00, -1 12203141cc406Sopenharmony_ci }; 12204141cc406Sopenharmony_ci 12205141cc406Sopenharmony_ci DBG (16, "entering coarseGainCalibration1220p() ... (%s:%d) \n", __FILE__, 12206141cc406Sopenharmony_ci __LINE__); 12207141cc406Sopenharmony_ci 12208141cc406Sopenharmony_ci /* temporary workaround */ 12209141cc406Sopenharmony_ci color = RGB_MODE; 12210141cc406Sopenharmony_ci 12211141cc406Sopenharmony_ci /* initialize VGA components */ 12212141cc406Sopenharmony_ci *vgaGreen = 0; 12213141cc406Sopenharmony_ci *vgaRed = 2; 12214141cc406Sopenharmony_ci *vgaBlue = 2; 12215141cc406Sopenharmony_ci 12216141cc406Sopenharmony_ci CMDSETGET (2, 0x10, opsc18); 12217141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opsc39); 12218141cc406Sopenharmony_ci opsc04[7] = opsc04[7] & 0x20; 12219141cc406Sopenharmony_ci opsc04[6] = 0x06; /* one channel gain value */ 12220141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc10); /* was opsc04, extraneaous string */ 12221141cc406Sopenharmony_ci /* that prevents using move .... */ 12222141cc406Sopenharmony_ci CMDSYNC (0xC2); 12223141cc406Sopenharmony_ci CMDSYNC (0x00); 12224141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 12225141cc406Sopenharmony_ci COMPLETIONWAIT; 12226141cc406Sopenharmony_ci CMDGETBUF (4, 0x200, buffer); 12227141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12228141cc406Sopenharmony_ci Dump (0x200, buffer, NULL); 12229141cc406Sopenharmony_ci 12230141cc406Sopenharmony_ci 12231141cc406Sopenharmony_ci /* auto correction of gain levels */ 12232141cc406Sopenharmony_ci /* first color component X */ 12233141cc406Sopenharmony_ci if (color >= RGB_MODE) 12234141cc406Sopenharmony_ci { 12235141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 12236141cc406Sopenharmony_ci { 12237141cc406Sopenharmony_ci motor[11] |= 0x20; 12238141cc406Sopenharmony_ci motor[12] = 0x08; 12239141cc406Sopenharmony_ci motor[13] |= 0x02; 12240141cc406Sopenharmony_ci 12241141cc406Sopenharmony_ci opsc04[7] |= 0x20; 12242141cc406Sopenharmony_ci } 12243141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 12244141cc406Sopenharmony_ci encodeVGA (*vgaRed, 0, 0, motor); 12245141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 12246141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opsc40); 12247141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12248141cc406Sopenharmony_ci { 12249141cc406Sopenharmony_ci bloc2Decode (motor); 12250141cc406Sopenharmony_ci bloc8Decode (opsc40); 12251141cc406Sopenharmony_ci } 12252141cc406Sopenharmony_ci opsc04[6] = *vgaRed; 12253141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 12254141cc406Sopenharmony_ci CMDSYNC (0xC2); 12255141cc406Sopenharmony_ci CMDSYNC (0x00); 12256141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 12257141cc406Sopenharmony_ci COMPLETIONWAIT; 12258141cc406Sopenharmony_ci CMDGETBUF (4, 0x14B4, buffer); 12259141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12260141cc406Sopenharmony_ci Dump (0x14B4, buffer, NULL); 12261141cc406Sopenharmony_ci sum = 0; 12262141cc406Sopenharmony_ci for (i = xstart; i < xend; i++) 12263141cc406Sopenharmony_ci sum += buffer[i]; 12264141cc406Sopenharmony_ci sum = sum / (xend - xstart); 12265141cc406Sopenharmony_ci while ((opsc04[6] < 0x0F) && (sum < 140)) 12266141cc406Sopenharmony_ci { 12267141cc406Sopenharmony_ci CMDSYNC (0x00); 12268141cc406Sopenharmony_ci opsc04[6]++; 12269141cc406Sopenharmony_ci CMDSETGET (1, 0x000008, opsc04); 12270141cc406Sopenharmony_ci COMPLETIONWAIT; 12271141cc406Sopenharmony_ci CMDGETBUF (4, 0x0014B4, buffer); 12272141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12273141cc406Sopenharmony_ci Dump (0x14B4, buffer, NULL); 12274141cc406Sopenharmony_ci sum = 0; 12275141cc406Sopenharmony_ci for (i = xstart; i < xend; i++) 12276141cc406Sopenharmony_ci sum += buffer[i]; 12277141cc406Sopenharmony_ci sum = sum / (xend - xstart); 12278141cc406Sopenharmony_ci } 12279141cc406Sopenharmony_ci *vgaRed = opsc04[6]; 12280141cc406Sopenharmony_ci 12281141cc406Sopenharmony_ci /* blue */ 12282141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 12283141cc406Sopenharmony_ci encodeVGA (0, 0, *vgaBlue, motor); 12284141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 12285141cc406Sopenharmony_ci { 12286141cc406Sopenharmony_ci motor[11] |= 0x20; 12287141cc406Sopenharmony_ci motor[12] = 0x08; 12288141cc406Sopenharmony_ci motor[13] |= 0x02; 12289141cc406Sopenharmony_ci 12290141cc406Sopenharmony_ci opsc04[7] |= 0x20; 12291141cc406Sopenharmony_ci } 12292141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 12293141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opsc40); 12294141cc406Sopenharmony_ci opsc04[6] = *vgaBlue; 12295141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 12296141cc406Sopenharmony_ci CMDSYNC (0xC2); 12297141cc406Sopenharmony_ci CMDSYNC (0x00); 12298141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 12299141cc406Sopenharmony_ci COMPLETIONWAIT; 12300141cc406Sopenharmony_ci CMDGETBUF (4, 0x14B4, buffer); 12301141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12302141cc406Sopenharmony_ci Dump (0x14B4, buffer, NULL); 12303141cc406Sopenharmony_ci sum = 0; 12304141cc406Sopenharmony_ci for (i = xstart; i < xend; i++) 12305141cc406Sopenharmony_ci sum += buffer[i]; 12306141cc406Sopenharmony_ci sum = sum / (xend - xstart); 12307141cc406Sopenharmony_ci while ((opsc04[6] < 0x0F) && (sum < 140)) 12308141cc406Sopenharmony_ci { 12309141cc406Sopenharmony_ci CMDSYNC (0x00); 12310141cc406Sopenharmony_ci opsc04[6]++; 12311141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 12312141cc406Sopenharmony_ci COMPLETIONWAIT; 12313141cc406Sopenharmony_ci CMDGETBUF (4, 0x14B4, buffer); 12314141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12315141cc406Sopenharmony_ci Dump (0x14B4, buffer, NULL); 12316141cc406Sopenharmony_ci sum = 0; 12317141cc406Sopenharmony_ci for (i = xstart; i < xend; i++) 12318141cc406Sopenharmony_ci sum += buffer[i]; 12319141cc406Sopenharmony_ci sum = sum / (xend - xstart); 12320141cc406Sopenharmony_ci } 12321141cc406Sopenharmony_ci *vgaBlue = opsc04[6]; 12322141cc406Sopenharmony_ci } 12323141cc406Sopenharmony_ci 12324141cc406Sopenharmony_ci 12325141cc406Sopenharmony_ci /* component Z: B&W component (green ...) */ 12326141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 12327141cc406Sopenharmony_ci encodeVGA (0, *vgaGreen, 0, motor); 12328141cc406Sopenharmony_ci if (color < RGB_MODE) 12329141cc406Sopenharmony_ci motor[0] = 0x01; /* in BW, scan zone doesn't have an extra 4 points */ 12330141cc406Sopenharmony_ci else 12331141cc406Sopenharmony_ci motor[0] = 0x05; /* extra 4 points */ 12332141cc406Sopenharmony_ci motor[13] = 0xC0; /* B&W */ 12333141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () == 1600) 12334141cc406Sopenharmony_ci { 12335141cc406Sopenharmony_ci motor[11] |= 0x20; 12336141cc406Sopenharmony_ci motor[12] = 0x08; 12337141cc406Sopenharmony_ci motor[13] |= 0x02; 12338141cc406Sopenharmony_ci 12339141cc406Sopenharmony_ci opsc04[7] |= 0x20; 12340141cc406Sopenharmony_ci } 12341141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 12342141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12343141cc406Sopenharmony_ci { 12344141cc406Sopenharmony_ci bloc2Decode (motor); 12345141cc406Sopenharmony_ci } 12346141cc406Sopenharmony_ci CMDSETGET (8, 0x24, opsc40); 12347141cc406Sopenharmony_ci opsc04[6] = *vgaGreen; 12348141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 12349141cc406Sopenharmony_ci CMDSYNC (0xC2); 12350141cc406Sopenharmony_ci CMDSYNC (0x00); 12351141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 12352141cc406Sopenharmony_ci COMPLETIONWAIT; 12353141cc406Sopenharmony_ci /* B&W hangs here XXX STEF XXX */ 12354141cc406Sopenharmony_ci CMDGETBUF (4, 0x14B4, buffer); 12355141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12356141cc406Sopenharmony_ci Dump (0x14B4, buffer, NULL); 12357141cc406Sopenharmony_ci sum = 0; 12358141cc406Sopenharmony_ci for (i = xstart; i < xend; i++) 12359141cc406Sopenharmony_ci sum += buffer[i]; 12360141cc406Sopenharmony_ci sum = sum / (xend - xstart); 12361141cc406Sopenharmony_ci while ((opsc04[6] < 0x07) && (sum < 110)) 12362141cc406Sopenharmony_ci { 12363141cc406Sopenharmony_ci CMDSYNC (0x00); 12364141cc406Sopenharmony_ci opsc04[6]++; 12365141cc406Sopenharmony_ci CMDSETGET (1, 0x08, opsc04); 12366141cc406Sopenharmony_ci COMPLETIONWAIT; 12367141cc406Sopenharmony_ci CMDGETBUF (4, 0x0014B4, buffer); 12368141cc406Sopenharmony_ci if (DBG_LEVEL >= 128) 12369141cc406Sopenharmony_ci Dump (0x14B4, buffer, NULL); 12370141cc406Sopenharmony_ci sum = 0; 12371141cc406Sopenharmony_ci for (i = xstart; i < xend; i++) 12372141cc406Sopenharmony_ci sum += buffer[i]; 12373141cc406Sopenharmony_ci sum = sum / (xend - xstart); 12374141cc406Sopenharmony_ci } 12375141cc406Sopenharmony_ci *vgaGreen = opsc04[6]; 12376141cc406Sopenharmony_ci DBG (1, "coarseGainCalibration1220p()=%d,%d,%d done ...\n", *vgaRed, 12377141cc406Sopenharmony_ci *vgaGreen, *vgaBlue); 12378141cc406Sopenharmony_ci return 1; 12379141cc406Sopenharmony_ci} 12380141cc406Sopenharmony_ci 12381141cc406Sopenharmony_ci/* 12382141cc406Sopenharmony_ci * generic function 12383141cc406Sopenharmony_ci */ 12384141cc406Sopenharmony_cistatic int 12385141cc406Sopenharmony_cicoarseGainCalibration (int color, int dcRed, int dcGreen, int dcBlue, 12386141cc406Sopenharmony_ci int *vgaRed, int *vgaGreen, int *vgaBlue) 12387141cc406Sopenharmony_ci{ 12388141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () <= 610) 12389141cc406Sopenharmony_ci { 12390141cc406Sopenharmony_ci if (coarseGainCalibration610p 12391141cc406Sopenharmony_ci (color, dcRed, dcGreen, dcBlue, vgaRed, vgaGreen, vgaBlue) == 0) 12392141cc406Sopenharmony_ci { 12393141cc406Sopenharmony_ci DBG (0, "coarseGainCalibration610p failed !!! (%s:%d)\n", __FILE__, 12394141cc406Sopenharmony_ci __LINE__); 12395141cc406Sopenharmony_ci return 0; 12396141cc406Sopenharmony_ci } 12397141cc406Sopenharmony_ci DBG (16, 12398141cc406Sopenharmony_ci "coarseGainCalibration610p passed ... (%s:%d)\n", __FILE__, 12399141cc406Sopenharmony_ci __LINE__); 12400141cc406Sopenharmony_ci } 12401141cc406Sopenharmony_ci else 12402141cc406Sopenharmony_ci { 12403141cc406Sopenharmony_ci if (coarseGainCalibration1220p 12404141cc406Sopenharmony_ci (color, dcRed, dcGreen, dcBlue, vgaRed, vgaGreen, vgaBlue) == 0) 12405141cc406Sopenharmony_ci { 12406141cc406Sopenharmony_ci DBG (0, "coarseGainCalibration1220p failed !!! (%s:%d)\n", __FILE__, 12407141cc406Sopenharmony_ci __LINE__); 12408141cc406Sopenharmony_ci return 0; 12409141cc406Sopenharmony_ci } 12410141cc406Sopenharmony_ci DBG (16, 12411141cc406Sopenharmony_ci "coarseGainCalibration1220p passed ... (%s:%d)\n", __FILE__, 12412141cc406Sopenharmony_ci __LINE__); 12413141cc406Sopenharmony_ci } 12414141cc406Sopenharmony_ci return 1; 12415141cc406Sopenharmony_ci} 12416141cc406Sopenharmony_ci 12417141cc406Sopenharmony_ci/* 12418141cc406Sopenharmony_ci * computes PGA offset for each pixel of the ccd. 12419141cc406Sopenharmony_ci * We scan a white area with PGA=0 and computes the 12420141cc406Sopenharmony_ci * offset to push the result in the correctable range 12421141cc406Sopenharmony_ci * returns 1 and PGA values in 'calibration' var on success . 12422141cc406Sopenharmony_ci * On failure, returns 0. 12423141cc406Sopenharmony_ci */ 12424141cc406Sopenharmony_cistatic int 12425141cc406Sopenharmony_cishadingCalibration610p (int color, int dcRed, int dcGreen, int dcBlue, 12426141cc406Sopenharmony_ci int vgaRed, int vgaGreen, int vgaBlue, 12427141cc406Sopenharmony_ci int *calibration) 12428141cc406Sopenharmony_ci{ 12429141cc406Sopenharmony_ci int motor[17] = { 12430141cc406Sopenharmony_ci 0x5A, 0x80, 0x02, 0x70, 0x00, 0x00, 0xC0, 0x00, 12431141cc406Sopenharmony_ci 0x17, 0x05, 0x6C, 0xAB, 0xAA, 0x2A, 0xA4, 0x00, 12432141cc406Sopenharmony_ci -1 12433141cc406Sopenharmony_ci }; 12434141cc406Sopenharmony_ci 12435141cc406Sopenharmony_ci int ccd[37] = { 12436141cc406Sopenharmony_ci 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x0C, 12437141cc406Sopenharmony_ci 0x00, 0x04, 0x40, 0x01, 0x00, 0x20, 0x02, 0x00, 12438141cc406Sopenharmony_ci 0x76, 0x5D, 0x40, 0xA5, 0x06, 0x00, 0x00, 0xE2, 12439141cc406Sopenharmony_ci 0x5E, 0xA0, 0x00, 0x8B, 0x4D, 0x4B, 0xD0, 0x68, 12440141cc406Sopenharmony_ci 0xDF, 0x13, 0x1A, 0x00, 12441141cc406Sopenharmony_ci -1 12442141cc406Sopenharmony_ci }; 12443141cc406Sopenharmony_ci 12444141cc406Sopenharmony_ci /* 12445141cc406Sopenharmony_ci * lm9811[7]= VGA << 4 12446141cc406Sopenharmony_ci * lm9811[6]= 0x40 | DC offset 12447141cc406Sopenharmony_ci */ 12448141cc406Sopenharmony_ci int lm9811[9] = { 12449141cc406Sopenharmony_ci 0x88, 0xE6, 0xFD, 0x8E, 0x30, 0x00, 0x0F, 0x80, 12450141cc406Sopenharmony_ci -1 12451141cc406Sopenharmony_ci }; 12452141cc406Sopenharmony_ci 12453141cc406Sopenharmony_ci int commit[9] = { 12454141cc406Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 12455141cc406Sopenharmony_ci -1 12456141cc406Sopenharmony_ci }; 12457141cc406Sopenharmony_ci 12458141cc406Sopenharmony_ci int len, dpi, size; 12459141cc406Sopenharmony_ci int bpp = 3; /* defaults to color scan value */ 12460141cc406Sopenharmony_ci int w, h, x, y; 12461141cc406Sopenharmony_ci int sum, i; 12462141cc406Sopenharmony_ci float avg, pct, coeff = 0; 12463141cc406Sopenharmony_ci unsigned char *data = NULL; 12464141cc406Sopenharmony_ci int top, bottom; 12465141cc406Sopenharmony_ci 12466141cc406Sopenharmony_ci TRACE (16, "entering shadingCalibration610p ...\n"); 12467141cc406Sopenharmony_ci len = 0x22; 12468141cc406Sopenharmony_ci w = 2550; 12469141cc406Sopenharmony_ci y = 10; 12470141cc406Sopenharmony_ci dpi = 300; 12471141cc406Sopenharmony_ci h = 90; 12472141cc406Sopenharmony_ci top = 8; 12473141cc406Sopenharmony_ci bottom = 8; 12474141cc406Sopenharmony_ci 12475141cc406Sopenharmony_ci /* move back first */ 12476141cc406Sopenharmony_ci MOVE (-31, PRECISION_OFF, NULL); 12477141cc406Sopenharmony_ci 12478141cc406Sopenharmony_ci /* gray scanning handling */ 12479141cc406Sopenharmony_ci if (color < RGB_MODE) 12480141cc406Sopenharmony_ci { 12481141cc406Sopenharmony_ci lm9811[7] = dcGreen << 4; 12482141cc406Sopenharmony_ci lm9811[6] = 0x40 | vgaGreen; 12483141cc406Sopenharmony_ci bpp = 1; 12484141cc406Sopenharmony_ci 12485141cc406Sopenharmony_ci motor[13] = 0x6F; 12486141cc406Sopenharmony_ci } 12487141cc406Sopenharmony_ci 12488141cc406Sopenharmony_ci data = (unsigned char *) malloc (w * h * bpp); 12489141cc406Sopenharmony_ci if (data == NULL) 12490141cc406Sopenharmony_ci { 12491141cc406Sopenharmony_ci DBG (0, "shadingCalibration610p: failed to allocate memory (%s:%d)\n", 12492141cc406Sopenharmony_ci __FILE__, __LINE__); 12493141cc406Sopenharmony_ci return 0; 12494141cc406Sopenharmony_ci } 12495141cc406Sopenharmony_ci memset (data, 0x00, w * h * bpp); 12496141cc406Sopenharmony_ci 12497141cc406Sopenharmony_ci /* prepare scan command */ 12498141cc406Sopenharmony_ci x = sanei_umax_pp_getLeft (); 12499141cc406Sopenharmony_ci encodeWX (w, x, dpi, color, ccd, bpp * w); 12500141cc406Sopenharmony_ci encodeHY (h, y, motor); 12501141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 12502141cc406Sopenharmony_ci encodeVGA (vgaRed, vgaGreen, vgaBlue, motor); 12503141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 12504141cc406Sopenharmony_ci { 12505141cc406Sopenharmony_ci bloc2Decode (motor); 12506141cc406Sopenharmony_ci bloc8Decode (ccd); 12507141cc406Sopenharmony_ci } 12508141cc406Sopenharmony_ci 12509141cc406Sopenharmony_ci CMDSYNC (0x00); 12510141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 12511141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 12512141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 12513141cc406Sopenharmony_ci CMDSYNC (0xC2); 12514141cc406Sopenharmony_ci CMDSETGET (4, 0x08, commit); 12515141cc406Sopenharmony_ci COMPLETIONWAIT; 12516141cc406Sopenharmony_ci 12517141cc406Sopenharmony_ci /* picture height is scan area height minus y */ 12518141cc406Sopenharmony_ci /* then we subtract 14 or 6 lines that aren't scanned */ 12519141cc406Sopenharmony_ci if (color < RGB_MODE) 12520141cc406Sopenharmony_ci h = h - y - 14; 12521141cc406Sopenharmony_ci else 12522141cc406Sopenharmony_ci h = h - y - 6; 12523141cc406Sopenharmony_ci size = w * bpp * h; 12524141cc406Sopenharmony_ci 12525141cc406Sopenharmony_ci DBG (128, 12526141cc406Sopenharmony_ci "shadingCalibration610p: trying to read 0x%06X bytes ... (%s:%d)\n", 12527141cc406Sopenharmony_ci size, __FILE__, __LINE__); 12528141cc406Sopenharmony_ci /* since we know that each scan line matches CCD width, we signals 12529141cc406Sopenharmony_ci * that data reading doesn't need to sync on each byte, but at each 12530141cc406Sopenharmony_ci * row end 12531141cc406Sopenharmony_ci */ 12532141cc406Sopenharmony_ci sanei_umax_pp_setfull (1); 12533141cc406Sopenharmony_ci CMDGETBUF (4, size, data); 12534141cc406Sopenharmony_ci sanei_umax_pp_setfull (0); 12535141cc406Sopenharmony_ci 12536141cc406Sopenharmony_ci /* computes correction here ... */ 12537141cc406Sopenharmony_ci /* debug image files */ 12538141cc406Sopenharmony_ci /* data is in R B G order */ 12539141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 12540141cc406Sopenharmony_ci DumpNB (w * bpp, h, data, NULL); 12541141cc406Sopenharmony_ci 12542141cc406Sopenharmony_ci /* zeroes all shading coefficients first */ 12543141cc406Sopenharmony_ci memset (calibration, 0x00, 3 * w * sizeof (int)); 12544141cc406Sopenharmony_ci 12545141cc406Sopenharmony_ci /* in gray scans, we have only green component (i=3) */ 12546141cc406Sopenharmony_ci if (color < RGB_MODE) 12547141cc406Sopenharmony_ci { 12548141cc406Sopenharmony_ci 12549141cc406Sopenharmony_ci /* build green only coefficients */ 12550141cc406Sopenharmony_ci for (x = 4; x < w; x++) 12551141cc406Sopenharmony_ci { 12552141cc406Sopenharmony_ci sum = 0; 12553141cc406Sopenharmony_ci for (y = top; y < h - bottom; y++) 12554141cc406Sopenharmony_ci sum += data[(y * bpp) * w + x]; 12555141cc406Sopenharmony_ci avg = ((float) (sum)) / ((float) (h - (top + bottom))); 12556141cc406Sopenharmony_ci /* XXX ICI XXX avg=128==>2 */ 12557141cc406Sopenharmony_ci /*coeff = (256.0 * (targetCode / avg - 1.0)) / 2.00;*/ 12558141cc406Sopenharmony_ci coeff = (256.0 * (targetCode / avg - 1.0)) / ((avg*3.5)/targetCode); 12559141cc406Sopenharmony_ci if (coeff < 0) 12560141cc406Sopenharmony_ci coeff = 0; 12561141cc406Sopenharmony_ci if (coeff > 255) 12562141cc406Sopenharmony_ci coeff = 255; 12563141cc406Sopenharmony_ci calibration[x + 2 * w - 4] = (int) (coeff + 0.5); 12564141cc406Sopenharmony_ci } 12565141cc406Sopenharmony_ci } 12566141cc406Sopenharmony_ci else 12567141cc406Sopenharmony_ci { 12568141cc406Sopenharmony_ci for (i = 0; i < 3; i++) 12569141cc406Sopenharmony_ci { 12570141cc406Sopenharmony_ci for (x = 4; x < w; x++) 12571141cc406Sopenharmony_ci { 12572141cc406Sopenharmony_ci sum = 0; 12573141cc406Sopenharmony_ci for (y = top; y < h - bottom; y++) 12574141cc406Sopenharmony_ci sum += data[(y * bpp + i) * w + x]; 12575141cc406Sopenharmony_ci avg = ((float) (sum)) / ((float) (h - (top + bottom))); 12576141cc406Sopenharmony_ci /* one step increase means a 0.71% increase of the final 12577141cc406Sopenharmony_ci pixel */ 12578141cc406Sopenharmony_ci pct = 100.0 - (avg * 100.0) / targetCode; 12579141cc406Sopenharmony_ci switch (i) 12580141cc406Sopenharmony_ci { 12581141cc406Sopenharmony_ci case 0: /* RED 1.80 */ 12582141cc406Sopenharmony_ci case 1: /* BLUE : 2.10 */ 12583141cc406Sopenharmony_ci coeff = (int) (pct / 0.57 + 0.5); 12584141cc406Sopenharmony_ci break; 12585141cc406Sopenharmony_ci case 2: /* GREEN 1.50 */ 12586141cc406Sopenharmony_ci coeff = (int) (pct / 0.45 + 0.5); 12587141cc406Sopenharmony_ci break; 12588141cc406Sopenharmony_ci } 12589141cc406Sopenharmony_ci if (coeff < 0) 12590141cc406Sopenharmony_ci coeff = 0; 12591141cc406Sopenharmony_ci if (coeff > 255) 12592141cc406Sopenharmony_ci coeff = 255; 12593141cc406Sopenharmony_ci calibration[x + i * w - 4] = (int) (coeff + 0.5); 12594141cc406Sopenharmony_ci } 12595141cc406Sopenharmony_ci /* 100 in coeffs -> +104 on picture */ 12596141cc406Sopenharmony_ci } 12597141cc406Sopenharmony_ci } 12598141cc406Sopenharmony_ci 12599141cc406Sopenharmony_ci /* use default color tables */ 12600141cc406Sopenharmony_ci for (x = 0; x < 256; x++) 12601141cc406Sopenharmony_ci { 12602141cc406Sopenharmony_ci calibration[3 * w + x] = ggRed[x]; 12603141cc406Sopenharmony_ci calibration[3 * w + x + 256] = ggGreen[x]; 12604141cc406Sopenharmony_ci calibration[3 * w + x + 512] = ggBlue[x]; 12605141cc406Sopenharmony_ci } 12606141cc406Sopenharmony_ci 12607141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 12608141cc406Sopenharmony_ci { 12609141cc406Sopenharmony_ci DumpNB (w * bpp, h, data, NULL); 12610141cc406Sopenharmony_ci DumpNB (w, h * bpp, data, NULL); 12611141cc406Sopenharmony_ci } 12612141cc406Sopenharmony_ci 12613141cc406Sopenharmony_ci free (data); 12614141cc406Sopenharmony_ci TRACE (16, "shadingCalibration610p end ...\n"); 12615141cc406Sopenharmony_ci return 1; 12616141cc406Sopenharmony_ci} 12617141cc406Sopenharmony_ci 12618141cc406Sopenharmony_ci/* 12619141cc406Sopenharmony_ci * build CCD correction: a white area below the top is scanned without 12620141cc406Sopenharmony_ci * correction, and the data are used to compute the coefficients needed 12621141cc406Sopenharmony_ci * to correct the light/CCD variations 12622141cc406Sopenharmony_ci */ 12623141cc406Sopenharmony_cistatic int 12624141cc406Sopenharmony_cishadingCalibration (int color, int dcRed, int dcGreen, int dcBlue, 12625141cc406Sopenharmony_ci int vgaRed, int vgaGreen, int vgaBlue, int *calibration) 12626141cc406Sopenharmony_ci{ 12627141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1220) 12628141cc406Sopenharmony_ci return shadingCalibration610p (color, dcRed, dcGreen, dcBlue, vgaRed, 12629141cc406Sopenharmony_ci vgaGreen, vgaBlue, calibration); 12630141cc406Sopenharmony_ci return shadingCalibration1220p (color, dcRed, dcGreen, dcBlue, vgaRed, 12631141cc406Sopenharmony_ci vgaGreen, vgaBlue, calibration); 12632141cc406Sopenharmony_ci} 12633141cc406Sopenharmony_ci 12634141cc406Sopenharmony_ci 12635141cc406Sopenharmony_ci/* 12636141cc406Sopenharmony_ci * this is certainly gamma calibration 12637141cc406Sopenharmony_ci * We scan a white area with PGA=0 and computes the 12638141cc406Sopenharmony_ci * offset to push the result in the correctable range 12639141cc406Sopenharmony_ci * returns 1 and PGA values in 'calibration' var on success . 12640141cc406Sopenharmony_ci * On failure, returns 0. 12641141cc406Sopenharmony_ci */ 12642141cc406Sopenharmony_cistatic int 12643141cc406Sopenharmony_cileftShadingCalibration610p (int color, int dcRed, int dcGreen, int dcBlue, 12644141cc406Sopenharmony_ci int vgaRed, int vgaGreen, int vgaBlue, 12645141cc406Sopenharmony_ci int *calibration) 12646141cc406Sopenharmony_ci{ 12647141cc406Sopenharmony_ci int motor[17] = { 12648141cc406Sopenharmony_ci 0x14, 0x80, 0x02, 0x60, 0xDE, 0x01, 0xC0, 0x2F, 12649141cc406Sopenharmony_ci 0x17, 0x00, 0x6C, 0xAB, 0xAA, 0x2A, 0xA4, 0x00, 12650141cc406Sopenharmony_ci -1 12651141cc406Sopenharmony_ci }; 12652141cc406Sopenharmony_ci 12653141cc406Sopenharmony_ci int ccd[37] = { 12654141cc406Sopenharmony_ci 0x00, 0x00, 0xD8, 0x27, 0xEC, 0x53, 0x7D, 0x8A, 12655141cc406Sopenharmony_ci 0x77, 0xE3, 0x1D, 0x79, 0x07, 0x20, 0x02, 0x00, 12656141cc406Sopenharmony_ci 0x76, 0x41, 0x80, 0xA3, 0xE5, 0x1D, 0x00, 0xF2, 12657141cc406Sopenharmony_ci 0x5D, 0xA0, 0x00, 0x8B, 0x4D, 0x4B, 0xD0, 0x68, 12658141cc406Sopenharmony_ci 0xDF, 0x13, 0x1A, 0x00, 12659141cc406Sopenharmony_ci -1 12660141cc406Sopenharmony_ci }; 12661141cc406Sopenharmony_ci 12662141cc406Sopenharmony_ci /* 12663141cc406Sopenharmony_ci * lm9811[7]= VGA << 4 12664141cc406Sopenharmony_ci * lm9811[6]= 0x40 | DC offset 12665141cc406Sopenharmony_ci * lm9811[6].bit7 = use shading data 12666141cc406Sopenharmony_ci */ 12667141cc406Sopenharmony_ci int lm9811[9] = { 12668141cc406Sopenharmony_ci 0x88, 0xE6, 0xFD, 0x8E, 0x30, 0x00, 0x8F, 0x80, 12669141cc406Sopenharmony_ci -1 12670141cc406Sopenharmony_ci }; 12671141cc406Sopenharmony_ci 12672141cc406Sopenharmony_ci int *commit = NULL; 12673141cc406Sopenharmony_ci 12674141cc406Sopenharmony_ci int len, dpi, size; 12675141cc406Sopenharmony_ci int w, h, x, y; 12676141cc406Sopenharmony_ci int ofst; 12677141cc406Sopenharmony_ci unsigned char *data = NULL; 12678141cc406Sopenharmony_ci 12679141cc406Sopenharmony_ci TRACE (16, "entering leftShadingCalibration610p ...\n"); 12680141cc406Sopenharmony_ci if (sanei_umax_pp_getastra () < 1220) 12681141cc406Sopenharmony_ci { 12682141cc406Sopenharmony_ci len = 0x22; 12683141cc406Sopenharmony_ci ofst = 28; 12684141cc406Sopenharmony_ci w = 2550; 12685141cc406Sopenharmony_ci x = 94 - ofst; /* left shift compared to shading calibration */ 12686141cc406Sopenharmony_ci y = 10; 12687141cc406Sopenharmony_ci dpi = 75; 12688141cc406Sopenharmony_ci h = 20; 12689141cc406Sopenharmony_ci } 12690141cc406Sopenharmony_ci else 12691141cc406Sopenharmony_ci { 12692141cc406Sopenharmony_ci len = 0x24; 12693141cc406Sopenharmony_ci ofst = 28; 12694141cc406Sopenharmony_ci w = 5100; 12695141cc406Sopenharmony_ci x = 180; 12696141cc406Sopenharmony_ci y = 10; 12697141cc406Sopenharmony_ci dpi = 600; 12698141cc406Sopenharmony_ci h = 67; 12699141cc406Sopenharmony_ci } 12700141cc406Sopenharmony_ci 12701141cc406Sopenharmony_ci commit = (int *) malloc ((w * 3 + 5) * sizeof (int)); 12702141cc406Sopenharmony_ci if (commit == NULL) 12703141cc406Sopenharmony_ci { 12704141cc406Sopenharmony_ci DBG (0, 12705141cc406Sopenharmony_ci "leftShadingCalibration610p: failed to allocate memory (%s:%d)\n", 12706141cc406Sopenharmony_ci __FILE__, __LINE__); 12707141cc406Sopenharmony_ci return 0; 12708141cc406Sopenharmony_ci } 12709141cc406Sopenharmony_ci 12710141cc406Sopenharmony_ci data = (unsigned char *) malloc (w * h * 3); 12711141cc406Sopenharmony_ci if (data == NULL) 12712141cc406Sopenharmony_ci { 12713141cc406Sopenharmony_ci DBG (0, 12714141cc406Sopenharmony_ci "leftShadingCalibration610p: failed to allocate memory (%s:%d)\n", 12715141cc406Sopenharmony_ci __FILE__, __LINE__); 12716141cc406Sopenharmony_ci free (commit); 12717141cc406Sopenharmony_ci return 0; 12718141cc406Sopenharmony_ci } 12719141cc406Sopenharmony_ci 12720141cc406Sopenharmony_ci /* prepare scan command */ 12721141cc406Sopenharmony_ci encodeWX (w, x, dpi, color, ccd, 7410); 12722141cc406Sopenharmony_ci encodeHY (h, y, motor); 12723141cc406Sopenharmony_ci encodeDC (dcRed, dcGreen, dcBlue, motor); 12724141cc406Sopenharmony_ci encodeVGA (vgaRed, vgaGreen, vgaBlue, motor); 12725141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 12726141cc406Sopenharmony_ci { 12727141cc406Sopenharmony_ci bloc2Decode (motor); 12728141cc406Sopenharmony_ci bloc8Decode (ccd); 12729141cc406Sopenharmony_ci } 12730141cc406Sopenharmony_ci 12731141cc406Sopenharmony_ci /* build shading calibration data */ 12732141cc406Sopenharmony_ci memset (commit, 0x00, (3 * w + 5) * sizeof (int)); 12733141cc406Sopenharmony_ci for (x = ofst; x < w; x++) 12734141cc406Sopenharmony_ci { 12735141cc406Sopenharmony_ci commit[x] = calibration[x - ofst]; 12736141cc406Sopenharmony_ci commit[x + w] = calibration[x - ofst + w]; 12737141cc406Sopenharmony_ci commit[x + 2 * w] = calibration[x - ofst + 2 * w]; 12738141cc406Sopenharmony_ci } 12739141cc406Sopenharmony_ci /* image data cropping coefficient */ 12740141cc406Sopenharmony_ci commit[3 * w + 3] = 0xFF; 12741141cc406Sopenharmony_ci commit[3 * w + 4] = 0xFF; 12742141cc406Sopenharmony_ci 12743141cc406Sopenharmony_ci CMDSYNC (0x00); 12744141cc406Sopenharmony_ci CMDSETGET (2, 0x10, motor); 12745141cc406Sopenharmony_ci CMDSETGET (8, len, ccd); 12746141cc406Sopenharmony_ci CMDSETGET (1, 0x08, lm9811); 12747141cc406Sopenharmony_ci CMDSYNC (0xC2); 12748141cc406Sopenharmony_ci CMDSETGET (4, 3 * w + 5, commit); 12749141cc406Sopenharmony_ci free (commit); 12750141cc406Sopenharmony_ci COMPLETIONWAIT; 12751141cc406Sopenharmony_ci 12752141cc406Sopenharmony_ci if (color >= RGB_MODE) 12753141cc406Sopenharmony_ci { 12754141cc406Sopenharmony_ci /* picture height is scan area height minus y */ 12755141cc406Sopenharmony_ci h = h - y; 12756141cc406Sopenharmony_ci size = w * 3 * h; 12757141cc406Sopenharmony_ci } 12758141cc406Sopenharmony_ci else 12759141cc406Sopenharmony_ci { 12760141cc406Sopenharmony_ci h = h - y - 1; 12761141cc406Sopenharmony_ci size = w * h; 12762141cc406Sopenharmony_ci } 12763141cc406Sopenharmony_ci DBG (128, 12764141cc406Sopenharmony_ci "leftShadingCalibration610p: trying to read 0x%06X bytes ... (%s:%d)\n", 12765141cc406Sopenharmony_ci size, __FILE__, __LINE__); 12766141cc406Sopenharmony_ci CMDGETBUF (4, size, data); 12767141cc406Sopenharmony_ci if (DBG_LEVEL > 128) 12768141cc406Sopenharmony_ci DumpNB (3 * w, h, data, NULL); 12769141cc406Sopenharmony_ci 12770141cc406Sopenharmony_ci /* XXX STEF XXX */ 12771141cc406Sopenharmony_ci /* build coefficients for the 25 left pixels */ 12772141cc406Sopenharmony_ci /* and compute gamma correction ? */ 12773141cc406Sopenharmony_ci 12774141cc406Sopenharmony_ci free (data); 12775141cc406Sopenharmony_ci TRACE (16, "leftShadingCalibration610p end ...\n"); 12776141cc406Sopenharmony_ci return 1; 12777141cc406Sopenharmony_ci} 12778