From 3bac9a71b6e4a424b494121a4274843b750b2fc4 Mon Sep 17 00:00:00 2001 From: Paul Traina Date: Sat, 4 May 1996 07:03:55 +0000 Subject: [PATCH] Update to version 1.1beta5d of the driver. This driver now runs under FreeBSD 2.1 and 2.2, BSD/OS 2.x, Linux, Solaris, and SCO V. --- sys/i386/isa/qcam.c | 101 ++++++++++---------------------- sys/i386/isa/qcamdefs.h | 35 ++++++++--- sys/i386/isa/qcamio.c | 125 ++++++++++++++++++++++++++++++++-------- sys/i386/isa/qcamreg.h | 4 +- 4 files changed, 158 insertions(+), 107 deletions(-) diff --git a/sys/i386/isa/qcam.c b/sys/i386/isa/qcam.c index 154c8530cc63..526b1784851c 100644 --- a/sys/i386/isa/qcam.c +++ b/sys/i386/isa/qcam.c @@ -1,12 +1,10 @@ /* - * FreeBSD Connectix QuickCam parallel-port camera video capture driver. + * Connectix QuickCam parallel-port camera video capture driver. * Copyright (c) 1996, Paul Traina. * - * This driver is based in part on the Linux QuickCam driver which is + * This driver is based in part on work * Copyright (c) 1996, Thomas Davis. * - * Additional ideas from code written by Michael Chinn. - * * QuickCam(TM) is a registered trademark of Connectix Inc. * Use this driver at your own risk, it is not warranted by * Connectix or the authors. @@ -59,6 +57,16 @@ #include #include +/* working off of nostrategy is very ugly, but we need to determine if we're + running in a kernel that has eliminated the cdevsw table (yea!) */ + +#if defined(__FreeBSD__) && defined(nostrategy) +#define STATIC_CDEVSW static +#define PRIVATE_CDEVSW +#else +#define STATIC_CDEVSW +#endif + int qcam_debug = 1; static struct qcam_softc qcam_softc[NQCAM]; @@ -87,20 +95,6 @@ static struct kern_devconf kdc_qcam_template = { }; #define UNIT(dev) minor(dev) -#define CDEV_MAJOR 73 - - -static d_open_t qcam_open; -static d_close_t qcam_close; -static d_read_t qcam_read; -static d_ioctl_t qcam_ioctl; - -static struct cdevsw qcam_cdevsw = - { qcam_open, qcam_close, qcam_read, nowrite, - qcam_ioctl, nostop, nullreset, nodevtotty, - noselect, nommap, nostrategy, "qcam", - NULL, -1 }; - static void qcam_registerdev (struct isa_device *id) @@ -177,7 +171,7 @@ qcam_attach (struct isa_device *devp) return 1; } -static int +STATIC_CDEVSW int qcam_open (dev_t dev, int flags, int fmt, struct proc *p) { struct qcam_softc *qs = &qcam_softc[UNIT(dev)]; @@ -203,7 +197,7 @@ qcam_open (dev_t dev, int flags, int fmt, struct proc *p) return 0; } -static int +STATIC_CDEVSW int qcam_close (dev_t dev, int flags, int fmt, struct proc *p) { struct qcam_softc *qs = &qcam_softc[UNIT(dev)]; @@ -219,7 +213,7 @@ qcam_close (dev_t dev, int flags, int fmt, struct proc *p) return 0; } -static int +STATIC_CDEVSW int qcam_read (dev_t dev, struct uio *uio, int ioflag) { struct qcam_softc *qs = &qcam_softc[UNIT(dev)]; @@ -243,7 +237,7 @@ qcam_read (dev_t dev, struct uio *uio, int ioflag) return 0; /* success */ } -static int +STATIC_CDEVSW int qcam_ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) { struct qcam_softc *qs = &qcam_softc[UNIT(dev)]; @@ -253,70 +247,33 @@ qcam_ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) return(EINVAL); switch (cmd) { - case QC_GET: - info->qc_version = QC_IOCTL_VERSION; - info->qc_xsize = qs->x_size; - info->qc_ysize = qs->y_size; - info->qc_xorigin = qs->x_origin; - info->qc_yorigin = qs->y_origin; - info->qc_bpp = qs->bpp; - info->qc_zoom = qs->zoom; - info->qc_exposure = qs->exposure; - info->qc_brightness = qs->brightness; - info->qc_whitebalance = qs->whitebalance; - info->qc_contrast = qs->contrast; - break; + return qcam_ioctl_get(qs, info) ? 0 : EINVAL; case QC_SET: - /* - * sanity check parameters passed in by user - * we're extra paranoid right now because the API - * is in flux - */ - if (info->qc_xsize > QC_MAX_XSIZE || - info->qc_ysize > QC_MAX_YSIZE || - info->qc_xorigin > QC_MAX_XSIZE || - info->qc_yorigin > QC_MAX_YSIZE || - (info->qc_bpp != 4 && info->qc_bpp != 6) || - info->qc_zoom > QC_ZOOM_200 || - info->qc_brightness > UCHAR_MAX || - info->qc_whitebalance > UCHAR_MAX || - info->qc_contrast > UCHAR_MAX) - return EINVAL; - - /* version check */ - if (info->qc_version != QC_IOCTL_VERSION) - return EINVAL; - - qs->x_size = info->qc_xsize; - qs->y_size = info->qc_ysize; - qs->x_origin = info->qc_xorigin; - qs->y_origin = info->qc_yorigin; - qs->bpp = info->qc_bpp; - qs->zoom = info->qc_zoom; - qs->exposure = info->qc_exposure; - qs->brightness = info->qc_brightness; - qs->whitebalance = info->qc_whitebalance; - qs->contrast = info->qc_contrast; - - /* request initialization before next scan pass */ - qs->init_req = 1; - break; + return qcam_ioctl_set(qs, info) ? 0 : EINVAL; default: - return ENOTTY; + return(ENOTTY); } return 0; } #ifdef __FreeBSD__ -#ifdef nostrategy /* new configuration system? */ - struct isa_driver qcamdriver = {qcam_probe, qcam_attach, "qcam"}; +#ifdef PRIVATE_CDEVSW /* new configuration system? */ + +#define CDEV_MAJOR 73 + +static struct cdevsw qcam_cdevsw = + { qcam_open, qcam_close, qcam_read, nowrite, + qcam_ioctl, nostop, nullreset, nodevtotty, + noselect, nommap, nostrategy, "qcam", + NULL, -1 }; + /* * Initialize the dynamic cdevsw hooks. */ diff --git a/sys/i386/isa/qcamdefs.h b/sys/i386/isa/qcamdefs.h index dcad3a9e279a..e026a62135bb 100644 --- a/sys/i386/isa/qcamdefs.h +++ b/sys/i386/isa/qcamdefs.h @@ -1,8 +1,8 @@ /* - * FreeBSD Connectix QuickCam parallel-port camera video capture driver. + * Connectix QuickCam parallel-port camera video capture driver. * Copyright (c) 1996, Paul Traina. * - * This driver is based in part on the Linux QuickCam driver which is + * This driver is based in part on work * Copyright (c) 1996, Thomas Davis. * * QuickCam(TM) is a registered trademark of Connectix Inc. @@ -42,6 +42,12 @@ extern int qcam_debug; struct qcam_softc { + +#if defined(bsdi) && defined(KERNEL) + /* must be first in structure */ + struct device sc_dev; /* kernel configuration */ +#endif /* bsdi KERNEL */ + u_char *buffer; /* frame buffer */ u_char *buffer_end; /* end of frame buffer */ u_int flags; @@ -62,14 +68,12 @@ struct qcam_softc { u_char brightness; u_char whitebalance; -#ifdef KERNEL -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && defined(KERNEL) struct kern_devconf kdc; /* kernel config database */ #ifdef DEVFS - void *devfs_token; + void *devfs_token; /* device filesystem handle */ #endif /* DEVFS */ -#endif /* __FreeBSD__ */ -#endif /* KERNEL */ +#endif /* __FreeBSD__ KERNEL */ }; /* flags in softc */ @@ -89,6 +93,8 @@ struct qcam_softc { #define write_status(P, V) outb((V), (P)+1) #define write_control(P, V) outb((V), (P)+2) +#define LONGDELAY(n) tsleep((n)/1000) + #else /* FreeBSD/NetBSD/BSDI */ #define read_data(P) inb((P)) @@ -98,6 +104,16 @@ struct qcam_softc { #define write_status(P, V) outb((P)+1, (V)) #define write_control(P, V) outb((P)+2, (V)) +#define LONGDELAY(n) DELAY(n) + +#ifndef KERNEL +#define DELAY(n) usleep(n) +#endif + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #endif #define QC_TIMEOUT_INIT 60000 /* timeout for first @@ -113,5 +129,8 @@ extern int qcam_detect __P((u_int port)); extern void qcam_reset __P((struct qcam_softc *qs)); extern int qcam_scan __P((struct qcam_softc *qs)); extern void qcam_default __P((struct qcam_softc *qs)); - +extern int qcam_ioctl_get __P((struct qcam_softc *qs, + struct qcam *info)); +extern int qcam_ioctl_set __P((struct qcam_softc *qs, + struct qcam *info)); #endif /* _QCAM_DEFS_H */ diff --git a/sys/i386/isa/qcamio.c b/sys/i386/isa/qcamio.c index a8c4fbdb2ed9..53cc4c7cc5f5 100644 --- a/sys/i386/isa/qcamio.c +++ b/sys/i386/isa/qcamio.c @@ -1,8 +1,8 @@ /* - * FreeBSD Connectix QuickCam parallel-port camera video capture driver. + * Connectix QuickCam parallel-port camera video capture driver. * Copyright (c) 1996, Paul Traina. * - * This driver is based in part on the Linux QuickCam driver which is + * This driver is based in part on work * Copyright (c) 1996, Thomas Davis. * * Additional ideas from code written by Michael Chinn and Nelson Minar. @@ -35,38 +35,52 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(bsdi) -#define CSRG /* a more specific way of saying not Linux and not SysV */ -#endif - -#ifdef CSRG -#include "qcam.h" +#ifndef NQCAM +#include "qcam.h" /* this file defines NQCAM _only_ */ #endif #if NQCAM > 0 -#ifdef CSRG +#if defined(__FreeBSD__) || defined(__NetBSD__) #include #include -#include #ifdef KERNEL #include #include -#endif /* KERNEL */ +#include #include -#endif /* CSRG */ +#else /* user mode version of driver */ +#include +#include +#include "qcam.h" +#endif /* KERNEL */ +#endif /* FreeBSD or NetBSD */ + +#ifdef bsdi +#include +#include +#include +#include "qcam.h" +#endif /* bsdi */ #ifdef LINUX -#include #include #include #include #include #include #include "qcam-linux.h" -#include "../include/qcam.h" +#include "qcam.h" #endif /* LINUX */ +#ifdef _SCO_DS +#include +#include +#include +#include "qcam-sco.h" +#include "qcam.h" +#endif + #include "qcamreg.h" #include "qcamdefs.h" @@ -135,13 +149,13 @@ static u_short *qcam_rsblow_end = &qcam_rsblow[STATBUFSIZE]; } inline static int -sendbyte (u_int port, int value, int delay) +sendbyte (u_int port, int value, int sdelay) { u_char s1, s2; write_data(port, value); - if (delay) { - DELAY(delay); + if (sdelay) { + DELAY(sdelay); write_data(port, value); } @@ -233,9 +247,9 @@ qcam_waitfor_bi (u_int port) */ #define DECODE_WORD_BI4BPP(P, W) \ - *(P)++ = 16 - (((W) >> 12) & 0x0f); \ - *(P)++ = 16 - ((((W) >> 8) & 0x08) | (((W) >> 5) & 0x07)); \ - *(P)++ = 16 - (((W) >> 1) & 0x0f); + *(P)++ = 15 - (((W) >> 12) & 0x0f); \ + *(P)++ = 15 - ((((W) >> 8) & 0x08) | (((W) >> 5) & 0x07)); \ + *(P)++ = 15 - (((W) >> 1) & 0x0f); static void qcam_bi_4bit (struct qcam_softc *qs) @@ -316,7 +330,7 @@ qcam_bi_6bit (struct qcam_softc *qs) * the next nibble to come ready to do any data conversion operations. */ #define DECODE_WORD_UNI4BPP(P, W) \ - *(P)++ = 16 - ((W) >> 4); + *(P)++ = 15 - ((W) >> 4); static void qcam_uni_4bit (struct qcam_softc *qs) @@ -503,7 +517,8 @@ qcam_scan (struct qcam_softc *qs) } void -qcam_default (struct qcam_softc *qs) { +qcam_default (struct qcam_softc *qs) +{ qs->contrast = QC_DEF_CONTRAST; qs->brightness = QC_DEF_BRIGHTNESS; qs->whitebalance = QC_DEF_WHITEBALANCE; @@ -516,6 +531,64 @@ qcam_default (struct qcam_softc *qs) { qs->exposure = QC_DEF_EXPOSURE; } +int +qcam_ioctl_get (struct qcam_softc *qs, struct qcam *info) +{ + info->qc_version = QC_IOCTL_VERSION; + info->qc_xsize = qs->x_size; + info->qc_ysize = qs->y_size; + info->qc_xorigin = qs->x_origin; + info->qc_yorigin = qs->y_origin; + info->qc_bpp = qs->bpp; + info->qc_zoom = qs->zoom; + info->qc_exposure = qs->exposure; + info->qc_brightness = qs->brightness; + info->qc_whitebalance = qs->whitebalance; + info->qc_contrast = qs->contrast; + + return 0; /* success */ +} + +int +qcam_ioctl_set (struct qcam_softc *qs, struct qcam *info) +{ + /* + * sanity check parameters passed in by user + * we're extra paranoid right now because the API + * is in flux + */ + if (info->qc_xsize > QC_MAX_XSIZE || + info->qc_ysize > QC_MAX_YSIZE || + info->qc_xorigin > QC_MAX_XSIZE || + info->qc_yorigin > QC_MAX_YSIZE || + (info->qc_bpp != 4 && info->qc_bpp != 6) || + info->qc_zoom > QC_ZOOM_200 || + info->qc_brightness > UCHAR_MAX || + info->qc_whitebalance > UCHAR_MAX || + info->qc_contrast > UCHAR_MAX) + return 1; /* failure */ + + /* version check */ + if (info->qc_version != QC_IOCTL_VERSION) + return 1; /* failure */ + + qs->x_size = info->qc_xsize; + qs->y_size = info->qc_ysize; + qs->x_origin = info->qc_xorigin; + qs->y_origin = info->qc_yorigin; + qs->bpp = info->qc_bpp; + qs->zoom = info->qc_zoom; + qs->exposure = info->qc_exposure; + qs->brightness = info->qc_brightness; + qs->whitebalance = info->qc_whitebalance; + qs->contrast = info->qc_contrast; + + /* request initialization before next scan pass */ + qs->init_req = 1; + + return 0; /* success */ +} + #ifndef QCAM_INVASIVE_SCAN /* * Attempt a non-destructive probe for the QuickCam. @@ -527,7 +600,8 @@ qcam_default (struct qcam_softc *qs) { * way is safe. */ int -qcam_detect (u_int port) { +qcam_detect (u_int port) +{ int i, transitions = 0; u_char reg, last; @@ -544,7 +618,7 @@ qcam_detect (u_int port) { transitions++; last = reg; - DELAY(100000); /* 100ms */ + LONGDELAY(100000); /* 100ms */ } return transitions >= QC_PROBECNTLOW && @@ -561,7 +635,8 @@ qcam_detect (u_int port) { * got a camera on the remote side. */ int -qcam_detect (u_int port) { +qcam_detect (u_int port) +{ write_control(port, 0x20); write_data(port, 0x75); read_data(port); diff --git a/sys/i386/isa/qcamreg.h b/sys/i386/isa/qcamreg.h index 2531a423ada5..7cfd84d35a94 100644 --- a/sys/i386/isa/qcamreg.h +++ b/sys/i386/isa/qcamreg.h @@ -1,8 +1,8 @@ /* - * FreeBSD Connectix QuickCam parallel-port camera video capture driver. + * Connectix QuickCam parallel-port camera video capture driver. * Copyright (c) 1996, Paul Traina. * - * This driver is based in part on the Linux QuickCam driver which is + * This driver is based in part on work * Copyright (c) 1996, Thomas Davis. * * QuickCam(TM) is a registered trademark of Connectix Inc.