1141cc406Sopenharmony_ci/** @file plustek-pp_wrapper.c 2141cc406Sopenharmony_ci * @brief The interface to the parport driver-code and the kernel module. 3141cc406Sopenharmony_ci * 4141cc406Sopenharmony_ci * Based on sources acquired from Plustek Inc.<br> 5141cc406Sopenharmony_ci * Copyright (C) 2001-2004 Gerhard Jaeger <gerhard@gjaeger.de> 6141cc406Sopenharmony_ci * 7141cc406Sopenharmony_ci * History: 8141cc406Sopenharmony_ci * - 0.40 - initial version 9141cc406Sopenharmony_ci * - 0.41 - added _PTDRV_ADJUST call 10141cc406Sopenharmony_ci * - 0.42 - added setmap function 11141cc406Sopenharmony_ci * - fixed the stopscan problem, that causes a crash in the kernel module 12141cc406Sopenharmony_ci * - 0.43 - added initialized setting 13141cc406Sopenharmony_ci * - cleanup 14141cc406Sopenharmony_ci * . 15141cc406Sopenharmony_ci * <hr> 16141cc406Sopenharmony_ci * This file is part of the SANE package. 17141cc406Sopenharmony_ci * 18141cc406Sopenharmony_ci * This program is free software; you can redistribute it and/or 19141cc406Sopenharmony_ci * modify it under the terms of the GNU General Public License as 20141cc406Sopenharmony_ci * published by the Free Software Foundation; either version 2 of the 21141cc406Sopenharmony_ci * License, or (at your option) any later version. 22141cc406Sopenharmony_ci * 23141cc406Sopenharmony_ci * This program is distributed in the hope that it will be useful, but 24141cc406Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 25141cc406Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26141cc406Sopenharmony_ci * General Public License for more details. 27141cc406Sopenharmony_ci * 28141cc406Sopenharmony_ci * You should have received a copy of the GNU General Public License 29141cc406Sopenharmony_ci * along with this program. If not, see <https://www.gnu.org/licenses/>. 30141cc406Sopenharmony_ci * 31141cc406Sopenharmony_ci * As a special exception, the authors of SANE give permission for 32141cc406Sopenharmony_ci * additional uses of the libraries contained in this release of SANE. 33141cc406Sopenharmony_ci * 34141cc406Sopenharmony_ci * The exception is that, if you link a SANE library with other files 35141cc406Sopenharmony_ci * to produce an executable, this does not by itself cause the 36141cc406Sopenharmony_ci * resulting executable to be covered by the GNU General Public 37141cc406Sopenharmony_ci * License. Your use of that executable is in no way restricted on 38141cc406Sopenharmony_ci * account of linking the SANE library code into it. 39141cc406Sopenharmony_ci * 40141cc406Sopenharmony_ci * This exception does not, however, invalidate any other reasons why 41141cc406Sopenharmony_ci * the executable file might be covered by the GNU General Public 42141cc406Sopenharmony_ci * License. 43141cc406Sopenharmony_ci * 44141cc406Sopenharmony_ci * If you submit changes to SANE to the maintainers to be included in 45141cc406Sopenharmony_ci * a subsequent release, you agree by submitting the changes that 46141cc406Sopenharmony_ci * those changes may be distributed with this exception intact. 47141cc406Sopenharmony_ci * 48141cc406Sopenharmony_ci * If you write modifications of your own for SANE, it is your choice 49141cc406Sopenharmony_ci * whether to permit this exception to apply to your modifications. 50141cc406Sopenharmony_ci * If you do not wish that, delete this exception notice. 51141cc406Sopenharmony_ci * <hr> 52141cc406Sopenharmony_ci */ 53141cc406Sopenharmony_ci 54141cc406Sopenharmony_ci/******************* wrapper functions for parport device ********************/ 55141cc406Sopenharmony_ci 56141cc406Sopenharmony_ci#ifndef _BACKEND_ENABLED 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_cistatic int PtDrvInit( char *dev_name, unsigned short model_override ) 59141cc406Sopenharmony_ci{ 60141cc406Sopenharmony_ci _VAR_NOT_USED( dev_name ); 61141cc406Sopenharmony_ci _VAR_NOT_USED( model_override ); 62141cc406Sopenharmony_ci DBG( _DBG_ERROR, "Backend does not support direct I/O!\n" ); 63141cc406Sopenharmony_ci return -1; 64141cc406Sopenharmony_ci} 65141cc406Sopenharmony_ci 66141cc406Sopenharmony_cistatic int PtDrvShutdown( void ) 67141cc406Sopenharmony_ci{ 68141cc406Sopenharmony_ci return 0; 69141cc406Sopenharmony_ci} 70141cc406Sopenharmony_ci 71141cc406Sopenharmony_cistatic int PtDrvOpen( void ) 72141cc406Sopenharmony_ci{ 73141cc406Sopenharmony_ci DBG( _DBG_ERROR, "Backend does not support direct I/O!\n" ); 74141cc406Sopenharmony_ci return -1; 75141cc406Sopenharmony_ci} 76141cc406Sopenharmony_ci 77141cc406Sopenharmony_cistatic int PtDrvClose( void ) 78141cc406Sopenharmony_ci{ 79141cc406Sopenharmony_ci DBG( _DBG_ERROR, "Backend does not support direct I/O!\n" ); 80141cc406Sopenharmony_ci return 0; 81141cc406Sopenharmony_ci} 82141cc406Sopenharmony_ci 83141cc406Sopenharmony_cistatic int PtDrvIoctl( unsigned int cmd, void *arg ) 84141cc406Sopenharmony_ci{ 85141cc406Sopenharmony_ci DBG( _DBG_ERROR, "Backend does not support direct I/O!\n" ); 86141cc406Sopenharmony_ci _VAR_NOT_USED( cmd ); 87141cc406Sopenharmony_ci if( arg == NULL ) 88141cc406Sopenharmony_ci return -2; 89141cc406Sopenharmony_ci return -1; 90141cc406Sopenharmony_ci} 91141cc406Sopenharmony_ci 92141cc406Sopenharmony_cistatic int PtDrvRead( unsigned char *buffer, int count ) 93141cc406Sopenharmony_ci{ 94141cc406Sopenharmony_ci DBG( _DBG_ERROR, "Backend does not support direct I/O!\n" ); 95141cc406Sopenharmony_ci _VAR_NOT_USED( count ); 96141cc406Sopenharmony_ci if( buffer == NULL ) 97141cc406Sopenharmony_ci return -2; 98141cc406Sopenharmony_ci return -1; 99141cc406Sopenharmony_ci} 100141cc406Sopenharmony_ci#endif /* _BACKEND_ENABLED */ 101141cc406Sopenharmony_ci 102141cc406Sopenharmony_ci/** 103141cc406Sopenharmony_ci */ 104141cc406Sopenharmony_cistatic int ppDev_open( const char *dev_name, void *misc ) 105141cc406Sopenharmony_ci{ 106141cc406Sopenharmony_ci int result; 107141cc406Sopenharmony_ci int handle; 108141cc406Sopenharmony_ci CompatAdjDef compatAdj; 109141cc406Sopenharmony_ci PPAdjDef adj; 110141cc406Sopenharmony_ci unsigned short version = _PTDRV_IOCTL_VERSION; 111141cc406Sopenharmony_ci Plustek_Device *dev = (Plustek_Device *)misc; 112141cc406Sopenharmony_ci 113141cc406Sopenharmony_ci if( dev->adj.direct_io ) { 114141cc406Sopenharmony_ci result = PtDrvInit( dev_name, dev->adj.mov ); 115141cc406Sopenharmony_ci if( 0 != result ) { 116141cc406Sopenharmony_ci DBG( _DBG_ERROR, "open: PtDrvInit failed: %d\n", result ); 117141cc406Sopenharmony_ci return -1; 118141cc406Sopenharmony_ci } 119141cc406Sopenharmony_ci } 120141cc406Sopenharmony_ci 121141cc406Sopenharmony_ci if( dev->adj.direct_io ) 122141cc406Sopenharmony_ci handle = PtDrvOpen(); 123141cc406Sopenharmony_ci else 124141cc406Sopenharmony_ci handle = open( dev_name, O_RDONLY ); 125141cc406Sopenharmony_ci 126141cc406Sopenharmony_ci if ( handle < 0 ) { 127141cc406Sopenharmony_ci DBG( _DBG_ERROR, "open: can't open %s as a device\n", dev_name ); 128141cc406Sopenharmony_ci return handle; 129141cc406Sopenharmony_ci } 130141cc406Sopenharmony_ci 131141cc406Sopenharmony_ci if( dev->adj.direct_io ) 132141cc406Sopenharmony_ci result = PtDrvIoctl( _PTDRV_OPEN_DEVICE, &version ); 133141cc406Sopenharmony_ci else 134141cc406Sopenharmony_ci result = ioctl( handle, _PTDRV_OPEN_DEVICE, &version ); 135141cc406Sopenharmony_ci 136141cc406Sopenharmony_ci if( result < 0 ) { 137141cc406Sopenharmony_ci 138141cc406Sopenharmony_ci if( -9019 == result ) { 139141cc406Sopenharmony_ci 140141cc406Sopenharmony_ci DBG( _DBG_INFO, "Version 0x%04x not supported, trying " 141141cc406Sopenharmony_ci "compatibility version 0x%04x\n", 142141cc406Sopenharmony_ci _PTDRV_IOCTL_VERSION, _PTDRV_COMPAT_IOCTL_VERSION); 143141cc406Sopenharmony_ci 144141cc406Sopenharmony_ci version = _PTDRV_COMPAT_IOCTL_VERSION; 145141cc406Sopenharmony_ci 146141cc406Sopenharmony_ci if( dev->adj.direct_io ) 147141cc406Sopenharmony_ci result = PtDrvIoctl( _PTDRV_OPEN_DEVICE, &version ); 148141cc406Sopenharmony_ci else 149141cc406Sopenharmony_ci result = ioctl( handle, _PTDRV_OPEN_DEVICE, &version ); 150141cc406Sopenharmony_ci 151141cc406Sopenharmony_ci if( result < 0 ) { 152141cc406Sopenharmony_ci 153141cc406Sopenharmony_ci if( dev->adj.direct_io ) 154141cc406Sopenharmony_ci PtDrvClose(); 155141cc406Sopenharmony_ci else 156141cc406Sopenharmony_ci close( dev->fd ); 157141cc406Sopenharmony_ci 158141cc406Sopenharmony_ci DBG( _DBG_ERROR, 159141cc406Sopenharmony_ci "ioctl PT_DRV_OPEN_DEVICE failed(%d)\n", result ); 160141cc406Sopenharmony_ci 161141cc406Sopenharmony_ci if( -9019 == result ) { 162141cc406Sopenharmony_ci DBG( _DBG_ERROR, 163141cc406Sopenharmony_ci "Version problem, please recompile driver!\n" ); 164141cc406Sopenharmony_ci } 165141cc406Sopenharmony_ci } else { 166141cc406Sopenharmony_ci 167141cc406Sopenharmony_ci DBG( _DBG_INFO, "Using compatibility version\n" ); 168141cc406Sopenharmony_ci 169141cc406Sopenharmony_ci compatAdj.lampOff = dev->adj.lampOff; 170141cc406Sopenharmony_ci compatAdj.lampOffOnEnd = dev->adj.lampOffOnEnd; 171141cc406Sopenharmony_ci compatAdj.warmup = dev->adj.warmup; 172141cc406Sopenharmony_ci 173141cc406Sopenharmony_ci memcpy( &compatAdj.pos, &dev->adj.pos, sizeof(OffsDef)); 174141cc406Sopenharmony_ci memcpy( &compatAdj.neg, &dev->adj.neg, sizeof(OffsDef)); 175141cc406Sopenharmony_ci memcpy( &compatAdj.tpa, &dev->adj.tpa, sizeof(OffsDef)); 176141cc406Sopenharmony_ci 177141cc406Sopenharmony_ci if( dev->adj.direct_io ) 178141cc406Sopenharmony_ci PtDrvIoctl( _PTDRV_ADJUST, &compatAdj ); 179141cc406Sopenharmony_ci else 180141cc406Sopenharmony_ci ioctl( handle, _PTDRV_ADJUST, &compatAdj ); 181141cc406Sopenharmony_ci return handle; 182141cc406Sopenharmony_ci } 183141cc406Sopenharmony_ci } 184141cc406Sopenharmony_ci return result; 185141cc406Sopenharmony_ci } 186141cc406Sopenharmony_ci 187141cc406Sopenharmony_ci memset( &adj, 0, sizeof(PPAdjDef)); 188141cc406Sopenharmony_ci 189141cc406Sopenharmony_ci adj.lampOff = dev->adj.lampOff; 190141cc406Sopenharmony_ci adj.lampOffOnEnd = dev->adj.lampOffOnEnd; 191141cc406Sopenharmony_ci adj.warmup = dev->adj.warmup; 192141cc406Sopenharmony_ci 193141cc406Sopenharmony_ci memcpy( &adj.pos, &dev->adj.pos, sizeof(OffsDef)); 194141cc406Sopenharmony_ci memcpy( &adj.neg, &dev->adj.neg, sizeof(OffsDef)); 195141cc406Sopenharmony_ci memcpy( &adj.tpa, &dev->adj.tpa, sizeof(OffsDef)); 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_ci adj.rgamma = dev->adj.rgamma; 198141cc406Sopenharmony_ci adj.ggamma = dev->adj.ggamma; 199141cc406Sopenharmony_ci adj.bgamma = dev->adj.bgamma; 200141cc406Sopenharmony_ci adj.graygamma = dev->adj.graygamma; 201141cc406Sopenharmony_ci 202141cc406Sopenharmony_ci if( dev->adj.direct_io ) 203141cc406Sopenharmony_ci PtDrvIoctl( _PTDRV_ADJUST, &adj ); 204141cc406Sopenharmony_ci else 205141cc406Sopenharmony_ci ioctl( handle, _PTDRV_ADJUST, &adj ); 206141cc406Sopenharmony_ci 207141cc406Sopenharmony_ci dev->initialized = SANE_TRUE; 208141cc406Sopenharmony_ci return handle; 209141cc406Sopenharmony_ci} 210141cc406Sopenharmony_ci 211141cc406Sopenharmony_ci/** 212141cc406Sopenharmony_ci */ 213141cc406Sopenharmony_cistatic int ppDev_close( Plustek_Device *dev ) 214141cc406Sopenharmony_ci{ 215141cc406Sopenharmony_ci if( dev->adj.direct_io ) 216141cc406Sopenharmony_ci return PtDrvClose(); 217141cc406Sopenharmony_ci else 218141cc406Sopenharmony_ci return close( dev->fd ); 219141cc406Sopenharmony_ci} 220141cc406Sopenharmony_ci 221141cc406Sopenharmony_ci/** 222141cc406Sopenharmony_ci */ 223141cc406Sopenharmony_cistatic int ppDev_getCaps( Plustek_Device *dev ) 224141cc406Sopenharmony_ci{ 225141cc406Sopenharmony_ci if( dev->adj.direct_io ) 226141cc406Sopenharmony_ci return PtDrvIoctl( _PTDRV_GET_CAPABILITIES, &dev->caps ); 227141cc406Sopenharmony_ci else 228141cc406Sopenharmony_ci return ioctl( dev->fd, _PTDRV_GET_CAPABILITIES, &dev->caps ); 229141cc406Sopenharmony_ci} 230141cc406Sopenharmony_ci 231141cc406Sopenharmony_ci/** 232141cc406Sopenharmony_ci */ 233141cc406Sopenharmony_cistatic int ppDev_getLensInfo( Plustek_Device *dev, pLensInfo lens ) 234141cc406Sopenharmony_ci{ 235141cc406Sopenharmony_ci if( dev->adj.direct_io ) 236141cc406Sopenharmony_ci return PtDrvIoctl( _PTDRV_GET_LENSINFO, lens ); 237141cc406Sopenharmony_ci else 238141cc406Sopenharmony_ci return ioctl( dev->fd, _PTDRV_GET_LENSINFO, lens ); 239141cc406Sopenharmony_ci} 240141cc406Sopenharmony_ci 241141cc406Sopenharmony_ci/** 242141cc406Sopenharmony_ci */ 243141cc406Sopenharmony_cistatic int ppDev_getCropInfo( Plustek_Device *dev, pCropInfo crop ) 244141cc406Sopenharmony_ci{ 245141cc406Sopenharmony_ci if( dev->adj.direct_io ) 246141cc406Sopenharmony_ci return PtDrvIoctl( _PTDRV_GET_CROPINFO, crop ); 247141cc406Sopenharmony_ci else 248141cc406Sopenharmony_ci return ioctl( dev->fd, _PTDRV_GET_CROPINFO, crop ); 249141cc406Sopenharmony_ci} 250141cc406Sopenharmony_ci 251141cc406Sopenharmony_ci/** 252141cc406Sopenharmony_ci */ 253141cc406Sopenharmony_cistatic int ppDev_putImgInfo( Plustek_Device *dev, pImgDef img ) 254141cc406Sopenharmony_ci{ 255141cc406Sopenharmony_ci if( dev->adj.direct_io ) 256141cc406Sopenharmony_ci return PtDrvIoctl( _PTDRV_PUT_IMAGEINFO, img ); 257141cc406Sopenharmony_ci else 258141cc406Sopenharmony_ci return ioctl( dev->fd, _PTDRV_PUT_IMAGEINFO, img ); 259141cc406Sopenharmony_ci} 260141cc406Sopenharmony_ci 261141cc406Sopenharmony_ci/** 262141cc406Sopenharmony_ci */ 263141cc406Sopenharmony_cistatic int ppDev_setScanEnv( Plustek_Device *dev, pScanInfo sinfo ) 264141cc406Sopenharmony_ci{ 265141cc406Sopenharmony_ci if( dev->adj.direct_io ) 266141cc406Sopenharmony_ci return PtDrvIoctl( _PTDRV_SET_ENV, sinfo ); 267141cc406Sopenharmony_ci else 268141cc406Sopenharmony_ci return ioctl( dev->fd, _PTDRV_SET_ENV, sinfo ); 269141cc406Sopenharmony_ci} 270141cc406Sopenharmony_ci 271141cc406Sopenharmony_ci/** 272141cc406Sopenharmony_ci */ 273141cc406Sopenharmony_cistatic int ppDev_startScan( Plustek_Device *dev, pStartScan start ) 274141cc406Sopenharmony_ci{ 275141cc406Sopenharmony_ci if( dev->adj.direct_io ) 276141cc406Sopenharmony_ci return PtDrvIoctl( _PTDRV_START_SCAN, start ); 277141cc406Sopenharmony_ci else 278141cc406Sopenharmony_ci return ioctl( dev->fd, _PTDRV_START_SCAN, start ); 279141cc406Sopenharmony_ci} 280141cc406Sopenharmony_ci 281141cc406Sopenharmony_ci/** function to send a gamma table to the kernel module. As the default table 282141cc406Sopenharmony_ci * entry is 16-bit, but the maps are 8-bit, we have to copy the values... 283141cc406Sopenharmony_ci */ 284141cc406Sopenharmony_cistatic int ppDev_setMap( Plustek_Device *dev, SANE_Word *map, 285141cc406Sopenharmony_ci SANE_Word length, SANE_Word channel ) 286141cc406Sopenharmony_ci{ 287141cc406Sopenharmony_ci SANE_Byte *buf; 288141cc406Sopenharmony_ci SANE_Word i; 289141cc406Sopenharmony_ci MapDef m; 290141cc406Sopenharmony_ci 291141cc406Sopenharmony_ci m.len = length; 292141cc406Sopenharmony_ci m.map_id = channel; 293141cc406Sopenharmony_ci 294141cc406Sopenharmony_ci m.map = (void *)map; 295141cc406Sopenharmony_ci 296141cc406Sopenharmony_ci DBG(_DBG_INFO,"Setting map[%u] at 0x%08lx\n", channel, (unsigned long)map); 297141cc406Sopenharmony_ci 298141cc406Sopenharmony_ci buf = (SANE_Byte*)malloc( m.len ); 299141cc406Sopenharmony_ci 300141cc406Sopenharmony_ci if( !buf ) 301141cc406Sopenharmony_ci return _E_ALLOC; 302141cc406Sopenharmony_ci 303141cc406Sopenharmony_ci for( i = 0; i < m.len; i++ ) { 304141cc406Sopenharmony_ci buf[i] = (SANE_Byte)map[i]; 305141cc406Sopenharmony_ci 306141cc406Sopenharmony_ci if( map[i] > 0xFF ) 307141cc406Sopenharmony_ci buf[i] = 0xFF; 308141cc406Sopenharmony_ci } 309141cc406Sopenharmony_ci 310141cc406Sopenharmony_ci m.map = buf; 311141cc406Sopenharmony_ci 312141cc406Sopenharmony_ci if( dev->adj.direct_io ) 313141cc406Sopenharmony_ci PtDrvIoctl( _PTDRV_SETMAP, &m ); 314141cc406Sopenharmony_ci else 315141cc406Sopenharmony_ci ioctl( dev->fd, _PTDRV_SETMAP, &m ); 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_ci /* we ignore the return values */ 318141cc406Sopenharmony_ci free( buf ); 319141cc406Sopenharmony_ci return 0; 320141cc406Sopenharmony_ci} 321141cc406Sopenharmony_ci 322141cc406Sopenharmony_ci/** 323141cc406Sopenharmony_ci */ 324141cc406Sopenharmony_cistatic int ppDev_stopScan( Plustek_Device *dev, short *mode ) 325141cc406Sopenharmony_ci{ 326141cc406Sopenharmony_ci int retval, tmp; 327141cc406Sopenharmony_ci 328141cc406Sopenharmony_ci /* save this one... */ 329141cc406Sopenharmony_ci tmp = *mode; 330141cc406Sopenharmony_ci 331141cc406Sopenharmony_ci if( dev->adj.direct_io ) 332141cc406Sopenharmony_ci retval = PtDrvIoctl( _PTDRV_STOP_SCAN, mode ); 333141cc406Sopenharmony_ci else 334141cc406Sopenharmony_ci retval = ioctl( dev->fd, _PTDRV_STOP_SCAN, mode ); 335141cc406Sopenharmony_ci 336141cc406Sopenharmony_ci /* ... and use it here */ 337141cc406Sopenharmony_ci if( 0 == tmp ) { 338141cc406Sopenharmony_ci if( dev->adj.direct_io ) 339141cc406Sopenharmony_ci PtDrvIoctl( _PTDRV_CLOSE_DEVICE, 0 ); 340141cc406Sopenharmony_ci else 341141cc406Sopenharmony_ci ioctl( dev->fd, _PTDRV_CLOSE_DEVICE, 0); 342141cc406Sopenharmony_ci }else 343141cc406Sopenharmony_ci sleep( 1 ); 344141cc406Sopenharmony_ci 345141cc406Sopenharmony_ci return retval; 346141cc406Sopenharmony_ci} 347141cc406Sopenharmony_ci 348141cc406Sopenharmony_ci/** 349141cc406Sopenharmony_ci */ 350141cc406Sopenharmony_cistatic int ppDev_readImage( Plustek_Device *dev, 351141cc406Sopenharmony_ci SANE_Byte *buf, unsigned long data_length ) 352141cc406Sopenharmony_ci{ 353141cc406Sopenharmony_ci if( dev->adj.direct_io ) 354141cc406Sopenharmony_ci return PtDrvRead( buf, data_length ); 355141cc406Sopenharmony_ci else 356141cc406Sopenharmony_ci return read( dev->fd, buf, data_length ); 357141cc406Sopenharmony_ci} 358141cc406Sopenharmony_ci 359141cc406Sopenharmony_ci/* END PLUSTEK-PP_WRAPPER.C .................................................*/ 360