summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/qcamio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/qcamio.c')
-rw-r--r--sys/i386/isa/qcamio.c92
1 files changed, 69 insertions, 23 deletions
diff --git a/sys/i386/isa/qcamio.c b/sys/i386/isa/qcamio.c
index 62a1d3b..a8c4fbd 100644
--- a/sys/i386/isa/qcamio.c
+++ b/sys/i386/isa/qcamio.c
@@ -35,9 +35,17 @@
* 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"
+#endif
+
#if NQCAM > 0
+#ifdef CSRG
#include <sys/param.h>
#include <machine/cpufunc.h>
#include <machine/clock.h>
@@ -45,8 +53,20 @@
#include <sys/systm.h>
#include <sys/devconf.h>
#endif /* KERNEL */
-
#include <machine/qcam.h>
+#endif /* CSRG */
+
+#ifdef LINUX
+#include <sys/param.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include "qcam-linux.h"
+#include "../include/qcam.h"
+#endif /* LINUX */
+
#include "qcamreg.h"
#include "qcamdefs.h"
@@ -263,14 +283,20 @@ qcam_bi_4bit (struct qcam_softc *qs)
static void
qcam_bi_6bit (struct qcam_softc *qs)
{
- u_char *p, *end;
- u_short hi, low, dummy;
+ u_char *p;
+ u_short hi, low;
u_int port;
port = qs->iobase; /* for speed */
qcam_waitfor_bi(port);
+ /*
+ * This was interleaved before, but I cut it back to the simple
+ * mode so that it's easier for people to play with it. A quick
+ * unrolling of the loop coupled with interleaved decoding and I/O
+ * should get us a slight CPU bonus later.
+ */
for (p = qs->buffer; p < qs->buffer_end; ) {
write_control(port, QC_CTL_HIGHWORD);
READ_DATA_WORD_HIGH(port, hi, QC_TIMEOUT);
@@ -280,12 +306,6 @@ qcam_bi_6bit (struct qcam_softc *qs)
READ_DATA_WORD_LOW(port, low, QC_TIMEOUT);
DECODE_WORD_BI6BPP(p, low);
}
-
-#ifdef notdef
- /* XXX xfqcam does this, seems stupid, the read times out */
- write_control(port, QC_CTL_HIGHWORD);
- READ_DATA_WORD_HIGH(port, dummy, QC_TIMEOUT);
-#endif
}
/*
@@ -352,7 +372,8 @@ qcam_uni_6bit (struct qcam_softc *qs)
/*
* This routine has been partially interleaved... we can do a better
- * job, but for right now, keep it simple.
+ * job, but for right now, I've deliberately kept it less efficient
+ * so we can play with decoding without hurting peoples brains.
*/
for (p = qs->buffer; p < qs->buffer_end; ) {
write_control(port, QC_CTL_HIGHNIB);
@@ -495,26 +516,25 @@ qcam_default (struct qcam_softc *qs) {
qs->exposure = QC_DEF_EXPOSURE;
}
+#ifndef QCAM_INVASIVE_SCAN
+/*
+ * Attempt a non-destructive probe for the QuickCam.
+ * Current models appear to toggle the upper 4 bits of
+ * the status register at approximately 5-10 Hz.
+ *
+ * Be aware that this isn't the way that Connectix detects the
+ * camera (they send a reset and try to handshake), but this
+ * way is safe.
+ */
int
qcam_detect (u_int port) {
- int i, transitions;
+ int i, transitions = 0;
u_char reg, last;
write_control(port, 0x20);
write_control(port, 0x0b);
write_control(port, 0x0e);
- /*
- * Attempt a non-destructive probe for the QuickCam.
- * Current models appear to toggle the upper 4 bits of
- * the status register at approximately 5-10 Hz.
- *
- * Be aware that this isn't the way that Connectix detects the
- * camera (they send a reset and try to handshake), but this
- * way is safe.
- */
- transitions = 0;
-
last = reg = read_status(port);
for (i = 0; i < QC_PROBELIMIT; i++) {
@@ -527,7 +547,33 @@ qcam_detect (u_int port) {
DELAY(100000); /* 100ms */
}
- return transitions >= QC_PROBECNTLOW && transitions <= QC_PROBECNTHI;
+ return transitions >= QC_PROBECNTLOW &&
+ transitions <= QC_PROBECNTHI;
}
+#else
+/*
+ * This form of probing for the camera can cause garbage to show
+ * up on your printers if they're plugged in instead. However,
+ * some folks have a problem with the nondestructive scan when
+ * using EPP/ECP parallel ports.
+ *
+ * Try to send down a brightness command, if we succeed, we've
+ * got a camera on the remote side.
+ */
+int
+qcam_detect (u_int port) {
+ write_control(port, 0x20);
+ write_data(port, 0x75);
+ read_data(port);
+ write_control(port, 0x0b);
+ DELAY(250);
+ write_control(port, 0x0e);
+ DELAY(250);
+
+ if (sendbyte(port, QC_BRIGHTNESS, QC_DEF_EXPOSURE) != QC_BRIGHTNESS)
+ return 0; /* failure */
+ return (sendbyte(port, 1, QC_DEF_EXPOSURE) == 1);
+}
+#endif
#endif /* NQCAM */
OpenPOWER on IntegriCloud