home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- From: lh@aega84.UUCP (Lothar Hirschbiegel)
- Subject: v29i078: gs45 - driver for Genius GS4500 hand scanner under SysV/386, Part01/01
- Message-ID: <1992Apr17.020205.15971@sparky.imd.sterling.com>
- X-Md4-Signature: 7a386ac88a5c2905a78313e126ec4704
- Date: Fri, 17 Apr 1992 02:02:05 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: lh@aega84.UUCP (Lothar Hirschbiegel)
- Posting-number: Volume 29, Issue 78
- Archive-name: gs45/part01
- Environment: Genius-GS4500, ISC-SVR4, MS-DOS
-
- Driver for GS4500 Hand Scanner.
-
- This is my first public release of a driver for the Genius hand scanner,
- model GS4500. I have noticed this scanner is sold as an OEM product under
- different names, so chances are high the driver will work with other brands
- of hand scanners too (though *not* real greyscale hand scanners with 64 or 256
- grey scales like the Logitech ScanMan256 and others).
- The driver supports all available resolutions from 100 up to 400 dpi.
- I have included a little test program to generate PBM output which can be
- processed by various viewers (xv, xloadimage) and filters.
-
- It works under ISC-SVR4 (and probably most other Intel based SVR4 versions,
- though not tested), and also under ISC-SVR3.
- I have included a README in the shar file.
-
- Regards
- L. Hirschbiegel / lh@aega84.uucp
-
- ==========================shar file follows=============================
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: COPYING INSTALLATION Master Node README System gs45.c
- # gs45.h gs45test.c
- # Wrapped by root@tmcsys on Tue Apr 14 23:02:20 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f COPYING -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"COPYING\"
- else
- echo shar: Extracting \"COPYING\" \(733 characters\)
- sed "s/^X//" >COPYING <<'END_OF_COPYING'
- XGenius GS4500 Scanner Driver V1.0
- XCopyright (c) 1992, Lothar F. Hirschbiegel
- XAll rights reserved.
- X
- XPermission is granted to distribute this program in exact, complete
- Xsource form, which includes this copyright notice, as long as no fee
- Xother than media and distribution cost is charged.
- X
- XThis program may not be used in whole, or in part, in any other manner
- Xwithout prior written permission from the author.
- X
- XThis program may not be distributed in modified form without prior
- Xwritten permission from the author. In other words, patches may be
- Xdistributed, but modified source may not be distributed.
- X
- XIf there are any questions, comments or suggestions, the author may be
- Xcontacted at:
- X
- X lh@aega84.uucp or
- X unido!aega84!lh
- X
- END_OF_COPYING
- if test 733 -ne `wc -c <COPYING`; then
- echo shar: \"COPYING\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f INSTALLATION -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"INSTALLATION\"
- else
- echo shar: Extracting \"INSTALLATION\" \(2365 characters\)
- sed "s/^X//" >INSTALLATION <<'END_OF_INSTALLATION'
- XInstallation
- X============
- X
- XI have not provided a Makefile, since compiling is trivial and wouldn't
- Xrequire a Makefile at all...
- X
- XPlease note that I have written and tested this driver for Interactive
- XSVR4.0.3 and Interactive SVR3 Release 2.0.2. I do *not* claim it will run
- Xon other Intel based Unix versions too, but given the similarities between
- Xdifferent versions of SVR4 (and sometimes SVR3) chances are quite high...
- X
- X1. If you are on a SVR4 system just go ahead compiling with the command
- X cc -c gs45.c
- X If you are on a SVR3 system you might have to change the line
- X gs45_paddr = kvtophys(gs45tsd); /* Line 124 in gs45.c */
- X to
- X gs45_paddr = svirtophys(gs45tsd);
- X if you run into problems after compiling and linking your new kernel.
- X I've used this driver with svirtophys under ISC SVR3r2.0.2 a while ago,
- X but I have absolutely no idea whether kvtophys is available also under
- X SVR3 (I don't have access to ISC SVR3 anymore).
- X
- X After compilation rename the resulting file gs45.o to Driver.o .
- X
- X2. Integrate the driver into the system by using
- X idinstall -a -k for SVR4 (WARNING: if you don't use the -k option
- X idinstall will clear your configuration files
- X after installation!)
- X or
- X insdriver for SVR3
- X I have prepared Master, Node and System files.
- X You will be asked about the drivers name; enter "gs45" then.
- X
- X3. That's almost all to do now. Now build a new kernel with
- X /etc/conf/bin/idbuild on SVR4 or use kconfig on SVR3.
- X
- X[ Disclaimer: you should *never* change your kernel and/or integrate
- X drivers into the kernel without making backups *before* doing so :-) ]
- X
- XAfter rebooting your system there will be a device called /dev/gscan.
- X
- XI have included a little test program "gs45test.c" which you may
- Xuse to test the successful installation of the driver. It generates
- XPBM output which can be viewed with xv or xloadimage.
- XCompile with cc -o gs45test gs45test.c , use it with "gs45test > outfile".
- XIt is also an example of how to use the driver. If in doubt, read the
- Xincluded manpage gs45.man.
- X
- XIf you have any questions, suggestions and/or complaints (hopefully not:-)
- Xyou can contact me under the email address "lh@aega84.uucp".
- X
- X[ By the way: anybody willing to write an online viewer
- Xfor X11 for the driver?? Would be nice to see your scanning progress
- Xdirectly in an X11 window... :-) ]
- END_OF_INSTALLATION
- if test 2365 -ne `wc -c <INSTALLATION`; then
- echo shar: \"INSTALLATION\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Master -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Master\"
- else
- echo shar: Extracting \"Master\" \(30 characters\)
- sed "s/^X//" >Master <<'END_OF_Master'
- Xgs45 ocri ioHc gs45 0 0 1 2 3
- END_OF_Master
- if test 30 -ne `wc -c <Master`; then
- echo shar: \"Master\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Node -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Node\"
- else
- echo shar: Extracting \"Node\" \(15 characters\)
- sed "s/^X//" >Node <<'END_OF_Node'
- Xgs45 gscan c 0
- END_OF_Node
- if test 15 -ne `wc -c <Node`; then
- echo shar: \"Node\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f README -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README\"
- else
- echo shar: Extracting \"README\" \(1207 characters\)
- sed "s/^X//" >README <<'END_OF_README'
- X
- X
- XDriver for GS4500 Hand Scanner, written by Lothar Hirschbiegel (lh@aega84.uucp)
- X
- XThis is my first public release of a driver for the Genius hand scanner,
- Xmodel GS4500. I have noticed this scanner is sold as an OEM product under
- Xdifferent names, so chances are high the driver will work with other brands
- Xof hand scanners too (though *not* real greyscale hand scanners with 64 or 256
- Xgrey scales like the Logitech ScanMan256 and others).
- XThe driver supports all available resolutions from 100 up to 400 dpi.
- XI have included a little test program to generate PBM output which can be
- Xprocessed by various viewers (xv, xloadimage) and filters.
- X
- XOne word of warning: since the Genius interface controller is not interrupt
- Xdriven in default HW mode, the driver is a real cpu hog... This is no problem
- Xunder MS-DOS, but under UNIX the slowdown is remarkably high. In fact the
- Xmachine locks up almost completely during scanning. This could be avoided,
- Xbut chances to lose lines of scanned pixels will increase dramatically.
- XI would not recommend using the scanner for large scanning sessions while 10
- Xother users are logged into your machine :-) .
- X
- XL. Hirschbiegel
- Xlh@aega84.uucp , Tue Apr 14 22:48:54 GMT 1992
- X
- END_OF_README
- if test 1207 -ne `wc -c <README`; then
- echo shar: \"README\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f System -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"System\"
- else
- echo shar: Extracting \"System\" \(27 characters\)
- sed "s/^X//" >System <<'END_OF_System'
- Xgs45 Y 1 0 0 0 272 27b 0 0
- END_OF_System
- if test 27 -ne `wc -c <System`; then
- echo shar: \"System\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f gs45.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"gs45.c\"
- else
- echo shar: Extracting \"gs45.c\" \(4838 characters\)
- sed "s/^X//" >gs45.c <<'END_OF_gs45.c'
- X
- X/*************************************************************
- X * Driver for GS4500 Scanner Controller *
- X * Copyright L. Hirschbiegel 1991 *
- X *************************************************************/
- X
- X/* This software was written by Lothar Hirschbiegel (lh@aega84.uucp) */
- X/* For a complete license see file COPYING */
- X
- X/********************************************/
- X/* Port address GROUP 1: 272, 273, 27A, 27B */
- X/* Settings for DMA channel 3 (default) */
- X/********************************************/
- X
- X#include <sys/signal.h>
- X#include <sys/types.h>
- X#include <sys/tss.h>
- X#include <sys/fs/s5dir.h>
- X#include <sys/sysmacros.h>
- X#include <sys/user.h>
- X#include <sys/errno.h>
- X#include <sys/buf.h>
- X#include <sys/ddi.h>
- X#define KERNEL
- X#include "gs45.h"
- X
- X/* Will only read from DMA port (no writing) */
- X#define DMALOAD 0x47
- X
- X/* private kernel buffer for temporary storage of data */
- Xunchar gs45tsd[256];
- X
- X#define DMA_mode 0x0b
- X#define DMA_fflop 0x0c
- X#define DMA_mask 0x0a
- X#define DMA_page 0x82
- X#define DMA_count 0x07
- X#define DMA_start 0x06
- X#define DMA_drqtc 0x08
- X#define DMA_req 0x09
- X
- X#define DMA3TC 0x08
- X
- X#define TRUE 1
- X#define FALSE 0
- X
- X#define START_SCAN 0x01
- X#define END_SCAN 0xfe
- X
- Xstruct _gs45state {
- X int is_open;
- X int is_on;
- X int ioval[4];
- X int iores[4];
- X int offs[4];
- X} gs45state = {0, /* is_open */
- X 0, /* is_on */
- X {0xf0,0xa0,0x80,0xe0}, /* ioval */
- X {0x35,0x69,0x9e,0xce}, /* iores */
- X {0xffe4,0xfff0,0xff84,0xffe4} /* DMA count full page */
- X };
- X
- Xunsigned long gs45_paddr;
- Xint gs45res_switch = -1;
- X
- X#define SCAN_ON (gs45state.ioval[gs45res_switch]|START_SCAN)
- X#define SCAN_OFF (gs45state.ioval[gs45res_switch]&END_SCAN)
- X#define SCAN_LEN (gs45state.iores[gs45res_switch])
- X
- Xgs45_start(xferlen)
- Xint xferlen;
- X{
- X short recv, rcl, rch;
- X uint page, base_l, base_h, len_l, len_h, base, plen;
- X
- X base = gs45_paddr;
- X plen = xferlen - 1;
- X
- X base_l = base & 0xff;
- X base = base >> 8;
- X base_h = base & 0xff;
- X base = base >> 8;
- X page = base & 0xff;
- X len_l = plen & 0xff;
- X plen = plen >> 8;
- X len_h = plen & 0xff;
- X
- X outb(DMA_page, page);
- X outb(DMA_mask, 0x07); /* mask channel 3 */
- X
- X outb(DMA_mode,DMALOAD);
- X outb(DMA_fflop, 0x0);
- X
- X outb(DMA_start, base_l); /* set dma base addr */
- X outb(DMA_start, base_h); /* set dma base addr */
- X
- X outb(DMA_fflop, 0x0);
- X
- X outb(DMA_count, len_l); /* set dma len counter */
- X outb(DMA_count, len_h); /* set dma len counter */
- X
- X outb(GS_CCP, 0); /* clear card receive counter */
- X recv = inb(GS_VDP, 0); /* reset card dma request */
- X
- X outb(DMA_req, 0x3); /* reset dma channel 3 */
- X outb(DMA_mask,0x3); /* clear masked channel */
- X
- X /* check for end of transfer */
- X
- X do {
- X recv = inb(DMA_drqtc);
- X } while (!(recv & DMA3TC)); /* check for channel_bit dma channel 3 */
- X}
- X
- Xgs45open(dev)
- Xint dev;
- X{
- X if(gs45state.is_open)
- X {
- X u.u_error=EBUSY;
- X return;
- X }
- X gs45state.is_open = TRUE;
- X gs45_paddr = kvtophys(gs45tsd);
- X
- X /* could be :
- X * gs45_paddr = svirtophys(gs45tsd);
- X * for SVR3.2. Test at your own risk... */
- X
- X gs45res_switch = -1; /* dpi switch is undefined */
- X}
- X
- Xgs45close(dev)
- Xint dev;
- X{
- X gs45state.is_open = FALSE;
- X if(gs45state.is_on == TRUE)
- X outb(GS_CP, SCAN_OFF);
- X gs45res_switch = -1; /* dpi switch is undefined */
- X}
- X
- Xcheck_gs45dpi()
- X{
- X int inval;
- X
- X do {
- X inval=inb(GS_SP);
- X } while (!(inval & 0x80)); /* wait until AR = 1 */
- X /* scanner turned on */
- X do {
- X inval=inb(GS_SP);
- X } while (inval & 0x80); /* wait until AR = 0 */
- X /* status port is valid */
- X inval &= 0xa4; /* mask dpi bits */
- X
- X switch(inval)
- X {
- X case 0x24: gs45res_switch = 0;
- X break;
- X case 0x20: gs45res_switch = 1;
- X break;
- X case 0x04: gs45res_switch = 2;
- X break;
- X case 0x00: gs45res_switch = 3;
- X break;
- X default: gs45res_switch = -1;
- X break;
- X }
- X}
- X
- Xgs45ioctl(dev,cmnd,arg)
- Xint dev;
- Xint cmnd;
- Xint *arg;
- X{
- X int i, cmstate;
- X
- X switch (cmnd)
- X {
- X case GET_DPI:
- X copyout(&gs45res_switch, arg, sizeof(int));
- X break;
- X case SCANNER_ON:
- X outb(GS_CP, TRUE); /* turn on scanner */
- X outb(GS_CCP, TRUE); /* clear dma count */
- X check_gs45dpi();
- X if(gs45res_switch == -1)
- X {
- X outb(GS_CP, FALSE);
- X gs45state.is_on = FALSE;
- X u.u_error = EIO;
- X return;
- X }
- X outb(GS_CP, SCAN_ON); /* reset scanner */
- X outb(GS_CCP, SCAN_ON); /* clear dma count */
- X gs45state.is_on = TRUE;
- X break;
- X case SCANNER_OFF:
- X outb(GS_CP, SCAN_OFF);
- X gs45state.is_on = FALSE;
- X break;
- X default: break;
- X }
- X return;
- X}
- X
- Xgs45read()
- X{
- X if(gs45state.is_on == FALSE)
- X {
- X u.u_error = EIO;
- X return;
- X }
- X
- X while (u.u_count >= SCAN_LEN)
- X {
- X gs45_start(SCAN_LEN);
- X
- X if (!copyout(gs45tsd,u.u_base,SCAN_LEN))
- X {
- X u.u_base += SCAN_LEN;
- X u.u_count -= SCAN_LEN;
- X }
- X else
- X {
- X u.u_error = EIO;
- X return;
- X }
- X }
- X}
- END_OF_gs45.c
- if test 4838 -ne `wc -c <gs45.c`; then
- echo shar: \"gs45.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f gs45.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"gs45.h\"
- else
- echo shar: Extracting \"gs45.h\" \(1137 characters\)
- sed "s/^X//" >gs45.h <<'END_OF_gs45.h'
- X/*************************************************************
- X * Includes for GS4500 Scanner Controller *
- X * Copyright L. Hirschbiegel 1991 *
- X *************************************************************/
- X
- X/* This software was written by Lothar Hirschbiegel (lh@aega84.uucp) */
- X/* For a complete license see file COPYING */
- X
- X/* common commands via ioctl */
- X/* special file is /dev/gscan */
- X
- X#define SCANNER_ON 0x10 /* no arg */
- X#define SCANNER_OFF 0x11 /* no arg */
- X#define GET_DPI 0x14 /* returns dpi_switch in (int *)arg */
- X /* 0 = 100 dpi ..... 3 = 400 dpi */
- X
- X#define LLEN_100 0x35 /* number of bytes per line res 100 dpi */
- X#define LLEN_200 0x69 /* number of bytes per line res 200 dpi */
- X#define LLEN_300 0x9e /* number of bytes per line res 300 dpi */
- X#define LLEN_400 0xce /* number of bytes per line res 400 dpi */
- X
- X
- X#ifdef KERNEL
- X
- X#define GS_VDP 0x272 /* video data port */
- X#define GS_SP 0x273 /* status port */
- X#define GS_CP 0x27a /* control port */
- X#define GS_CCP 0x27b /* counter clear port */
- X
- X#endif /* KERNEL */
- END_OF_gs45.h
- if test 1137 -ne `wc -c <gs45.h`; then
- echo shar: \"gs45.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f gs45test.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"gs45test.c\"
- else
- echo shar: Extracting \"gs45test.c\" \(1618 characters\)
- sed "s/^X//" >gs45test.c <<'END_OF_gs45test.c'
- X
- X/*************************************************************
- X * Test program for GS4500 Scanner Driver *
- X * Copyright L. Hirschbiegel 1991 *
- X *************************************************************/
- X
- X/* This software was written by Lothar Hirschbiegel (lh@aega84.uucp) */
- X/* For a complete license see file COPYING */
- X
- X/* USAGE: gs45test [ scanlines ] > outfile */
- X/* This test program generates PBM output files from GS4500 scanner input */
- X
- X#include <stdio.h>
- X#include "gs45.h"
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int fd, z, numbytes;
- X unsigned char c, *buf;
- X int sv, i, num, scanlines;
- X char res[8];
- X char lines[8], ibuf[8];
- X
- X if(argc == 2)
- X scanlines = atoi(*(++argv));
- X else
- X scanlines = 800; /* default */
- X
- X if ((fd = open("/dev/gscan",0)) < 0)
- X perror("");
- X
- X if((ioctl(fd,SCANNER_ON))==-1)
- X perror("");
- X
- X ioctl(fd, GET_DPI, &sv);
- X num = (sv + 1) * 100;
- X fprintf(stderr,"DPI = %d\n",num);
- X
- X switch(sv)
- X {
- X case 0: strcpy(res,"424");
- X numbytes = scanlines*LLEN_100;
- X break;
- X case 1: strcpy(res,"840");
- X numbytes = scanlines*LLEN_200;
- X break;
- X case 2: strcpy(res,"1264");
- X numbytes = scanlines*LLEN_300;
- X break;
- X case 3: strcpy(res,"1648");
- X numbytes = scanlines*LLEN_400;
- X break;
- X }
- X
- X fprintf(stderr,"SCANLINES = %d\n",scanlines);
- X sprintf(ibuf,"%d",scanlines);
- X strcpy(lines,ibuf);
- X buf = (unsigned char *)malloc(numbytes);
- X if (buf == NULL) {
- X perror("");
- X exit(1);
- X }
- X printf("P4\n%s %s\n",res, lines);
- X num = read(fd, buf, numbytes);
- X for (i=0;i<num;i++) printf("%c",(buf[i]^0xff));
- X ioctl(fd,SCANNER_OFF);
- X}
- END_OF_gs45test.c
- if test 1618 -ne `wc -c <gs45test.c`; then
- echo shar: \"gs45test.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-
- exit 0 # Just in case...
-