Remove ctx driver. another scanner. This one uses COMPAT_ISA shims
which is going away soon. If someone updates this to the latest APIs and tests it, it can return.
This commit is contained in:
parent
2dc8d58f59
commit
8822b75696
sys
@ -261,7 +261,6 @@ i386/ibcs2/imgact_coff.c optional ibcs2
|
||||
i386/isa/atpic.c standard
|
||||
i386/isa/atpic_vector.s standard
|
||||
i386/isa/clock.c standard
|
||||
i386/isa/ctx.c optional ctx
|
||||
i386/isa/cy.c count cy
|
||||
i386/isa/elink.c optional ep
|
||||
i386/isa/elink.c optional ie
|
||||
|
@ -630,7 +630,6 @@ options SAFE_RNDTEST # enable rndtest support
|
||||
#
|
||||
# Miscellaneous hardware:
|
||||
#
|
||||
# ctx: Cortex-I frame grabber
|
||||
# apm: Laptop Advanced Power Management (experimental)
|
||||
# pmtimer: Timer device driver for power management events (APM or ACPI)
|
||||
# spigot: The Creative Labs Video Spigot video-acquisition board
|
||||
@ -690,10 +689,6 @@ options SAFE_RNDTEST # enable rndtest support
|
||||
# Brumby: flags 2 msize 0x4000
|
||||
# Stallion: flags 1 msize 0x10000
|
||||
|
||||
device ctx
|
||||
hint.ctx.0.at="isa"
|
||||
hint.ctx.0.port="0x230"
|
||||
hint.ctx.0.maddr="0xd0000"
|
||||
device spigot 1
|
||||
hint.spigot.0.at="isa"
|
||||
hint.spigot.0.port="0xad6"
|
||||
|
@ -1,437 +0,0 @@
|
||||
/*
|
||||
* CORTEX-I Frame Grabber driver V1.0
|
||||
*
|
||||
* Copyright (C) 1994, Paul S. LaFollette, Jr. This software may be used,
|
||||
* modified, copied, distributed, and sold, in both source and binary form
|
||||
* provided that the above copyright and these terms are retained. Under
|
||||
* no circumstances is the author responsible for the proper functioning
|
||||
* of this software, nor does the author assume any responsibility
|
||||
* for damages incurred with its use.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Device Driver for CORTEX-I Frame Grabber
|
||||
* Made by ImageNation Corporation
|
||||
* 1200 N.E. Keyues Road
|
||||
* Vancouver, WA 98684 (206) 944-9131
|
||||
* (I have no ties to this company, just thought you might want
|
||||
* to know how to get in touch with them.)
|
||||
*
|
||||
* In order to understand this device, you really need to consult the
|
||||
* manual which ImageNation provides when you buy the board. (And
|
||||
* what a pleasure it is to buy something for a PC and actually get
|
||||
* programming information along with it.) I will limit myself here to
|
||||
* a few comments which are specific to this driver. See also the file
|
||||
* ctxreg.h for definitions of registers and control bits.
|
||||
*
|
||||
* 1. Although the hardware supports low resolution (256 x 256)
|
||||
* acqusition and display, I have not implemented access to
|
||||
* these modes in this driver. There are some fairly quirky
|
||||
* aspects to the way this board works in low resolution mode,
|
||||
* and I don't want to deal with them. Maybe later.
|
||||
*
|
||||
* 2. Choosing the base address for the video memory: This is set
|
||||
* using a combination of hardware and software, using the left
|
||||
* most dip switch on the board, and the AB_SELECT bit of control
|
||||
* port 1, according to the chart below:
|
||||
*
|
||||
* Left DIP switch || DOWN | UP |
|
||||
* =================================================
|
||||
* AB_SELECT = 0 || 0xA0000 | 0xB0000 |
|
||||
* -------------------------------------------------
|
||||
* AB_SELECT = 1 || 0xD0000 | 0xE0000 |
|
||||
* ------------------------------------------------
|
||||
*
|
||||
* When the RAM_ENABLE bit of control port 1 is clear (0), the
|
||||
* video ram is disconnected from the computer bus. This makes
|
||||
* it possible, in principle, to share memory space with other
|
||||
* devices (such as VGA) which can also disconnect themselves
|
||||
* from the bus. It also means that multiple CORTEX-I boards
|
||||
* can share the same video memory space. Disconnecting from the
|
||||
* bus does not affect the video display of the video ram contents,
|
||||
* so that one needs only set the RAM_ENABLE bit when actually
|
||||
* reading or writing to memory. The cost of this is low,
|
||||
* the benefits to me are great (I need more than one board
|
||||
* in my machine, and 0xE0000 is the only address choice that
|
||||
* doesn't conflict with anything) so I adopt this strategy here.
|
||||
*
|
||||
* XXX-Note... this driver has only been tested for the
|
||||
* XXX base = 0xE0000 case!
|
||||
*
|
||||
* 3) There is a deficiency in the documentation from ImageNation, I
|
||||
* think. In order to successfully load the lookup table, it is
|
||||
* necessary to clear SEE_STORED_VIDEO in control port 0 as well as
|
||||
* setting LUT_LOAD_ENABLE in control port 1.
|
||||
*
|
||||
* 4) This driver accesses video memory through read or write operations.
|
||||
* Other functionality is provided through ioctl's, manifest
|
||||
* constants for which are defined in ioctl_ctx.h. The ioctl's
|
||||
* include:
|
||||
* CTX_LIVE Display live video
|
||||
* CTX_GRAB Grab a frame of video data
|
||||
* CTX_H_ORGANIZE Set things up so that sequential read
|
||||
* operations access horizontal lines of
|
||||
* pixels.
|
||||
* CTX_V_ORGANIZE Set things up so that sequential read
|
||||
* operations access vertical lines of
|
||||
* pixels.
|
||||
* CTX_SET_LUT Set the lookup table from an array
|
||||
* of 256 unsigned chars passed as the
|
||||
* third parameter to ioctl.
|
||||
* CTX_GET_LUT Return the current lookup table to
|
||||
* the application as an array of 256
|
||||
* unsigned chars. Again the third
|
||||
* parameter to the ioctl call.
|
||||
*
|
||||
* Thus,
|
||||
* ioctl(fi, CTX_H_ORGANIZE, 0);
|
||||
* lseek(fi, y*512, SEEK_SET);
|
||||
* read(fi, buffer, 512);
|
||||
*
|
||||
* will fill buffer with 512 pixels (unsigned chars) which represent
|
||||
* the y-th horizontal line of the image.
|
||||
* Similarly,
|
||||
* ioctl(fi, CTX_V_ORGANIZE, 0:
|
||||
* lseek(fi, x*512+y, SEEK_SET);
|
||||
* read(fi, buffer, 10);
|
||||
*
|
||||
* will read 10 a vertical line of 10 pixels starting at (x,y).
|
||||
*
|
||||
* Obviously, this sort of ugliness needs to be hidden away from
|
||||
* the casual user, with an appropriate set of higher level
|
||||
* functions.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <i386/isa/isa_device.h>
|
||||
#include <i386/isa/ctxreg.h>
|
||||
#include <machine/ioctl_ctx.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#ifndef COMPAT_OLDISA
|
||||
#error "The ctx device requires the old isa compatibility shims"
|
||||
#endif
|
||||
|
||||
static int waitvb(int port);
|
||||
|
||||
/* state flags */
|
||||
#define OPEN (0x01) /* device is open */
|
||||
|
||||
static int ctxprobe(struct isa_device *devp);
|
||||
static int ctxattach(struct isa_device *devp);
|
||||
struct isa_driver ctxdriver = {
|
||||
INTR_TYPE_MISC,
|
||||
ctxprobe,
|
||||
ctxattach,
|
||||
"ctx"
|
||||
};
|
||||
COMPAT_ISA_DRIVER(ctx, ctxdriver);
|
||||
|
||||
static d_open_t ctxopen;
|
||||
static d_close_t ctxclose;
|
||||
static d_read_t ctxread;
|
||||
static d_write_t ctxwrite;
|
||||
static d_ioctl_t ctxioctl;
|
||||
|
||||
static struct cdevsw ctx_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_flags = D_NEEDGIANT,
|
||||
.d_open = ctxopen,
|
||||
.d_close = ctxclose,
|
||||
.d_read = ctxread,
|
||||
.d_write = ctxwrite,
|
||||
.d_ioctl = ctxioctl,
|
||||
.d_name = "ctx",
|
||||
};
|
||||
|
||||
|
||||
#define LUTSIZE 256 /* buffer size for Look Up Table (LUT) */
|
||||
#define PAGESIZE 65536 /* size of one video page, 1/4 of the screen */
|
||||
|
||||
/*
|
||||
* Per unit shadow registers (because the dumb hardware is RO)
|
||||
*/
|
||||
|
||||
struct ctx_soft_registers {
|
||||
u_char *lutp;
|
||||
u_char cp0;
|
||||
u_char cp1;
|
||||
u_char flag;
|
||||
int iobase;
|
||||
caddr_t maddr;
|
||||
int msize;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
ctxprobe(struct isa_device * devp)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (inb(devp->id_iobase) == 0xff) /* 0xff only if board absent */
|
||||
status = 0;
|
||||
else {
|
||||
status = 1; /*XXX uses only one port? */
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
static int
|
||||
ctxattach(struct isa_device * devp)
|
||||
{
|
||||
struct ctx_soft_registers *sr;
|
||||
dev_t dev;
|
||||
|
||||
sr = malloc(sizeof *sr, M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
sr->cp0 = 0; /* zero out the shadow registers */
|
||||
sr->cp1 = 0; /* and the open flag. wait for */
|
||||
sr->flag = 0; /* open to malloc the LUT space */
|
||||
sr->iobase = devp->id_iobase;
|
||||
sr->maddr = devp->id_maddr;
|
||||
sr->msize = devp->id_msize;
|
||||
dev = make_dev(&ctx_cdevsw, 0, 0, 0, 0600, "ctx%d", devp->id_unit);
|
||||
dev->si_drv1 = sr;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ctxopen(dev_t dev, int flags, int fmt, struct thread *td)
|
||||
{
|
||||
struct ctx_soft_registers *sr;
|
||||
int i;
|
||||
|
||||
sr = dev->si_drv1;
|
||||
|
||||
if (sr->flag != 0) /* someone has already opened us */
|
||||
return (EBUSY);
|
||||
|
||||
/* get space for the LUT buffer */
|
||||
|
||||
sr->lutp = malloc(LUTSIZE, M_DEVBUF, M_WAITOK);
|
||||
if (sr->lutp == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
sr->flag = OPEN;
|
||||
|
||||
/*
|
||||
Set up the shadow registers. We don't actually write these
|
||||
values to the control ports until after we finish loading the
|
||||
lookup table.
|
||||
*/
|
||||
sr->cp0 |= SEE_STORED_VIDEO;
|
||||
if ((kvtop(sr->maddr) == 0xB0000) || (kvtop(sr->maddr) == 0xE0000))
|
||||
sr->cp1 |= AB_SELECT; /* map to B or E if necessary */
|
||||
/* but don't enable RAM */
|
||||
/*
|
||||
Set up the lookup table initially so that it is transparent.
|
||||
*/
|
||||
|
||||
outb(sr->iobase + ctx_cp0, (u_char) 0);
|
||||
outb(sr->iobase + ctx_cp1, (u_char) (LUT_LOAD_ENABLE | BLANK_DISPLAY));
|
||||
for (i = 0; i < LUTSIZE; i++) {
|
||||
outb(sr->iobase + ctx_lutaddr, (u_char) i);
|
||||
sr->lutp[i] = (u_char) i;
|
||||
outb(sr->iobase + ctx_lutdata, (u_char) sr->lutp[i]);
|
||||
}
|
||||
/*
|
||||
Disable LUT loading, and push the data in the shadow
|
||||
registers into the control ports.
|
||||
*/
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
return (0); /* successful open. All ready to go. */
|
||||
}
|
||||
|
||||
static int
|
||||
ctxclose(dev_t dev, int flags, int fmt, struct thread *td)
|
||||
{
|
||||
struct ctx_soft_registers *sr;
|
||||
|
||||
sr = dev->si_drv1;
|
||||
sr->flag = 0;
|
||||
free(sr->lutp, M_DEVBUF);
|
||||
sr->lutp = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ctxwrite(dev_t dev, struct uio * uio, int ioflag)
|
||||
{
|
||||
int status = 0;
|
||||
int page, count, offset;
|
||||
struct ctx_soft_registers *sr;
|
||||
|
||||
sr = dev->si_drv1;
|
||||
|
||||
if (uio->uio_offset < 0)
|
||||
return (EINVAL);
|
||||
if (uio->uio_offset >= 4 * PAGESIZE)
|
||||
page = 4; /* EOF */
|
||||
else
|
||||
page = (u_int)uio->uio_offset / PAGESIZE;
|
||||
offset = (u_int)uio->uio_offset % PAGESIZE;
|
||||
count = min(uio->uio_resid, PAGESIZE - offset);
|
||||
while ((page >= 0) && (page <= 3) && (count > 0)) {
|
||||
sr->cp0 &= ~3;
|
||||
sr->cp0 |= page;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
|
||||
/*
|
||||
Before doing the uiomove, we need to "connect" the frame buffer
|
||||
ram to the machine bus. This is done here so that we can have
|
||||
several different boards installed, all sharing the same memory
|
||||
space... each board is only "connected" to the bus when its memory
|
||||
is actually being read or written. All my instincts tell me that
|
||||
I should disable interrupts here, so I have done so.
|
||||
*/
|
||||
|
||||
disable_intr();
|
||||
sr->cp1 |= RAM_ENABLE;
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
status = uiomove(sr->maddr + offset, count, uio);
|
||||
sr->cp1 &= ~RAM_ENABLE;
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
enable_intr();
|
||||
|
||||
page = (u_int)uio->uio_offset / PAGESIZE;
|
||||
offset = (u_int)uio->uio_offset % PAGESIZE;
|
||||
count = min(uio->uio_resid, PAGESIZE - offset);
|
||||
}
|
||||
if (uio->uio_resid > 0)
|
||||
return (ENOSPC);
|
||||
else
|
||||
return (status);
|
||||
}
|
||||
|
||||
static int
|
||||
ctxread(dev_t dev, struct uio * uio, int ioflag)
|
||||
{
|
||||
int status = 0;
|
||||
int page, count, offset;
|
||||
struct ctx_soft_registers *sr;
|
||||
|
||||
sr = dev->si_drv1;
|
||||
|
||||
if (uio->uio_offset < 0)
|
||||
return (EINVAL);
|
||||
if (uio->uio_offset >= 4 * PAGESIZE)
|
||||
page = 4; /* EOF */
|
||||
else
|
||||
page = (u_int)uio->uio_offset / PAGESIZE;
|
||||
offset = (u_int)uio->uio_offset % PAGESIZE;
|
||||
count = min(uio->uio_resid, PAGESIZE - offset);
|
||||
while ((page >= 0) && (page <= 3) && (count > 0)) {
|
||||
sr->cp0 &= ~3;
|
||||
sr->cp0 |= page;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
/*
|
||||
Before doing the uiomove, we need to "connect" the frame buffer
|
||||
ram to the machine bus. This is done here so that we can have
|
||||
several different boards installed, all sharing the same memory
|
||||
space... each board is only "connected" to the bus when its memory
|
||||
is actually being read or written. All my instincts tell me that
|
||||
I should disable interrupts here, so I have done so.
|
||||
*/
|
||||
disable_intr();
|
||||
sr->cp1 |= RAM_ENABLE;
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
status = uiomove(sr->maddr + offset, count, uio);
|
||||
sr->cp1 &= ~RAM_ENABLE;
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
enable_intr();
|
||||
|
||||
page = (u_int)uio->uio_offset / PAGESIZE;
|
||||
offset = (u_int)uio->uio_offset % PAGESIZE;
|
||||
count = min(uio->uio_resid, PAGESIZE - offset);
|
||||
}
|
||||
if (uio->uio_resid > 0)
|
||||
return (ENOSPC);
|
||||
else
|
||||
return (status);
|
||||
}
|
||||
|
||||
static int
|
||||
ctxioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
|
||||
{
|
||||
int error;
|
||||
int i;
|
||||
struct ctx_soft_registers *sr;
|
||||
|
||||
error = 0;
|
||||
sr = dev->si_drv1;
|
||||
|
||||
switch (cmd) {
|
||||
case CTX_LIVE:
|
||||
sr->cp0 &= ~SEE_STORED_VIDEO;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
break;
|
||||
case CTX_GRAB:
|
||||
sr->cp0 &= ~SEE_STORED_VIDEO;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
sr->cp0 |= ACQUIRE;
|
||||
if (waitvb(sr->iobase)) /* wait for vert blank to start
|
||||
* acquire */
|
||||
error = ENODEV;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
if (waitvb(sr->iobase)) /* wait for two more to finish acquire */
|
||||
error = ENODEV;
|
||||
if (waitvb(sr->iobase))
|
||||
error = ENODEV;
|
||||
sr->cp0 &= ~ACQUIRE; /* turn off acquire and turn on
|
||||
* display */
|
||||
sr->cp0 |= SEE_STORED_VIDEO;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
break;
|
||||
case CTX_H_ORGANIZE:
|
||||
sr->cp0 &= ~PAGE_ROTATE;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
break;
|
||||
case CTX_V_ORGANIZE:
|
||||
sr->cp0 |= PAGE_ROTATE;
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0);
|
||||
break;
|
||||
case CTX_SET_LUT:
|
||||
bcopy((u_char *) data, sr->lutp, LUTSIZE);
|
||||
outb(sr->iobase + ctx_cp0, (u_char) 0);
|
||||
outb(sr->iobase + ctx_cp1, (u_char) (LUT_LOAD_ENABLE | BLANK_DISPLAY));
|
||||
for (i = 0; i < LUTSIZE; i++) {
|
||||
outb(sr->iobase + ctx_lutaddr, i);
|
||||
outb(sr->iobase + ctx_lutdata, sr->lutp[i]);
|
||||
}
|
||||
outb(sr->iobase + ctx_cp0, sr->cp0); /* restore control
|
||||
* registers */
|
||||
outb(sr->iobase + ctx_cp1, sr->cp1);
|
||||
break;
|
||||
case CTX_GET_LUT:
|
||||
bcopy(sr->lutp, (u_char *) data, LUTSIZE);
|
||||
break;
|
||||
default:
|
||||
error = ENODEV;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
waitvb(int port)
|
||||
{ /* wait for a vertical blank, */
|
||||
if (inb(port) == 0xff) /* 0xff means no board present */
|
||||
return (1);
|
||||
|
||||
while ((inb(port) & VERTICAL_BLANK) != 0) {
|
||||
}
|
||||
while ((inb(port) & VERTICAL_BLANK) == 0) {
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 1994, Paul S. LaFollette, Jr. This software may be used,
|
||||
* modified, copied, distributed, and sold, in both source and binary form
|
||||
* provided that the above copyright and these terms are retained. Under
|
||||
* no circumstances is the author responsible for the proper functioning
|
||||
* of this software, nor does the author assume any responsibility
|
||||
* for damages incurred with its use
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Register and bit definitions for CORTEX-I frame grabber
|
||||
*/
|
||||
|
||||
#ifndef _I386_ISA_CTXREG_H_
|
||||
#define _I386_ISA_CTXREG_H_
|
||||
|
||||
/* Control Ports (all are write-only) */
|
||||
|
||||
#define ctx_cp0 0 /* offset to control port 0 */
|
||||
#define ctx_cp1 1 /* offset to control port 1 */
|
||||
#define ctx_lutaddr 2 /* offset to lut address port */
|
||||
#define ctx_lutdata 3 /* offset to lut data port */
|
||||
|
||||
/* Status port (read-only but same address as control port 0) */
|
||||
|
||||
#define ctx_status 0 /* offset to status port */
|
||||
|
||||
/* Bit assignments for control port 0 */
|
||||
|
||||
#define PAGE_SELECT0 1 /* These two bits choose which 1/4 of the */
|
||||
#define PAGE_SELECT1 2 /* video memory is accessible to us. */
|
||||
#define PAGE_ROTATE 4 /* 0 => horizontal access. 1 => vertical */
|
||||
#define ACQUIRE 8 /* set to start frame grab */
|
||||
#define SEE_STORED_VIDEO 16 /* set to allow stored frame to be seen */
|
||||
#define LOW_RESOLUTION 32 /* set to enable 256 x 256 mode */
|
||||
|
||||
/* Bit assignments for control port 1 */
|
||||
|
||||
#define INTERRUPT_ENABLE 1 /* Allow interrupts (we avoid this bit) */
|
||||
#define TRIGGER_ENABLE 2 /* Enable external trigger for frame grab */
|
||||
#define LUT_LOAD_ENABLE 4 /* Allow loading of lookup table */
|
||||
#define BLANK_DISPLAY 8 /* Turn off display */
|
||||
#define AB_SELECT 16 /* Along with HW switch, choose base memory */
|
||||
#define RAM_ENABLE 32 /* Connect video RAM to computer bus */
|
||||
|
||||
/* Bit assignments for status port */
|
||||
|
||||
#define INTERRUPT_STATUS 1 /* Ignored by us */
|
||||
#define ADC_OVERFLOW 2 /* Set if any pixes from camera "too bright"*/
|
||||
#define FIELD 4 /* 0 or 1 shows which interlace field are in*/
|
||||
#define VERTICAL_BLANK 8 /* 1 if in vertical blanking interval */
|
||||
#define TRIGGERED 16 /* 1 if HW trigger contacts closed */
|
||||
#define ACQUIRING_ACK 32 /* 1 if currently grabbing a frame */
|
||||
|
||||
|
||||
#endif /* ifndef _I386_ISA_CTXREG_H_ */
|
Loading…
Reference in New Issue
Block a user