summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files7
-rw-r--r--sys/dev/usb/files.usb7
-rw-r--r--sys/dev/usb/uvideo.c1118
-rw-r--r--sys/dev/usb/uvideo.h382
-rw-r--r--sys/dev/video.c199
-rw-r--r--sys/dev/video_if.h49
-rw-r--r--sys/dev/videovar.h29
-rw-r--r--sys/sys/conf.h10
-rw-r--r--sys/sys/videoio.h1516
9 files changed, 3314 insertions, 3 deletions
diff --git a/sys/conf/files b/sys/conf/files
index f40bef8b826..9c45d640adf 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.426 2008/03/16 19:42:57 otto Exp $
+# $OpenBSD: files,v 1.427 2008/04/09 19:49:55 robert Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -20,6 +20,7 @@ define radiobus {}
define i2cbus {}
define gpiobus {}
define onewirebus {}
+define video {}
# filesystem firmware loading attribute
define firmload
@@ -34,6 +35,9 @@ define lm700x
define tc921x
define pt2254a
+device video
+attach video at video
+
# audio and midi devices, attaches to audio hardware driver
device audio
attach audio at audio
@@ -619,6 +623,7 @@ file dev/raidframe/rf_stripelocks.c raid needs-flag
file dev/raidframe/rf_strutils.c raid needs-flag
file dev/raidframe/rf_threadstuff.c raid needs-flag
file dev/raidframe/rf_utils.c raid needs-flag
+file dev/video.c video needs-flag
file isofs/cd9660/cd9660_bmap.c cd9660
file isofs/cd9660/cd9660_lookup.c cd9660
file isofs/cd9660/cd9660_node.c cd9660
diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb
index 3345d0adb27..098a116d5dd 100644
--- a/sys/dev/usb/files.usb
+++ b/sys/dev/usb/files.usb
@@ -1,4 +1,4 @@
-# $OpenBSD: files.usb,v 1.75 2007/12/16 18:10:46 deraadt Exp $
+# $OpenBSD: files.usb,v 1.76 2008/04/09 19:49:55 robert Exp $
# $NetBSD: files.usb,v 1.16 2000/02/14 20:29:54 augustss Exp $
#
# Config file and device description for machine-independent USB code.
@@ -34,6 +34,11 @@ device uaudio: audio, auconv, mulaw
attach uaudio at uhub
file dev/usb/uaudio.c uaudio
+# Video devices
+device uvideo: video
+attach uvideo at uhub
+file dev/usb/uvideo.c uvideo
+
# MIDI devices
device umidi: midibus
attach umidi at uhub
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
new file mode 100644
index 00000000000..3f2f537f911
--- /dev/null
+++ b/sys/dev/usb/uvideo.c
@@ -0,0 +1,1118 @@
+/*
+ * Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
+ * Copyright (c) 2008 Marcus Glocker <mglocker@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/file.h>
+#include <sys/reboot.h>
+#include <sys/selinfo.h>
+#include <sys/proc.h>
+#include <sys/namei.h>
+#include <sys/vnode.h>
+#include <sys/lock.h>
+#include <sys/stat.h>
+#include <sys/device.h>
+#include <sys/poll.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdevs.h>
+#include <dev/usb/uvideo.h>
+
+#include <dev/video_if.h>
+
+#define UVIDEO_DEBUG
+
+#ifdef UVIDEO_DEBUG
+int uvideo_debug = 1;
+#define DPRINTF(l, x...) do { if ((l) <= uvideo_debug) printf(x); } while (0)
+#else
+#define DPRINTF(l, x...)
+#endif
+
+int uvideo_enable(void *);
+void uvideo_disable(void *);
+
+int uvideo_open(void *, int);
+int uvideo_close(void *);
+
+int uvideo_find_vs_if(struct uvideo_softc *,
+ struct usb_attach_arg *, usb_config_descriptor_t *);
+usbd_status uvideo_vs_alloc(struct uvideo_softc *);
+usbd_status uvideo_vs_open(struct uvideo_softc *);
+void uvideo_vs_start(struct uvideo_softc *);
+void uvideo_vs_cb(usbd_xfer_handle, usbd_private_handle,
+ usbd_status);
+int uvideo_vs_set_probe(struct uvideo_softc *, uint8_t *);
+int uvideo_vs_get_probe(struct uvideo_softc *, uint8_t *);
+int uvideo_vs_set_probe_commit(struct uvideo_softc *, uint8_t *);
+
+int uvideo_vs_decode_stream_header(struct uvideo_softc *,
+ uint8_t *, int);
+
+void uvideo_dump_desc_all(struct uvideo_softc *);
+void uvideo_dump_desc_vcheader(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_input(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_output(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_endpoint(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_interface(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_config(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_cs_endpoint(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_colorformat(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_frame_mjpeg(struct uvideo_softc *,
+ const usb_descriptor_t *);
+void uvideo_dump_desc_format_mjpeg(struct uvideo_softc *,
+ const usb_descriptor_t *);
+
+int uvideo_debug_file_open(struct uvideo_softc *);
+void uvideo_debug_file_write_sample(void *);
+
+void uvideo_hexdump(void *, int);
+
+int uvideo_match(struct device *, void *, void *);
+void uvideo_attach(struct device *, struct device *, void *);
+int uvideo_detach(struct device *, int);
+int uvideo_activate(struct device *, enum devact);
+
+int uvideo_querycap(void *, struct v4l2_capability *);
+int uvideo_s_fmt(void *, struct v4l2_format *);
+int uvideo_g_fmt(void *, struct v4l2_format *);
+int uvideo_reqbufs(void *, struct v4l2_requestbuffers *);
+
+#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
+
+const struct cfattach uvideo_ca = {
+ sizeof(struct uvideo_softc),
+ uvideo_match,
+ uvideo_attach,
+ uvideo_detach,
+ uvideo_activate,
+};
+
+struct cfdriver uvideo_cd = {
+ NULL,
+ "uvideo",
+ DV_DULL
+};
+
+usbd_status
+uvideo_usb_request(struct uvideo_softc * sc, u_int8_t type, u_int8_t request,
+ u_int16_t value, u_int16_t index, u_int16_t length, u_int8_t * data);
+
+struct video_hw_if uvideo_hw_if = {
+ uvideo_open, /* open */
+ uvideo_close, /* close */
+ uvideo_querycap, /* VIDIOC_QUERYCAP */
+ uvideo_s_fmt, /* VIDIOC_S_FMT */
+ uvideo_g_fmt, /* VIDIOC_G_FMT */
+ uvideo_reqbufs, /* VIDIOC_REQBUFS */
+ NULL, /* VIDIOC_QBUF */
+ NULL /* VIDIOC_DQBUF */
+};
+
+int
+uvideo_match(struct device * parent, void *match, void *aux)
+{
+ struct usb_attach_arg *uaa = aux;
+ usb_interface_descriptor_t *id;
+
+ if (uaa->iface == NULL)
+ return (UMATCH_NONE);
+
+ id = usbd_get_interface_descriptor(uaa->iface);
+ if (id == NULL)
+ return (UMATCH_NONE);
+
+ if (id->bInterfaceClass == UICLASS_VIDEO &&
+ id->bInterfaceSubClass == UISUBCLASS_VIDEOCONTROL)
+ return (UMATCH_VENDOR_PRODUCT_CONF_IFACE);
+
+ return (UMATCH_NONE);
+}
+
+void
+uvideo_attach(struct device * parent, struct device * self, void *aux)
+{
+ struct uvideo_softc *sc = (struct uvideo_softc *) self;
+ struct usb_attach_arg *uaa = aux;
+ usb_config_descriptor_t *cdesc;
+ usbd_status err;
+ uint8_t probe_data[34];
+ struct uvideo_sample_buffer *fb = &sc->sc_sample_buffer;
+
+ sc->sc_udev = uaa->device;
+
+ /* get the config descriptor */
+ cdesc = usbd_get_config_descriptor(sc->sc_udev);
+ if (cdesc == NULL) {
+ printf("%s: failed to get configuration descriptor\n",
+ DEVNAME(sc));
+ return;
+ }
+
+ uvideo_dump_desc_all(sc);
+
+ if (uvideo_vs_set_probe(sc, probe_data))
+ return;
+ if (uvideo_vs_get_probe(sc, probe_data))
+ return;
+ if (uvideo_vs_set_probe_commit(sc, probe_data))
+ return;
+
+ uvideo_find_vs_if(sc, uaa, cdesc);
+
+ err = uvideo_vs_alloc(sc);
+ if (err != USBD_NORMAL_COMPLETION)
+ return;
+
+ err = uvideo_vs_open(sc);
+ if (err != USBD_NORMAL_COMPLETION)
+ return;
+
+ fb->buf = malloc(32000, M_TEMP, M_NOWAIT);
+
+ uvideo_debug_file_open(sc);
+ usb_init_task(&sc->sc_task_write, uvideo_debug_file_write_sample, sc);
+
+ uvideo_vs_start(sc);
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, &sc->sc_dev);
+
+ DPRINTF(1, "uvideo_attach: doing video_attach_mi\n");
+ sc->sc_videodev = video_attach_mi(&uvideo_hw_if, sc, &sc->sc_dev);
+}
+
+int
+uvideo_detach(struct device * self, int flags)
+{
+ struct uvideo_softc *sc = (struct uvideo_softc *) self;
+ int rv = 0;
+
+ sc->sc_dying = 1;
+
+ if (sc->sc_videodev != NULL)
+ rv = config_detach(sc->sc_videodev, flags);
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, &sc->sc_dev);
+
+ return (rv);
+}
+
+int
+uvideo_activate(struct device * self, enum devact act)
+{
+ struct uvideo_softc *sc = (struct uvideo_softc *) self;
+ int rv = 0;
+
+ DPRINTF(1, "uvideo_activate: sc=%p\n", sc);
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ break;
+ case DVACT_DEACTIVATE:
+ if (sc->sc_videodev != NULL)
+ config_deactivate(sc->sc_videodev);
+ sc->sc_dying = 1;
+ break;
+ }
+ return (rv);
+}
+
+int
+uvideo_enable(void *v)
+{
+ struct uvideo_softc *sc = v;
+
+ DPRINTF(1, "%s: uvideo_enable sc=%p\n", DEVNAME(sc), sc);
+
+ if (sc->sc_dying)
+ return (EIO);
+
+ if (sc->sc_enabled)
+ return (EBUSY);
+
+
+ sc->sc_enabled = 1;
+
+ return (0);
+}
+
+void
+uvideo_disable(void *v)
+{
+ struct uvideo_softc *sc = v;
+
+ DPRINTF(1, "%s: uvideo_disable sc=%p\n", DEVNAME(sc), sc);
+
+ if (!sc->sc_enabled) {
+ printf("uvideo_disable: already disabled!\n");
+ return;
+ }
+ sc->sc_enabled = 0;
+}
+
+int
+uvideo_open(void *addr, int flags)
+{
+ struct uvideo_softc *sc = addr;
+
+ DPRINTF(1, "uvideo_open: sc=%p\n", sc);
+
+ if (sc->sc_dying)
+ return (EIO);
+
+ return (0);
+}
+
+int
+uvideo_close(void *addr)
+{
+ struct uvideo_softc *sc = addr;
+
+ DPRINTF(1, "uvideo_close: sc=%p\n", sc);
+
+ return (0);
+}
+
+int
+uvideo_find_vs_if(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
+ usb_config_descriptor_t *cdesc)
+{
+ struct uvideo_stream_if *si = &sc->sc_curr_strm;
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
+ int i, numalts;
+
+ printf("%s: nifaces=%d\n", DEVNAME(sc), uaa->nifaces);
+
+ for (i = 0; i < uaa->nifaces; i++) {
+ if (uaa->ifaces[i] == NULL)
+ continue;
+
+ id = usbd_get_interface_descriptor(uaa->ifaces[i]);
+ if (id == NULL)
+ continue;
+ printf("%s: bInterfaceNumber=%d, bAlternateSetting=%d, ",
+ DEVNAME(sc),
+ id->bInterfaceNumber, id->bAlternateSetting);
+
+ numalts = usbd_get_no_alts(cdesc, id->bInterfaceNumber);
+ printf("numalts=%d\n", numalts);
+
+ if (id->bInterfaceNumber == 1) { /* XXX baInterfaceNr */
+ si->in_ifaceh = uaa->ifaces[i];
+ si->numalts = numalts;
+ }
+
+ ed = usbd_interface2endpoint_descriptor(uaa->ifaces[i], i);
+ if (ed == NULL) {
+ printf("%s: no endpoint descriptor for iface %d\n",
+ DEVNAME(sc), i);
+ continue;
+ }
+ printf("%s: bEndpointAddress=0x%02x\n",
+ DEVNAME(sc), ed->bEndpointAddress);
+ }
+
+ for (i = 0; i < si->numalts; i++) {
+ if (usbd_set_interface(si->in_ifaceh, i)) {
+ printf("%s: could not set alt iface %d\n",
+ DEVNAME(sc), i);
+ return (1);
+ }
+
+ ed = usbd_interface2endpoint_descriptor(si->in_ifaceh, 0);
+ if (ed == NULL) {
+ printf("%s: no endpoint descriptor for VS iface\n",
+ DEVNAME(sc));
+ continue;
+ }
+ printf("%s: VS iface alt iface bEndpointAddress=0x%02x, "
+ "wMaxPacketSize=%d\n",
+ DEVNAME(sc),
+ ed->bEndpointAddress,
+ UGETW(ed->wMaxPacketSize));
+
+ si->endpoint = ed->bEndpointAddress;
+ }
+
+ return (0);
+}
+
+usbd_status
+uvideo_vs_alloc(struct uvideo_softc *sc)
+{
+ struct uvideo_stream_if *si = &sc->sc_curr_strm;
+
+ DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
+
+ si->sc = sc;
+
+ si->xfer = usbd_alloc_xfer(sc->sc_udev);
+ if (si->xfer == NULL) {
+ printf("%s: could not allocate VideoStream xfer!\n",
+ DEVNAME(sc));
+ return (USBD_NOMEM);
+ }
+
+ si->buf = usbd_alloc_buffer(si->xfer, 384 * UVIDEO_NFRAMES);
+ if (si->buf == NULL) {
+ printf("%s: could not allocate VideoStream buffer!\n",
+ DEVNAME(sc));
+ return (USBD_NOMEM);
+ }
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+usbd_status
+uvideo_vs_open(struct uvideo_softc *sc)
+{
+ struct uvideo_stream_if *si = &sc->sc_curr_strm;
+ usb_endpoint_descriptor_t *ed;
+ usbd_status err;
+
+ DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
+
+ err = usbd_set_interface(si->in_ifaceh, 2);
+ if (err != 0) {
+ printf("%s: could not set alternate interface!\n",
+ DEVNAME(sc));
+ return (err);
+ }
+
+ ed = usbd_interface2endpoint_descriptor(si->in_ifaceh, 0);
+ if (ed == NULL) {
+ printf("%s: no endpoint descriptor for VS iface\n",
+ DEVNAME(sc));
+ return (USBD_NOMEM);
+ }
+ printf("%s: open pipe for bEndpointAddress=0x%02x (0x%02x), "
+ "wMaxPacketSize=%d\n",
+ DEVNAME(sc),
+ ed->bEndpointAddress,
+ si->endpoint,
+ UGETW(ed->wMaxPacketSize));
+
+ err = usbd_open_pipe(si->in_ifaceh, si->endpoint, USBD_EXCLUSIVE_USE,
+ &si->in_pipeh);
+ if (err) {
+ printf("%s: could not open VS pipe: %s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ return (err);
+ }
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+void
+uvideo_vs_start(struct uvideo_softc *sc)
+{
+ struct uvideo_stream_if *si = &sc->sc_curr_strm;
+ int i;
+
+ DPRINTF(2, "%s: %s\n", DEVNAME(sc), __func__);
+
+ for (i = 0; i < UVIDEO_NFRAMES; i++)
+ si->size[i] = 384;
+
+ bzero(si->buf, 384 * UVIDEO_NFRAMES);
+
+ usbd_setup_isoc_xfer(
+ si->xfer,
+ si->in_pipeh,
+ si,
+ si->size,
+ UVIDEO_NFRAMES,
+ USBD_NO_COPY | USBD_SHORT_XFER_OK,
+ uvideo_vs_cb);
+
+ (void)usbd_transfer(si->xfer);
+}
+
+void
+uvideo_vs_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
+ usbd_status status)
+{
+ struct uvideo_stream_if *sc_curr_strm = priv;
+ struct uvideo_softc *sc = sc_curr_strm->sc;
+ int len, i, frame_size;
+ uint8_t *frame;
+
+ DPRINTF(2, "%s: %s\n", DEVNAME(sc), __func__);
+
+ if (status != USBD_NORMAL_COMPLETION) {
+ printf("%s: %s: %s\n", DEVNAME(sc), __func__,
+ usbd_errstr(status));
+ return;
+ }
+ usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
+
+ DPRINTF(2, "%s: *** buffer len = %d\n", DEVNAME(sc), len);
+ if (len == 0)
+ goto skip;
+
+ for (i = 0; i < UVIDEO_NFRAMES; i++) {
+ frame = sc_curr_strm->buf + (i * 384);
+ frame_size = sc_curr_strm->size[i];
+
+ if (frame_size == 0)
+ /* frame is empty */
+ continue;
+
+ uvideo_vs_decode_stream_header(sc, frame, frame_size);
+ }
+
+skip: /* setup new transfer */
+ uvideo_vs_start(sc);
+}
+
+int
+uvideo_vs_set_probe(struct uvideo_softc *sc, uint8_t *probe_data)
+{
+ usb_device_request_t req;
+ usbd_status err;
+ uint16_t tmp;
+ struct usb_video_probe_commit *pc;
+
+ req.bmRequestType = UVIDEO_SET_IF;
+ req.bRequest = SET_CUR;
+ tmp = VS_PROBE_CONTROL;
+ tmp = tmp << 8;
+ USETW(req.wValue, tmp);
+ USETW(req.wIndex, 1);
+ USETW(req.wLength, 26);
+
+ bzero(probe_data, sizeof(probe_data));
+ pc = (struct usb_video_probe_commit *)probe_data;
+ USETW(pc->bmHint, 8);
+ //USETW(pc->bmHint, 1);
+ pc->bFormatIndex = 1;
+ pc->bFrameIndex = 1;
+
+ err = usbd_do_request(sc->sc_udev, &req, probe_data);
+ if (err) {
+ printf("%s: could not send SET request: %s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ return (-1);
+ }
+
+ DPRINTF(1, "%s: SET probe control request successfully\n",
+ DEVNAME(sc));
+
+ return (0);
+}
+
+int
+uvideo_vs_get_probe(struct uvideo_softc *sc, uint8_t *probe_data)
+{
+ usb_device_request_t req;
+ usbd_status err;
+ uint16_t tmp;
+ struct usb_video_probe_commit *pc;
+
+ req.bmRequestType = UVIDEO_GET_IF;
+ req.bRequest = GET_CUR;
+ tmp = VS_PROBE_CONTROL;
+ tmp = tmp << 8;
+ USETW(req.wValue, tmp);
+ USETW(req.wIndex, 1);
+ USETW(req.wLength, 26);
+
+ bzero(probe_data, sizeof(probe_data));
+ pc = (struct usb_video_probe_commit *)probe_data;
+
+ err = usbd_do_request(sc->sc_udev, &req, probe_data);
+ if (err) {
+ printf("%s: could not send GET request: %s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ return (-1);
+ }
+
+ DPRINTF(1, "%s: GET probe control request successfully\n",
+ DEVNAME(sc));
+
+ DPRINTF(1, "bmHint=0x%02x\n", UGETW(pc->bmHint));
+ DPRINTF(1, "bFormatIndex=0x%02x\n", pc->bFormatIndex);
+ DPRINTF(1, "bFrameIndex=0x%02x\n", pc->bFrameIndex);
+ DPRINTF(1, "dwFrameInterval=%d (ns)\n", UGETDW(pc->dwFrameInterval));
+ DPRINTF(1, "wKeyFrameRate=%d\n", UGETW(pc->wKeyFrameRate));
+ DPRINTF(1, "wPFrameRate=0x%d\n", UGETW(pc->wPFrameRate));
+ DPRINTF(1, "wCompQuality=0x%d\n", UGETW(pc->wCompQuality));
+ DPRINTF(1, "wCompWindowSize=0x%04x\n", UGETW(pc->wCompWindowSize));
+ DPRINTF(1, "wDelay=%d (ms)\n", UGETW(pc->wDelay));
+ DPRINTF(1, "dwMaxVideoFrameSize=%d (bytes)\n",
+ UGETDW(pc->dwMaxVideoFrameSize));
+ DPRINTF(1, "dwMaxPayloadTransferSize=%d (bytes)\n",
+ UGETDW(pc->dwMaxPayloadTransferSize));
+
+ return (0);
+}
+
+int
+uvideo_vs_set_probe_commit(struct uvideo_softc *sc, uint8_t *probe_data)
+{
+ usb_device_request_t req;
+ usbd_status err;
+ uint16_t tmp;
+
+ req.bmRequestType = UVIDEO_SET_IF;
+ req.bRequest = SET_CUR;
+ tmp = VS_COMMIT_CONTROL;
+ tmp = tmp << 8;
+ USETW(req.wValue, tmp);
+ USETW(req.wIndex, 1);
+ USETW(req.wLength, 26);
+
+ err = usbd_do_request(sc->sc_udev, &req, probe_data);
+ if (err) {
+ printf("%s: could not send SET commit request: %s\n",
+ DEVNAME(sc), usbd_errstr(err));
+ return (-1);
+ }
+
+ DPRINTF(1, "%s: SET probe commit request successfully\n",
+ DEVNAME(sc));
+
+ return (0);
+}
+
+int
+uvideo_vs_decode_stream_header(struct uvideo_softc *sc, uint8_t *frame,
+ int frame_size)
+{
+ struct uvideo_sample_buffer *fb = &sc->sc_sample_buffer;
+ int header_len, header_flags, fragment_len;
+
+ if (frame_size < 2)
+ /* frame too small to contain a valid stream header */
+ return (-1);
+
+ header_len = frame[0];
+ header_flags = frame[1];
+
+ DPRINTF(2, "%s: header_len = %d\n", DEVNAME(sc), header_len);
+
+ if (header_len != 12)
+ /* frame header is 12 bytes long */
+ return (-1);
+ if (header_len == frame_size && !(header_flags & UVIDEO_STREAM_EOF)) {
+ /* stream header without payload and no EOF */
+ return (-1);
+ }
+
+
+ DPRINTF(2, "%s: frame_size = %d\n", DEVNAME(sc), frame_size);
+
+ if (header_flags & UVIDEO_STREAM_FID) {
+ DPRINTF(2, "%s: %s: FID ON (0x%02x)\n",
+ DEVNAME(sc), __func__,
+ header_flags & UVIDEO_STREAM_FID);
+ } else {
+ DPRINTF(2, "%s: %s: FID OFF (0x%02x)\n",
+ DEVNAME(sc), __func__,
+ header_flags & UVIDEO_STREAM_FID);
+ }
+
+ if (fb->fragment == 0) {
+ /* first fragment for a sample */
+ fb->fragment = 1;
+ fb->fid = header_flags & UVIDEO_STREAM_FID;
+ fb->offset = 0;
+ } else {
+ /* continues fragment for a sample, check consistency */
+ if (fb->fid != (header_flags & UVIDEO_STREAM_FID)) {
+ DPRINTF(1, "%s: %s: wrong FID, ignore last sample!\n",
+ DEVNAME(sc), __func__);
+ fb->fragment = 1;
+ fb->fid = header_flags & UVIDEO_STREAM_FID;
+ fb->offset = 0;
+ }
+ }
+
+ /* save sample fragment */
+ fragment_len = frame_size - header_len;
+ bcopy(frame + header_len, fb->buf + fb->offset, fragment_len);
+ fb->offset += fragment_len;
+
+ if (header_flags & UVIDEO_STREAM_EOF) {
+ /* got a full sample */
+ DPRINTF(2, "%s: %s: EOF (sample size = %d bytes)\n",
+ DEVNAME(sc), __func__, fb->offset);
+#ifdef UVIDEO_DEBUG
+ /* do the file write in process context */
+ usb_rem_task(sc->sc_udev, &sc->sc_task_write);
+ usb_add_task(sc->sc_udev, &sc->sc_task_write);
+#endif
+ fb->fragment = 0;
+ fb->fid = 0;
+// fb->offset = 0;
+ }
+
+ return (0);
+}
+
+int
+uvideo_querycap(void *v, struct v4l2_capability * caps)
+{
+ struct uvideo_softc *sc = v;
+
+ bzero(caps, sizeof(caps));
+ strlcpy(caps->driver, DEVNAME(sc),
+ sizeof(caps->driver));
+ strncpy(caps->card, "Generic USB video class device",
+ sizeof(caps->card));
+ strncpy(caps->bus_info, "usb", sizeof(caps->bus_info));
+
+ caps->version = 1;
+ caps->capabilities = V4L2_CAP_VIDEO_CAPTURE
+ | V4L2_CAP_STREAMING
+ | V4L2_CAP_READWRITE;
+
+ return (0);
+}
+
+int
+uvideo_s_fmt(void *v, struct v4l2_format * fmt)
+{
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return (EINVAL);
+
+ return (0);
+}
+
+int
+uvideo_g_fmt(void *v, struct v4l2_format * fmt)
+{
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return (EINVAL);
+
+ return (0);
+}
+
+int
+uvideo_reqbufs(void *v, struct v4l2_requestbuffers * rb)
+{
+ return (0);
+}
+
+void
+uvideo_dump_desc_all(struct uvideo_softc *sc)
+{
+ usbd_desc_iter_t iter;
+ const usb_descriptor_t *desc;
+
+ usb_desc_iter_init(sc->sc_udev, &iter);
+ desc = usb_desc_iter_next(&iter);
+ while (desc) {
+ printf("bLength=%d\n", desc->bLength);
+ printf("bDescriptorType=0x%02x", desc->bDescriptorType);
+
+ switch (desc->bDescriptorType) {
+ case UDESC_CS_INTERFACE:
+ printf(" (CS_INTERFACE)\n");
+
+ switch (desc->bDescriptorSubtype) {
+ case UDESCSUB_VC_HEADER:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (UDESCSUB_VC_HEADER)\n");
+ if (desc->bLength == 13) {
+ printf("|\n");
+ uvideo_dump_desc_vcheader(sc, desc);
+ }
+ break;
+ case UDESCSUB_VC_INPUT_TERMINAL:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (UDESCSUB_VC_INPUT_TERMINAL)\n");
+ printf("|\n");
+ uvideo_dump_desc_input(sc, desc);
+ break;
+ case UDESCSUB_VC_OUTPUT_TERMINAL:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (UDESCSUB_VC_OUTPUT)\n");
+ printf("|\n");
+ uvideo_dump_desc_output(sc, desc);
+ break;
+ case UDESCSUB_VC_SELECTOR_UNIT:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (UDESCSUB_VC_SELECTOR_UNIT)\n");
+ /* TODO */
+ break;
+ case UDESCSUB_VC_PROCESSING_UNIT:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (UDESCSUB_VC_PROCESSING_UNIT)\n");
+ /* TODO */
+ break;
+ case UDESCSUB_VC_EXTENSION_UNIT:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ if (desc->bLength == 11) {
+ printf(" (UDESCSUB_VS_FORMAT_MJPEG)\n");
+ printf("|\n");
+ uvideo_dump_desc_format_mjpeg(sc, desc);
+ } else {
+ printf(" (UDESCSUB_VC_EXTENSION_UNIT)\n");
+ /* TODO */
+ }
+ break;
+ case UDESCSUB_VS_FRAME_MJPEG:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (UDESCSUB_VS_FRAME_MJPEG)\n");
+ if (desc->bLength > 26) {
+ printf("|\n");
+ uvideo_dump_desc_frame_mjpeg(sc, desc);
+ }
+ break;
+ case UDESCSUB_VS_COLORFORMAT:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (UDESCSUB_VS_COLORFORMAT)\n");
+ printf("|\n");
+ uvideo_dump_desc_colorformat(sc, desc);
+ break;
+ }
+
+ break;
+ case UDESC_CS_ENDPOINT:
+ printf(" (UDESC_CS_ENDPOINT)\n");
+
+ switch (desc->bDescriptorSubtype) {
+ case EP_INTERRUPT:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (EP_INTERRUPT)\n");
+ printf("|\n");
+ uvideo_dump_desc_cs_endpoint(sc, desc);
+ break;
+ case EP_GENERAL:
+ printf("bDescriptorSubtype=0x%02x",
+ desc->bDescriptorSubtype);
+ printf(" (EP_GENERAL)\n");
+ printf("|\n");
+ uvideo_dump_desc_cs_endpoint(sc, desc);
+ break;
+ }
+
+ break;
+ case UDESC_CONFIG:
+ printf(" (UDESC_CONFIG)\n");
+ printf("|\n");
+ uvideo_dump_desc_config(sc, desc);
+ break;
+ case UDESC_ENDPOINT:
+ printf(" (UDESC_ENDPOINT)\n");
+ printf("|\n");
+ uvideo_dump_desc_endpoint(sc, desc);
+ break;
+ case UDESC_INTERFACE:
+ printf(" (UDESC_INTERFACE)\n");
+ printf("|\n");
+ uvideo_dump_desc_interface(sc, desc);
+ break;
+ default:
+ printf(" (unknown)\n");
+ break;
+ }
+
+ printf("\n");
+
+ desc = usb_desc_iter_next(&iter);
+ }
+
+}
+
+void
+uvideo_dump_desc_vcheader(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ struct usb_video_header_desc *d;
+
+ d = (struct usb_video_header_desc *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
+ printf("bcdUVC=0x%04x\n", UGETW(d->bcdUVC));
+ printf("wTotalLength=%d\n", UGETW(d->wTotalLength));
+ printf("dwClockFrequency=%d\n", UGETDW(d->dwClockFrequency));
+ printf("bInCollection=0x%02x\n", d->bInCollection);
+ printf("baInterfaceNr=0x%02x\n", d->baInterfaceNr);
+}
+
+void
+uvideo_dump_desc_input(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ struct usb_video_input_terminal_desc *d;
+
+ d = (struct usb_video_input_terminal_desc *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
+ printf("bTerminalID=0x%02x\n", d->bTerminalID);
+ printf("wTerminalType=0x%04x\n", UGETW(d->wTerminalType));
+ printf("bAssocTerminal=0x%02x\n", d->bAssocTerminal);
+ printf("iTerminal=0x%02x\n", d->iTerminal);
+}
+
+void
+uvideo_dump_desc_output(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ struct usb_video_output_terminal_desc *d;
+
+ d = (struct usb_video_output_terminal_desc *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
+ printf("bTerminalID=0x%02x\n", d->bTerminalID);
+ printf("bAssocTerminal=0x%02x\n", d->bAssocTerminal);
+ printf("bSourceID=0x%02x\n", d->bSourceID);
+ printf("iTerminal=0x%02x\n", d->iTerminal);
+
+}
+
+void
+uvideo_dump_desc_endpoint(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ usb_endpoint_descriptor_t *d;
+
+ d = (usb_endpoint_descriptor_t *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bEndpointAddress=0x%02x", d->bEndpointAddress);
+ if (UE_GET_DIR(d->bEndpointAddress) == UE_DIR_IN)
+ printf(" (IN)\n");
+ if (UE_GET_DIR(d->bEndpointAddress) == UE_DIR_OUT)
+ printf(" (OUT)\n");
+ printf("bmAttributes=0x%02x", d->bmAttributes);
+ if (UE_GET_XFERTYPE(d->bmAttributes) == UE_ISOCHRONOUS) {
+ printf(" (UE_ISOCHRONOUS,");
+ if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_ASYNC)
+ printf(" UE_ISO_ASYNC)\n");
+ if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_ADAPT)
+ printf(" UE_ISO_ADAPT)\n");
+ if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_SYNC)
+ printf(" UE_ISO_SYNC)\n");
+ }
+ if (UE_GET_XFERTYPE(d->bmAttributes) == UE_CONTROL)
+ printf(" (UE_CONTROL)\n");
+ if (UE_GET_XFERTYPE(d->bmAttributes) == UE_BULK)
+ printf(" (UE_BULK)\n");
+ if (UE_GET_XFERTYPE(d->bmAttributes) == UE_INTERRUPT)
+ printf(" (UE_INTERRUPT)\n");
+ printf("wMaxPacketsize=%d\n", UGETW(d->wMaxPacketSize));
+ printf("bInterval=0x%02x\n", d->bInterval);
+}
+
+void
+uvideo_dump_desc_interface(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ usb_interface_descriptor_t *d;
+
+ d = (usb_interface_descriptor_t *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bInterfaceNumber=0x%02x\n", d->bInterfaceNumber);
+ printf("bAlternateSetting=0x%02x\n", d->bAlternateSetting);
+ printf("bNumEndpoints=%d\n", d->bNumEndpoints);
+ printf("bInterfaceClass=0x%02x\n", d->bInterfaceClass);
+ printf("bInterfaceSubClass=0x%02x\n", d->bInterfaceSubClass);
+ printf("bInterfaceProtocol=0x%02x\n", d->bInterfaceProtocol);
+ printf("iInterface=0x%02x\n", d->iInterface);
+}
+
+void
+uvideo_dump_desc_config(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ usb_config_descriptor_t *d;
+
+ d = (usb_config_descriptor_t *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("wTotalLength=0x%02x\n", d->wTotalLength);
+ printf("bNumInterface=0x%02x\n", d->bNumInterface);
+ printf("bConfigurationValue=0x%02x\n", d->bConfigurationValue);
+ printf("iConfiguration=0x%02x\n", d->iConfiguration);
+ printf("bmAttributes=0x%02x\n", d->bmAttributes);
+ printf("bMaxPower=0x%02x\n", d->bMaxPower);
+}
+
+void
+uvideo_dump_desc_cs_endpoint(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ struct usb_video_vc_endpoint_desc *d;
+
+ d = (struct usb_video_vc_endpoint_desc *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
+ printf("wMaxTransferSize=%d\n", UGETW(d->wMaxTransferSize));
+}
+
+void
+uvideo_dump_desc_colorformat(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ struct usb_video_color_matching_descr *d;
+
+ d = (struct usb_video_color_matching_descr *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
+ printf("bColorPrimaries=0x%02x\n", d->bColorPrimaries);
+ printf("bTransferCharacteristics=0x%02x\n",
+ d->bTransferCharacteristics);
+ printf("bMatrixCoefficients=0x%02x\n", d->bMatrixCoefficients);
+}
+
+void
+uvideo_dump_desc_frame_mjpeg(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ struct usb_video_frame_descriptor *d;
+
+ d = (struct usb_video_frame_descriptor *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
+ printf("bFrameIndex=0x%02x\n", d->bFrameIndex);
+ printf("bmCapabilities=0x%02x\n", d->bmCapabilities);
+ printf("wWidth=0x%d\n", UGETW(d->wWidth));
+ printf("wHeight=0x%d\n", UGETW(d->wHeight));
+ printf("dwMinBitRate=0x%08x\n", UGETDW(d->dwMaxBitRate));
+ printf("dwMaxVideoFrameBufferSize=0x%08x\n",
+ UGETDW(d->dwMaxVideoFrameBufferSize));
+ printf("dwDefaultFrameInterval=0x%d\n",
+ UGETDW(d->dwDefaultFrameInterval));
+ printf("bFrameIntervalType=0x%02x\n", d->bFrameIntervalType);
+}
+
+void
+uvideo_dump_desc_format_mjpeg(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ struct usb_video_format_mjpeg_descriptor *d;
+
+ d = (struct usb_video_format_mjpeg_descriptor *)(uint8_t *)desc;
+
+ printf("bLength=%d\n", d->bLength);
+ printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
+ printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
+ printf("bFormatIndex=0x%02x\n", d->bFormatIndex);
+ printf("bNumFrameDescriptors=0x%02x\n", d->bNumFrameDescriptors);
+ printf("bmFlags=0x%02x\n", d->bmFlags);
+ printf("bDefaultFrameIndex=0x%02x\n", d->bDefaultFrameIndex);
+ printf("bAspectRatioX=0x%02x\n", d->bAspectRatioX);
+ printf("bAspectRatioY=0x%02x\n", d->bAspectRatioY);
+ printf("bmInterlaceFlags=0x%02x\n", d->bmInterlaceFlags);
+ printf("bCopyProtect=0x%02x\n", d->bCopyProtect);
+}
+
+int
+uvideo_debug_file_open(struct uvideo_softc *sc)
+{
+ struct proc *p = curproc;
+ struct nameidata nd;
+ char name[] = "/uvideo.mjpeg";
+ int error;
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
+ error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
+ if (error) {
+ return (-1);
+ }
+
+ sc->sc_vp = nd.ni_vp;
+ VOP_UNLOCK(sc->sc_vp, 0, p);
+ if (nd.ni_vp->v_type != VREG) {
+ vn_close(nd.ni_vp, FWRITE, p->p_ucred, p);
+ return (-1);
+ }
+
+ DPRINTF(1, "%s: %s: created debug file %s\n",
+ DEVNAME(sc), __func__, name);
+
+ return (0);
+}
+
+void
+uvideo_debug_file_write_sample(void *arg)
+{
+ struct uvideo_softc *sc = arg;
+ struct uvideo_sample_buffer *sb = &sc->sc_sample_buffer;
+ struct proc *p = curproc;
+ int error;
+
+ if (sc->sc_vp == NULL) {
+ printf("%s: %s: no file open!\n", DEVNAME(sc));
+ return;
+ }
+
+ error = vn_rdwr(UIO_WRITE, sc->sc_vp, sb->buf, sb->offset, (off_t)0,
+ UIO_SYSSPACE, IO_APPEND|IO_UNIT, p->p_ucred, NULL, p);
+
+ if (error)
+ DPRINTF(1, "vn_rdwr error!\n");
+}
+
+void
+uvideo_hexdump(void *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (i % 16 == 0)
+ printf("%s%5i:", i ? "\n" : "", i);
+ if (i % 4 == 0)
+ printf(" ");
+ printf("%02x", (int)*((u_char *)buf + i));
+ }
+ printf("\n");
+}
diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h
new file mode 100644
index 00000000000..74420766623
--- /dev/null
+++ b/sys/dev/usb/uvideo.h
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2007 Robert Nagy <robert@openbsd.org>
+ * Copyright (c) 2008 Marcus Glocker <mglocker@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/videoio.h>
+
+/*
+ * USB Video Class
+ */
+/* Table A-7: Video Class-Specific Endpoint Descriptor Subtypes */
+#define EP_UNDEFINED 0x00
+#define EP_GENERAL 0x01
+#define EP_ENDPOINT 0x02
+#define EP_INTERRUPT 0x03
+
+/* Table A-5: Video Class-Specific VC Interface Descriptor Subtypes */
+#define UDESCSUB_VC_DESCRIPTOR_UNDEFINED 0x00
+#define UDESCSUB_VC_HEADER 0x01
+#define UDESCSUB_VC_INPUT_TERMINAL 0x02
+#define UDESCSUB_VC_OUTPUT_TERMINAL 0x03
+#define UDESCSUB_VC_SELECTOR_UNIT 0x04
+#define UDESCSUB_VC_PROCESSING_UNIT 0x05
+#define UDESCSUB_VC_EXTENSION_UNIT 0x06
+
+/* Table A-6: Video Class-Specific VS Interface Descriptor Subtypes */
+#define UDESCSUB_VS_UNDEFINED 0x00
+#define UDESCSUB_VS_INPUT_HEADER 0x01
+#define UDESCSUB_VS_OUTPUT_HEADER 0x02
+#define UDESCSUB_VS_STILL_IMAGE_FRAME 0x03
+#define UDESCSUB_VS_FORMAT_UNCOMPRESSED 0x04
+#define UDESCSUB_VS_FRAME_UNCOMPRESSED 0x05
+#define UDESCSUB_VS_FORMAT_MJPEG 0x06
+#define UDESCSUB_VS_FRAME_MJPEG 0x07
+#define UDESCSUB_VS_FORMAT_MPEG2TS 0x0a
+#define UDESCSUB_VS_FORMAT_DV 0x0c
+#define UDESCSUB_VS_COLORFORMAT 0x0d
+#define UDESCSUB_VS_FORMAT_FRAME_BASED 0x10
+#define UDESCSUB_VS_FRAME_FRAME_BASED 0x11
+#define UDESCSUB_VS_FORMAT_STREAM_BASED 0x12
+
+/* Table A-8: Video Class-Specific Request Codes */
+#define RC_UNDEFINED 0x00
+#define SET_CUR 0x01
+#define GET_CUR 0x81
+#define GET_MIN 0x82
+#define GET_MAX 0x83
+#define GET_RES 0x84
+#define GET_LEN 0x85
+#define GET_INFO 0x86
+#define GET_DEF 0x87
+
+/* Table A-9: Video Control Interface Control Selectors */
+#define VC_CONTROL_UNDEFINED 0x00
+#define VC_VIDEO_POWER_MODE_CONTROL 0x01
+#define VC_REQUEST_ERROR_CODE_CONTROL 0x02
+
+/* Table A-11: Selector Unit Control Selectors */
+#define SU_CONTROL_UNDEFINED 0x00
+#define SU_INPUT_SELECT_CONTROL 0x01
+
+/* Table A-12: Camera Terminal Control Selectors */
+#define CT_CONTROL_UNDEFINED 0x00
+#define CT_SCANNING_MODE_CONTROL 0x01
+#define CT_AE_MODE_CONTROL 0x02
+#define CT_AE_PRIORITY_CONTROL 0x03
+#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
+#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
+#define CT_FOCUS_ABSOLUTE_CONTROL 0x06
+#define CT_FOCUS_RELATIVE_CONTROL 0x07
+#define CT_FOCUS_AUTO_CONTROL 0x08
+#define CT_IRIS_ABSOLUTE_CONTROL 0x09
+#define CT_IRIS_RELATIVE_CONTROL 0x0a
+#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b
+#define CT_ZOOM_RELATIVE_CONTROL 0x0c
+#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d
+#define CT_PANTILT_RELATIVE_CONTROL 0x0e
+#define CT_ROLL_ABSOLUTE_CONTROL 0x0f
+#define CT_ROLL_RELATIVE_CONTROL 0x10
+#define CT_PRIVACY_CONTROL 0x11
+
+/* Table A-13: Processing Unit Control Selectors */
+#define PU_CONTROL_UNDEFINED 0x00
+#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01
+#define PU_BRIGHTNESS_CONTROL 0x02
+#define PU_CONTRAST_CONTROL 0x03
+#define PU_GAIN_CONTROL 0x04
+#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05
+#define PU_HUE_CONTROL 0x06
+#define PU_SATURATION_CONTROL 0x07
+#define PU_SHARPNESS_CONTROL 0x08
+#define PU_GAMMA_CONTROL 0x09
+#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a
+#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b
+#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c
+#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d
+#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e
+#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f
+#define PU_HUE_AUTO_CONTROL 0x10
+#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11
+#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12
+
+/* Table A-15: VideoStreaming Interface Control Selectors */
+#define VS_CONTROL_UNDEFINED 0x00
+#define VS_PROBE_CONTROL 0x01
+#define VS_COMMIT_CONTROL 0x02
+#define VS_STILL_PROBE_CONTROL 0x03
+#define VS_STILL_COMMIT_CONTROL 0x04
+#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05
+#define VS_STREAM_ERROR_CODE_CONTROL 0x06
+#define VS_GENERATE_KEY_FRAME_CONTROL 0x07
+#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08
+#define VS_SYNC_DELAY_CONTROL 0x09
+
+/* probe commit bmRequests */
+#define UVIDEO_SET_IF 0x21
+#define UVIDEO_GET_IF 0xa1
+#define UVIDEO_SET_EP 0x22
+#define UVIDEO_GET_EP 0xa2
+
+/* Table B-1: USB Terminal Types */
+#define TT_VENDOR_SPECIFIC 0x0100
+#define TT_STREAMING 0x0101
+
+/* Table B-2: Input Terminal Types */
+#define ITT_VENDOR_SPECIFIC 0x0200
+#define ITT_CAMERA 0x0201
+#define ITT_MEDIA_TRANSPORT_INPUT 0x0202
+
+/* Table B-3: Output Terminal Types */
+#define OTT_VENDOR_SPECIFIC 0x0300
+#define OTT_DISPLAY 0x0301
+#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302
+
+/* Table B-4: External Terminal Types */
+#define EXTERNAL_VENDOR_SPECIFIC 0x0400
+#define COMPOSITE_CONNECTOR 0x0401
+#define SVIDEO_CONNECTOR 0x0402
+#define COMPONENT_CONNECTOR 0x0403
+
+/* Table 3-3: VC Interface Header Descriptor */
+struct usb_video_header_descriptor {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uWord bcdUVC;
+ uWord wTotalLength;
+ uDWord dwClockFrequency; /* XXX deprecated */
+ uByte bInCollection;
+};
+
+struct usb_video_control {
+ struct usb_video_header_descriptor *descr;
+ uByte *baInterfaceNr;
+};
+
+struct usb_video_header_desc {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uWord bcdUVC;
+ uWord wTotalLength;
+ uDWord dwClockFrequency; /* XXX deprecated */
+ uByte bInCollection;
+ uByte baInterfaceNr;
+};
+
+/* Table 3-4: Input Terminal Descriptor */
+struct usb_video_input_terminal_desc {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uByte bTerminalID;
+ uWord wTerminalType;
+ uByte bAssocTerminal;
+ uByte iTerminal;
+};
+
+/* Table 3-5: Output Terminal Descriptor */
+struct usb_video_output_terminal_desc {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uByte bTerminalID;
+ uWord wTerminalType;
+ uByte bAssocTerminal;
+ uByte bSourceID;
+ uByte iTerminal;
+};
+
+/* Table 3-6: Camera Terminal Descriptor */
+struct usb_video_camera_terminal_desc {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uByte bTerminalID;
+ uWord wTerminalType;
+ uByte bAssocTerminal;
+ uByte iTerminal;
+ uWord wObjectiveFocalLengthMin;
+ uWord wObjectiveFocalLengthMax;
+ uWord wOcularFocalLength;
+ uByte bControlSize;
+ uByte *bmControls; /* XXX */
+};
+
+/* Table 3-11: VC Endpoint Descriptor */
+struct usb_video_vc_endpoint_desc {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uWord wMaxTransferSize;
+};
+
+/* Table 3-18: Color Matching Descriptor */
+struct usb_video_color_matching_descr {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uByte bColorPrimaries;
+ uByte bTransferCharacteristics;
+ uByte bMatrixCoefficients;
+} __packed;
+
+/* Table 4-47: Video Probe and Commit Controls */
+struct usb_video_probe_commit {
+ uByte bmHint[2];
+ uByte bFormatIndex;
+ uByte bFrameIndex;
+ uByte dwFrameInterval[4];
+ uByte wKeyFrameRate[2];
+ uByte wPFrameRate[2];
+ uByte wCompQuality[2];
+ uByte wCompWindowSize[2];
+ uByte wDelay[2];
+ uByte dwMaxVideoFrameSize[4];
+ uByte dwMaxPayloadTransferSize[4];
+ uByte wClockFrequency[4];
+ uByte bmFramingInfo;
+ uByte bPreferedVersion;
+ uByte bMinVersion;
+ uByte bMaxVersion;
+} __packed;
+
+/*
+ * USB Video Payload Uncompressed
+ */
+/* Table 2-1: Compression Formats */
+#define UVIDEO_FORMAT_GUID_YUY2 { \
+ 0x59, 0x55, 0x59, 0x32, 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+
+#define UVIDEO_FORMAT_GUID_NV12 { \
+ 0x4e, 0x56, 0x31, 0x32, 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
+
+/*
+ * USB Video Payload MJPEG
+ */
+/* Table 2-1: Stream Header Format for the Motion-JPEG */
+#define UVIDEO_STREAM_FID (1 << 0)
+#define UVIDEO_STREAM_EOF (1 << 1)
+#define UVIDEO_STREAM_PTS (1 << 2)
+#define UVIDEO_STREAM_SCR (1 << 3)
+#define UVIDEO_STREAM_RES (1 << 4)
+#define UVIDEO_STREAM_STI (1 << 5)
+#define UVIDEO_STREAM_ERR (1 << 6)
+#define UVIDEO_STREAM_EOH (1 << 7)
+
+/* Table 3-1: Motion-JPEG Video Format Descriptor */
+struct usb_video_format_mjpeg_descriptor {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uByte bFormatIndex;
+ uByte bNumFrameDescriptors;
+ uByte bmFlags;
+ uByte bDefaultFrameIndex;
+ uByte bAspectRatioX;
+ uByte bAspectRatioY;
+ uByte bmInterlaceFlags;
+ uByte bCopyProtect;
+} __packed;
+
+/* Table 3-2: Motion-JPEG Video Frame Descriptor */
+struct usb_video_frame_descriptor {
+ uByte bLength;
+ uByte bDescriptorType;
+ uByte bDescriptorSubtype;
+ uByte bFrameIndex;
+ uByte bmCapabilities;
+ uWord wWidth;
+ uWord wHeight;
+ uDWord dwMinBitRate;
+ uDWord dwMaxBitRate;
+ uDWord dwMaxVideoFrameBufferSize;
+ uWord dwDefaultFrameInterval;
+ uByte bFrameIntervalType;
+} __packed;
+
+/*
+ * Driver specific private definitions.
+ */
+#define UVIDEO_NFRAMES 10 /* XXX calculate right value */
+
+struct uvideo_stream_if {
+ struct uvideo_softc *sc;
+ usbd_xfer_handle xfer;
+ void *buf;
+ int busy;
+ int numalts;
+ usbd_interface_handle in_ifaceh;
+ usbd_pipe_handle in_pipeh;
+ int endpoint;
+ u_int16_t size[UVIDEO_NFRAMES];
+
+ u_int8_t fmtgrp_cnt;
+
+ usbd_interface_handle ifaceh;
+ usbd_interface_handle *if_descr;
+ int curr_alt;
+ u_int32_t max_isoc_payload;
+
+ char start_polling;
+ char fid;
+};
+
+struct uvideo_sample_buffer {
+ int fragment;
+ uint8_t fid;
+ int offset;
+ uint8_t *buf;
+};
+
+struct uvideo_softc {
+ struct device sc_dev;
+ usbd_device_handle sc_udev;
+ usbd_interface_handle sc_iface;
+ int sc_iface_number;
+ int sc_product;
+ int sc_vendor;
+
+ int sc_intr_number;
+ usbd_pipe_handle sc_intr_pipe;
+ u_char *sc_ibuf;
+ int sc_isize;
+ int sc_vc_iface;
+
+ struct device *sc_videodev;
+
+ struct vs_info *sc_alts;
+ int sc_nalts;
+ int sc_nullalt;
+ int sc_video_rev;
+ int sc_enabled;
+ int sc_dying;
+ int sc_mode;
+
+ u_int16_t uvc_version;
+ u_int32_t clock_frequency;
+ u_int32_t quirks;
+
+ struct uvideo_sample_buffer sc_sample_buffer;
+
+ struct vnode *sc_vp;
+ struct usb_task sc_task_write;
+
+ struct usb_video_control *sc_vc_header;
+ struct uvideo_stream_if sc_curr_strm;
+};
diff --git a/sys/dev/video.c b/sys/dev/video.c
new file mode 100644
index 00000000000..75a19eaa5f8
--- /dev/null
+++ b/sys/dev/video.c
@@ -0,0 +1,199 @@
+/* $OpenBSD: video.c,v 1.1 2008/04/09 19:49:55 robert Exp $ */
+/*
+ * Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <sys/device.h>
+#include <sys/vnode.h>
+#include <sys/conf.h>
+#include <sys/videoio.h>
+
+#include <dev/video_if.h>
+#include <dev/videovar.h>
+
+#define DPRINTF(x) do { printf x; } while (0)
+
+int videoprobe(struct device *, void *, void *);
+void videoattach(struct device *, struct device *, void *);
+int videodetach(struct device *, int);
+int videoactivate(struct device *, enum devact);
+int videoprint(void *, const char *);
+
+struct cfattach video_ca = {
+ sizeof(struct video_softc), videoprobe, videoattach,
+ videodetach, videoactivate
+};
+
+struct cfdriver video_cd = {
+ NULL, "video", DV_DULL
+};
+
+int
+videoprobe(struct device *parent, void *match, void *aux)
+{
+ return (1);
+}
+
+void
+videoattach(struct device *parent, struct device *self, void *aux)
+{
+ struct video_softc *sc = (void *) self;
+ struct video_attach_args *sa = aux;
+
+ printf("\n");
+ sc->hw_if = sa->hwif;
+ sc->hw_hdl = sa->hdl;
+ sc->sc_dev = parent;
+}
+
+int
+videoopen(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ int unit;
+ struct video_softc *sc;
+
+ unit = VIDEOUNIT(dev);
+ if (unit >= video_cd.cd_ndevs ||
+ (sc = video_cd.cd_devs[unit]) == NULL ||
+ sc->hw_if == NULL)
+ return (ENXIO);
+
+ if (sc->hw_if->open != NULL)
+ return (sc->hw_if->open(sc->hw_hdl, flags));
+ else
+ return (0);
+}
+
+int
+videoclose(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ struct video_softc *sc;
+
+ sc = video_cd.cd_devs[VIDEOUNIT(dev)];
+
+ if (sc->hw_if->close != NULL)
+ return (sc->hw_if->close(sc->hw_hdl));
+ else
+ return (0);
+}
+
+int
+videoioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
+{
+ struct video_softc *sc;
+ int unit, error;
+
+ unit = VIDEOUNIT(dev);
+ if (unit >= video_cd.cd_ndevs ||
+ (sc = video_cd.cd_devs[unit]) == NULL || sc->hw_if == NULL)
+ return (ENXIO);
+
+ DPRINTF(("video_ioctl(%d, '%c', %d)\n",
+ IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd & 0xff));
+
+ error = EOPNOTSUPP;
+ switch (cmd) {
+ case VIDIOC_QUERYCAP:
+ if (sc->hw_if->querycap)
+ error = (sc->hw_if->querycap)(sc->hw_hdl,
+ (struct v4l2_capability *)data);
+ break;
+ case VIDIOC_S_FMT:
+ if (!(flags & FWRITE))
+ return (EACCES);
+ if (sc->hw_if->s_fmt)
+ error = (sc->hw_if->s_fmt)(sc->hw_hdl,
+ (struct v4l2_format *)data);
+ break;
+ case VIDIOC_G_FMT:
+ if (sc->hw_if->g_fmt)
+ error = (sc->hw_if->g_fmt)(sc->hw_hdl,
+ (struct v4l2_format *)data);
+ break;
+ case VIDIOC_REQBUFS:
+ if (sc->hw_if->reqbufs)
+ error = (sc->hw_if->reqbufs)(sc->hw_hdl,
+ (struct v4l2_requestbuffers *)data);
+ break;
+ case VIDIOC_QUERYBUF:
+ case VIDIOC_QBUF:
+ default:
+ error = (ENOTTY);
+ }
+
+ return (error);
+}
+
+/*
+ * Called from hardware driver. This is where the MI video driver gets
+ * probed/attached to the hardware driver
+ */
+struct device *
+video_attach_mi(struct video_hw_if *rhwp, void *hdlp, struct device *dev)
+{
+ struct video_attach_args arg;
+
+ arg.hwif = rhwp;
+ arg.hdl = hdlp;
+ return (config_found(dev, &arg, videoprint));
+}
+
+int
+videoprint(void *aux, const char *pnp)
+{
+ if (pnp != NULL)
+ printf("video at %s", pnp);
+ return (UNCONF);
+}
+
+int
+videodetach(struct device *self, int flags)
+{
+ /*struct video_softc *sc = (struct video_softc *)self;*/
+ int maj, mn;
+
+ /* locate the major number */
+ for (maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == videoopen)
+ break;
+
+ /* Nuke the vnodes for any open instances (calls close). */
+ mn = self->dv_unit;
+ vdevgone(maj, mn, mn, VCHR);
+
+ return (0);
+}
+
+int
+videoactivate(struct device *self, enum devact act)
+{
+ struct video_softc *sc = (struct video_softc *)self;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ break;
+
+ case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
+ break;
+ }
+ return (0);
+}
diff --git a/sys/dev/video_if.h b/sys/dev/video_if.h
new file mode 100644
index 00000000000..66360fe8614
--- /dev/null
+++ b/sys/dev/video_if.h
@@ -0,0 +1,49 @@
+/* $OpenBSD: video_if.h,v 1.1 2008/04/09 19:49:55 robert Exp $ */
+/*
+ * Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SYS_DEV_VIDEO_IF_H
+#define _SYS_DEV_VIDEO_IF_H
+
+/*
+ * Generic interface to hardware driver
+ */
+
+#define VIDEOUNIT(x) (minor(x))
+
+struct video_hw_if {
+ /* open hardware */
+ int (*open)(void *, int);
+
+ /* close hardware */
+ int (*close)(void *);
+
+ int (*querycap)(void *, struct v4l2_capability *);
+ int (*s_fmt)(void *, struct v4l2_format *);
+ int (*g_fmt)(void *, struct v4l2_format *);
+ int (*reqbufs)(void *, struct v4l2_requestbuffers *);
+ int (*qbuf)(void *, struct v4l2_buffer *);
+ int (*dqbuf)(void *, struct v4l2_buffer *);
+};
+
+struct video_attach_args {
+ void *hwif;
+ void *hdl;
+};
+
+struct device *video_attach_mi(struct video_hw_if *, void *, struct device *);
+
+#endif /* _SYS_DEV_VIDEO_IF_H */
diff --git a/sys/dev/videovar.h b/sys/dev/videovar.h
new file mode 100644
index 00000000000..3b6319cfd28
--- /dev/null
+++ b/sys/dev/videovar.h
@@ -0,0 +1,29 @@
+/* $OpenBSD: videovar.h,v 1.1 2008/04/09 19:49:55 robert Exp $ */
+/*
+ * Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SYS_DEV_VIDEOVAR_H
+#define _SYS_DEV_VIDEOVAR_H
+
+struct video_softc {
+ struct device dev;
+ void *hw_hdl; /* hardware driver handle */
+ struct device *sc_dev; /* hardware device struct */
+ struct video_hw_if *hw_if; /* hardware interface */
+ char sc_dying; /* device detached */
+};
+
+#endif /* _SYS_DEV_VIDEOVAR_H */
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 60e32073ea1..8fe773508a3 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.86 2008/04/08 14:31:54 claudio Exp $ */
+/* $OpenBSD: conf.h,v 1.87 2008/04/09 19:49:55 robert Exp $ */
/* $NetBSD: conf.h,v 1.33 1996/05/03 20:03:32 christos Exp $ */
/*-
@@ -450,6 +450,13 @@ void randomattach(void);
(dev_type_stop((*))) enodev, 0, (dev_type_poll((*))) enodev, \
(dev_type_mmap((*))) enodev }
+/* open, close, ioctl */
+#define cdev_video_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) enodev, 0, (dev_type_poll((*))) enodev, \
+ (dev_type_mmap((*))) enodev }
+
/* open, close, write, ioctl */
#define cdev_spkr_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
@@ -587,6 +594,7 @@ cdev_decl(audio);
cdev_decl(midi);
cdev_decl(sequencer);
cdev_decl(radio);
+cdev_decl(video);
cdev_decl(cn);
bdev_decl(sw);
diff --git a/sys/sys/videoio.h b/sys/sys/videoio.h
new file mode 100644
index 00000000000..be9c9c0bfc4
--- /dev/null
+++ b/sys/sys/videoio.h
@@ -0,0 +1,1516 @@
+/* $OpenBSD: videoio.h,v 1.1 2008/04/09 19:49:55 robert Exp $ */
+/*
+ * Video for Linux Two header file
+ *
+ * Copyright (C) 1999-2007 the contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Alternatively you can redistribute this file under the terms of the
+ * BSD license as stated below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. The names of its contributors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Header file for v4l or V4L2 drivers and applications
+ * with public API.
+ * All kernel-specific stuff were moved to media/v4l2-dev.h, so
+ * no #if __KERNEL tests are allowed here
+ *
+ * See http://linuxtv.org for more info
+ *
+ * Author: Bill Dirks <bill@thedirks.org>
+ * Justin Schoeman
+ * Hans Verkuil <hverkuil@xs4all.nl>
+ * et al.
+ */
+
+#ifndef _SYS_VIDEOIO_H_
+#define _SYS_VIDEOIO_H_
+#include <sys/time.h>
+#include <sys/types.h>
+
+#ifndef __user
+#define __user
+#endif
+
+#ifndef __u8
+typedef u_int8_t __u8;
+#endif
+#ifndef __u16
+typedef u_int16_t __u16;
+#endif
+#ifndef __u32
+typedef u_int32_t __u32;
+#endif
+#ifndef __u64
+typedef u_int64_t __u64;
+#endif
+#ifndef __s32
+typedef int32_t __s32;
+#endif
+#ifndef __s64
+typedef int64_t __s64;
+#endif
+
+
+/*
+ * Common stuff for both V4L1 and V4L2
+ */
+#define VIDEO_MAX_FRAME 32
+
+#define VID_TYPE_CAPTURE 1 /* Can capture */
+#define VID_TYPE_TUNER 2 /* Can tune */
+#define VID_TYPE_TELETEXT 4 /* Does teletext */
+#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
+#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
+#define VID_TYPE_CLIPPING 32 /* Can clip */
+#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
+#define VID_TYPE_SCALES 128 /* Scalable */
+#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
+#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
+#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
+#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
+#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
+#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
+
+/*
+ * M I S C E L L A N E O U S
+ */
+
+/* Four-character-code (FOURCC) */
+#define v4l2_fourcc(a,b,c,d)\
+ (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+/*
+ * E N U M S
+ */
+enum v4l2_field {
+ V4L2_FIELD_ANY = 0, /* driver can choose from none, top, bottom,
+ * interlaced depending on whatever it thinks
+ * is approximate ... */
+ V4L2_FIELD_NONE = 1, /* this device has no fields ... */
+ V4L2_FIELD_TOP = 2, /* top field only */
+ V4L2_FIELD_BOTTOM = 3, /* bottom field only */
+ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
+ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one buffer,
+ * top-bottom order */
+ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
+ V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into
+ * separate buffers */
+ V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
+ * first and the top field is
+ * transmitted first */
+ V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
+ * first and the bottom field is
+ * transmitted first */
+};
+#define V4L2_FIELD_HAS_TOP(field) \
+ ((field) == V4L2_FIELD_TOP ||\
+ (field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_INTERLACED_TB ||\
+ (field) == V4L2_FIELD_INTERLACED_BT ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTTOM(field) \
+ ((field) == V4L2_FIELD_BOTTOM ||\
+ (field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_INTERLACED_TB ||\
+ (field) == V4L2_FIELD_INTERLACED_BT ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTH(field) \
+ ((field) == V4L2_FIELD_INTERLACED ||\
+ (field) == V4L2_FIELD_INTERLACED_TB ||\
+ (field) == V4L2_FIELD_INTERLACED_BT ||\
+ (field) == V4L2_FIELD_SEQ_TB ||\
+ (field) == V4L2_FIELD_SEQ_BT)
+
+enum v4l2_buf_type {
+ V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
+ V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
+ V4L2_BUF_TYPE_VBI_CAPTURE = 4,
+ V4L2_BUF_TYPE_VBI_OUTPUT = 5,
+ V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
+ V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
+#if 1 /* KEEP */
+ /* Experimental */
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
+#endif
+ V4L2_BUF_TYPE_PRIVATE = 0x80,
+};
+
+enum v4l2_ctrl_type {
+ V4L2_CTRL_TYPE_INTEGER = 1,
+ V4L2_CTRL_TYPE_BOOLEAN = 2,
+ V4L2_CTRL_TYPE_MENU = 3,
+ V4L2_CTRL_TYPE_BUTTON = 4,
+ V4L2_CTRL_TYPE_INTEGER64 = 5,
+ V4L2_CTRL_TYPE_CTRL_CLASS = 6,
+};
+
+enum v4l2_tuner_type {
+ V4L2_TUNER_RADIO = 1,
+ V4L2_TUNER_ANALOG_TV = 2,
+ V4L2_TUNER_DIGITAL_TV = 3,
+};
+
+enum v4l2_memory {
+ V4L2_MEMORY_MMAP = 1,
+ V4L2_MEMORY_USERPTR = 2,
+ V4L2_MEMORY_OVERLAY = 3,
+};
+
+/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
+enum v4l2_colorspace {
+ /* ITU-R 601 -- broadcast NTSC/PAL */
+ V4L2_COLORSPACE_SMPTE170M = 1,
+
+ /* 1125-Line (US) HDTV */
+ V4L2_COLORSPACE_SMPTE240M = 2,
+
+ /* HD and modern captures. */
+ V4L2_COLORSPACE_REC709 = 3,
+
+ /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
+ V4L2_COLORSPACE_BT878 = 4,
+
+ /* These should be useful. Assume 601 extents. */
+ V4L2_COLORSPACE_470_SYSTEM_M = 5,
+ V4L2_COLORSPACE_470_SYSTEM_BG = 6,
+
+ /*
+ * I know there will be cameras that send this. So, this is
+ * unspecified chromaticities and full 0-255 on each of the Y'CbCr
+ * components
+ */
+ V4L2_COLORSPACE_JPEG = 7,
+
+ /* For RGB colourspaces, this is probably a good start. */
+ V4L2_COLORSPACE_SRGB = 8,
+};
+
+enum v4l2_priority {
+ V4L2_PRIORITY_UNSET = 0,/* not initialized */
+ V4L2_PRIORITY_BACKGROUND = 1,
+ V4L2_PRIORITY_INTERACTIVE = 2,
+ V4L2_PRIORITY_RECORD = 3,
+ V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
+};
+
+struct v4l2_rect {
+ __s32 left;
+ __s32 top;
+ __s32 width;
+ __s32 height;
+};
+
+struct v4l2_fract {
+ __u32 numerator;
+ __u32 denominator;
+};
+
+/*
+ * D R I V E R C A P A B I L I T I E S
+ */
+struct v4l2_capability {
+ __u8 driver[16]; /* i.e.ie; "bttv" */
+ __u8 card[32]; /* i.e.ie; "Hauppauge WinTV" */
+ __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
+ __u32 version;/* should use KERNEL_VERSION() */
+ __u32 capabilities; /* Device capabilities */
+ __u32 reserved[4];
+};
+
+/* Values for 'capabilities' field */
+#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture
+ * device */
+#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output
+ * device */
+#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
+#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture
+ * device */
+#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output
+ * device */
+#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI
+ * capture device */
+#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI
+ * output device */
+#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
+#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output
+ * overlay */
+
+#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
+#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
+#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
+
+#define V4L2_CAP_READWRITE 0x01000000 /* read/write
+ * systemcalls */
+#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
+#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
+
+/*
+ * V I D E O I M A G E F O R M A T
+ */
+struct v4l2_pix_format {
+ __u32 width;
+ __u32 height;
+ __u32 pixelformat;
+ enum v4l2_field field;
+ __u32 bytesperline; /* for padding, zero if unused */
+ __u32 sizeimage;
+ enum v4l2_colorspace colorspace;
+ __u32 priv; /* private data, depends on pixelformat */
+};
+
+/* Pixel format FOURCC depth Description */
+#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */
+#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R','4','4','4') /* 16 xxxxrrrr ggggbbbb */
+#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */
+#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */
+#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */
+#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */
+#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */
+#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */
+#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */
+#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P','A','L','8') /* 8 8-bit palette */
+#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */
+#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */
+#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */
+#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */
+#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y','4','4','4') /* 16 xxxxyyyy uuuuvvvv */
+#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y','U','V','O') /* 16 YUV-5-5-5 */
+#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y','U','V','P') /* 16 YUV-5-6-5 */
+#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y','U','V','4') /* 32 YUV-8-8-8-8 */
+
+/* two planes -- one Y, one Cr + Cb interleaved */
+#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */
+#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */
+
+/* The following formats are not defined in the V4L2 specification */
+#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */
+#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */
+#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */
+#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */
+#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H','M','1','2') /* 8 YUV 4:2:0 16x16
+ * macroblocks */
+
+/* see http://www.siliconimaging.com/RGB%20Bayer.htm */
+#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */
+
+/* compressed formats */
+#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */
+#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */
+#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */
+#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG-1/2/4 */
+
+/* Vendor-specific formats */
+#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
+#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */
+#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */
+#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */
+#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5') /* ET61X251 compression */
+
+/*
+ * F O R M A T E N U M E R A T I O N
+ */
+struct v4l2_fmtdesc {
+ __u32 index; /* Format number */
+ enum v4l2_buf_type type;/* buffer type */
+ __u32 flags;
+ __u8 description[32]; /* Description string */
+ __u32 pixelformat; /* Format fourcc */
+ __u32 reserved[4];
+};
+
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
+
+#if 1 /* KEEP */
+/* Experimental Frame Size and frame rate enumeration */
+/*
+ * F R A M E S I Z E E N U M E R A T I O N
+ */
+enum v4l2_frmsizetypes {
+ V4L2_FRMSIZE_TYPE_DISCRETE = 1,
+ V4L2_FRMSIZE_TYPE_CONTINUOUS = 2,
+ V4L2_FRMSIZE_TYPE_STEPWISE = 3,
+};
+
+struct v4l2_frmsize_discrete {
+ __u32 width; /* Frame width [pixel] */
+ __u32 height; /* Frame height [pixel] */
+};
+
+struct v4l2_frmsize_stepwise {
+ __u32 min_width; /* Minimum frame width [pixel] */
+ __u32 max_width; /* Maximum frame width [pixel] */
+ __u32 step_width; /* Frame width step size [pixel] */
+ __u32 min_height; /* Minimum frame height [pixel] */
+ __u32 max_height; /* Maximum frame height [pixel] */
+ __u32 step_height; /* Frame height step size [pixel] */
+};
+
+struct v4l2_frmsizeenum {
+ __u32 index; /* Frame size number */
+ __u32 pixel_format; /* Pixel format */
+ __u32 type; /* Frame size type the device supports. */
+
+ union { /* Frame size */
+ struct v4l2_frmsize_discrete discrete;
+ struct v4l2_frmsize_stepwise stepwise;
+ };
+
+ __u32 reserved[2]; /* Reserved space for future use */
+};
+
+/*
+ * F R A M E R A T E E N U M E R A T I O N
+ */
+enum v4l2_frmivaltypes {
+ V4L2_FRMIVAL_TYPE_DISCRETE = 1,
+ V4L2_FRMIVAL_TYPE_CONTINUOUS = 2,
+ V4L2_FRMIVAL_TYPE_STEPWISE = 3,
+};
+
+struct v4l2_frmival_stepwise {
+ struct v4l2_fract min; /* Minimum frame interval [s] */
+ struct v4l2_fract max; /* Maximum frame interval [s] */
+ struct v4l2_fract step; /* Frame interval step size [s] */
+};
+
+struct v4l2_frmivalenum {
+ __u32 index; /* Frame format index */
+ __u32 pixel_format; /* Pixel format */
+ __u32 width; /* Frame width */
+ __u32 height; /* Frame height */
+ __u32 type; /* Frame interval type the device supports. */
+
+ union { /* Frame interval */
+ struct v4l2_fract discrete;
+ struct v4l2_frmival_stepwise stepwise;
+ };
+
+ __u32 reserved[2]; /* Reserved space for future use */
+};
+#endif
+
+/*
+ * T I M E C O D E
+ */
+struct v4l2_timecode {
+ __u32 type;
+ __u32 flags;
+ __u8 frames;
+ __u8 seconds;
+ __u8 minutes;
+ __u8 hours;
+ __u8 userbits[4];
+};
+
+/* Type */
+#define V4L2_TC_TYPE_24FPS 1
+#define V4L2_TC_TYPE_25FPS 2
+#define V4L2_TC_TYPE_30FPS 3
+#define V4L2_TC_TYPE_50FPS 4
+#define V4L2_TC_TYPE_60FPS 5
+
+/* Flags */
+#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */
+#define V4L2_TC_FLAG_COLORFRAME 0x0002
+#define V4L2_TC_USERBITS_field 0x000C
+#define V4L2_TC_USERBITS_USERDEFINED 0x0000
+#define V4L2_TC_USERBITS_8BITCHARS 0x0008
+/* The above is based on SMPTE timecodes */
+
+#ifdef __KERNEL__
+/*
+ * M P E G C O M P R E S S I O N P A R A M E T E R S
+ *
+ * ### WARNING: This experimental MPEG compression API is obsolete.
+ * ### It is replaced by the MPEG controls API.
+ * ### This old API will disappear in the near future!
+ *
+ */
+enum v4l2_bitrate_mode {
+ V4L2_BITRATE_NONE = 0, /* not specified */
+ V4L2_BITRATE_CBR, /* constant bitrate */
+ V4L2_BITRATE_VBR, /* variable bitrate */
+};
+struct v4l2_bitrate {
+ /* rates are specified in kbit/sec */
+ enum v4l2_bitrate_mode mode;
+ __u32 min;
+ __u32 target; /* use this one for CBR */
+ __u32 max;
+};
+
+enum v4l2_mpeg_streamtype {
+ V4L2_MPEG_SS_1, /* MPEG-1 system stream */
+ V4L2_MPEG_PS_2, /* MPEG-2 program stream */
+ V4L2_MPEG_TS_2, /* MPEG-2 transport stream */
+ V4L2_MPEG_PS_DVD, /* MPEG-2 program stream with DVD header
+ * fixups */
+};
+enum v4l2_mpeg_audiotype {
+ V4L2_MPEG_AU_2_I, /* MPEG-2 layer 1 */
+ V4L2_MPEG_AU_2_II, /* MPEG-2 layer 2 */
+ V4L2_MPEG_AU_2_III, /* MPEG-2 layer 3 */
+ V4L2_MPEG_AC3, /* AC3 */
+ V4L2_MPEG_LPCM, /* LPCM */
+};
+enum v4l2_mpeg_videotype {
+ V4L2_MPEG_VI_1, /* MPEG-1 */
+ V4L2_MPEG_VI_2, /* MPEG-2 */
+};
+enum v4l2_mpeg_aspectratio {
+ V4L2_MPEG_ASPECT_SQUARE = 1, /* square pixel */
+ V4L2_MPEG_ASPECT_4_3 = 2, /* 4 : 3 */
+ V4L2_MPEG_ASPECT_16_9 = 3, /* 16 : 9 */
+ V4L2_MPEG_ASPECT_1_221 = 4, /* 1 : 2,21 */
+};
+
+struct v4l2_mpeg_compression {
+ /* general */
+ enum v4l2_mpeg_streamtype st_type;
+ struct v4l2_bitrate st_bitrate;
+
+ /* transport streams */
+ __u16 ts_pid_pmt;
+ __u16 ts_pid_audio;
+ __u16 ts_pid_video;
+ __u16 ts_pid_pcr;
+
+ /* program stream */
+ __u16 ps_size;
+ __u16 reserved_1; /* align */
+
+ /* audio */
+ enum v4l2_mpeg_audiotype au_type;
+ struct v4l2_bitrate au_bitrate;
+ __u32 au_sample_rate;
+ __u8 au_pesid;
+ __u8 reserved_2[3]; /* align */
+
+ /* video */
+ enum v4l2_mpeg_videotype vi_type;
+ enum v4l2_mpeg_aspectratio vi_aspect_ratio;
+ struct v4l2_bitrate vi_bitrate;
+ __u32 vi_frame_rate;
+ __u16 vi_frames_per_gop;
+ __u16 vi_bframes_count;
+ __u8 vi_pesid;
+ __u8 reserved_3[3]; /* align */
+
+ /* misc flags */
+ __u32 closed_gops:1;
+ __u32 pulldown:1;
+ __u32 reserved_4:30; /* align */
+
+ /* I don't expect the above being perfect yet ;) */
+ __u32 reserved_5[8];
+};
+#endif
+
+struct v4l2_jpegcompression {
+ int quality;
+
+ int APPn; /* Number of APP segment to be written, must
+ * be 0..15 */
+ int APP_len;/* Length of data in JPEG APPn segment */
+ char APP_data[60]; /* Data in the JPEG APPn segment. */
+
+ int COM_len;/* Length of data in JPEG COM segment */
+ char COM_data[60]; /* Data in JPEG COM segment */
+
+ __u32 jpeg_markers; /* Which markers should go into the
+ * JPEG output. Unless you exactly
+ * know what you do, leave them
+ * untouched. Inluding less markers
+ * will make the resulting code
+ * smaller, but there will be fewer
+ * aplications which can read it. The
+ * presence of the APP and COM marker
+ * is influenced by APP_len and
+ * COM_len ONLY, not by this
+ * property! */
+
+#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
+#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
+#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
+#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
+#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will allways
+ * use APP0 */
+};
+
+/*
+ * M E M O R Y - M A P P I N G B U F F E R S
+ */
+struct v4l2_requestbuffers {
+ __u32 count;
+ enum v4l2_buf_type type;
+ enum v4l2_memory memory;
+ __u32 reserved[2];
+};
+
+struct v4l2_buffer {
+ __u32 index;
+ enum v4l2_buf_type type;
+ __u32 bytesused;
+ __u32 flags;
+ enum v4l2_field field;
+ struct timeval timestamp;
+ struct v4l2_timecode timecode;
+ __u32 sequence;
+
+ /* memory location */
+ enum v4l2_memory memory;
+ union {
+ __u32 offset;
+ unsigned long userptr;
+ } m;
+ __u32 length;
+ __u32 input;
+ __u32 reserved;
+};
+
+/* Flags for 'flags' field */
+#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */
+#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */
+#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */
+#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
+#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
+#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
+#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
+#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */
+
+/*
+ * O V E R L A Y P R E V I E W
+ */
+struct v4l2_framebuffer {
+ __u32 capability;
+ __u32 flags;
+ /*
+ * FIXME: in theory we should pass something like PCI device + memory
+ * region + offset instead of some physical address
+ */
+ void *base;
+ struct v4l2_pix_format fmt;
+};
+/* Flags for the 'capability' field. Read only */
+#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
+#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
+#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
+#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
+#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
+#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
+#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
+/* Flags for the 'flags' field. */
+#define V4L2_FBUF_FLAG_PRIMARY 0x0001
+#define V4L2_FBUF_FLAG_OVERLAY 0x0002
+#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
+#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
+#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
+#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
+
+struct v4l2_clip {
+ struct v4l2_rect c;
+ struct v4l2_clip __user *next;
+};
+
+struct v4l2_window {
+ struct v4l2_rect w;
+ enum v4l2_field field;
+ __u32 chromakey;
+ struct v4l2_clip __user *clips;
+ __u32 clipcount;
+ void __user *bitmap;
+ __u8 global_alpha;
+};
+
+/*
+ * C A P T U R E P A R A M E T E R S
+ */
+struct v4l2_captureparm {
+ __u32 capability; /* Supported modes */
+ __u32 capturemode; /* Current mode */
+ struct v4l2_fract timeperframe; /* Time per frame in .1us units */
+ __u32 extendedmode; /* Driver-specific extensions */
+ __u32 readbuffers; /* # of buffers for read */
+ __u32 reserved[4];
+};
+
+/* Flags for 'capability' and 'capturemode' fields */
+#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
+#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
+
+struct v4l2_outputparm {
+ __u32 capability; /* Supported modes */
+ __u32 outputmode; /* Current mode */
+ struct v4l2_fract timeperframe; /* Time per frame in seconds */
+ __u32 extendedmode; /* Driver-specific extensions */
+ __u32 writebuffers; /* # of buffers for write */
+ __u32 reserved[4];
+};
+
+/*
+ * I N P U T I M A G E C R O P P I N G
+ */
+struct v4l2_cropcap {
+ enum v4l2_buf_type type;
+ struct v4l2_rect bounds;
+ struct v4l2_rect defrect;
+ struct v4l2_fract pixelaspect;
+};
+
+struct v4l2_crop {
+ enum v4l2_buf_type type;
+ struct v4l2_rect c;
+};
+
+/*
+ * A N A L O G V I D E O S T A N D A R D
+ */
+
+typedef __u64 v4l2_std_id;
+
+/* one bit for each */
+#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
+#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
+#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
+#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
+#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
+#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
+#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
+#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
+
+#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
+#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
+#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
+#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
+
+#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
+#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
+#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
+#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000)
+
+#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
+#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
+#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
+#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
+#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
+#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
+#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
+#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000)
+
+/* ATSC/HDTV */
+#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
+#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
+
+/*
+ * FIXME: Although std_id is 64 bits, there is an issue on PPC32 architecture
+ * that makes switch(__u64) to break. So, there's a hack on v4l2-common.c
+ * rounding this value to 32 bits. As, currently, the max value is for
+ * V4L2_STD_ATSC_16_VSB (30 bits wide), it should work fine. However, if
+ * needed to add more than two standards, v4l2-common.c should be fixed.
+ */
+
+/* some merged standards */
+#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
+#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
+#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
+#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
+
+/* some common needed stuff */
+#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
+ V4L2_STD_PAL_B1 |\
+ V4L2_STD_PAL_G)
+#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
+ V4L2_STD_PAL_D1 |\
+ V4L2_STD_PAL_K)
+#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
+ V4L2_STD_PAL_DK |\
+ V4L2_STD_PAL_H |\
+ V4L2_STD_PAL_I)
+#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
+ V4L2_STD_NTSC_M_JP |\
+ V4L2_STD_NTSC_M_KR)
+#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
+ V4L2_STD_SECAM_K |\
+ V4L2_STD_SECAM_K1)
+#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
+ V4L2_STD_SECAM_G |\
+ V4L2_STD_SECAM_H |\
+ V4L2_STD_SECAM_DK |\
+ V4L2_STD_SECAM_L |\
+ V4L2_STD_SECAM_LC)
+
+#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
+ V4L2_STD_PAL_60 |\
+ V4L2_STD_NTSC |\
+ V4L2_STD_NTSC_443)
+#define V4L2_STD_625_50 (V4L2_STD_PAL |\
+ V4L2_STD_PAL_N |\
+ V4L2_STD_PAL_Nc |\
+ V4L2_STD_SECAM)
+#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\
+ V4L2_STD_ATSC_16_VSB)
+
+#define V4L2_STD_UNKNOWN 0
+#define V4L2_STD_ALL (V4L2_STD_525_60 |\
+ V4L2_STD_625_50)
+
+struct v4l2_standard {
+ __u32 index;
+ v4l2_std_id id;
+ __u8 name[24];
+ struct v4l2_fract frameperiod; /* Frames, not fields */
+ __u32 framelines;
+ __u32 reserved[4];
+};
+
+/*
+ * V I D E O I N P U T S
+ */
+struct v4l2_input {
+ __u32 index; /* Which input */
+ __u8 name[32]; /* Label */
+ __u32 type; /* Type of input */
+ __u32 audioset; /* Associated audios (bitfield) */
+ __u32 tuner; /* Associated tuner */
+ v4l2_std_id std;
+ __u32 status;
+ __u32 reserved[4];
+};
+
+/* Values for the 'type' field */
+#define V4L2_INPUT_TYPE_TUNER 1
+#define V4L2_INPUT_TYPE_CAMERA 2
+
+/* field 'status' - general */
+#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */
+#define V4L2_IN_ST_NO_SIGNAL 0x00000002
+#define V4L2_IN_ST_NO_COLOR 0x00000004
+
+/* field 'status' - analog */
+#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
+#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
+
+/* field 'status' - digital */
+#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */
+#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */
+#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */
+
+/* field 'status' - VCR and set-top box */
+#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */
+#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
+#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
+
+/*
+ * V I D E O O U T P U T S
+ */
+struct v4l2_output {
+ __u32 index; /* Which output */
+ __u8 name[32]; /* Label */
+ __u32 type; /* Type of output */
+ __u32 audioset; /* Associated audios (bitfield) */
+ __u32 modulator; /* Associated modulator */
+ v4l2_std_id std;
+ __u32 reserved[4];
+};
+/* Values for the 'type' field */
+#define V4L2_OUTPUT_TYPE_MODULATOR 1
+#define V4L2_OUTPUT_TYPE_ANALOG 2
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
+
+/*
+ * C O N T R O L S
+ */
+struct v4l2_control {
+ __u32 id;
+ __s32 value;
+};
+
+struct v4l2_ext_control {
+ __u32 id;
+ __u32 reserved2[2];
+ union {
+ __s32 value;
+ __s64 value64;
+ void *reserved;
+ };
+} __attribute__((packed));
+
+struct v4l2_ext_controls {
+ __u32 ctrl_class;
+ __u32 count;
+ __u32 error_idx;
+ __u32 reserved[2];
+ struct v4l2_ext_control *controls;
+};
+
+/* Values for ctrl_class field */
+#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
+#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
+
+#define V4L2_CTRL_ID_MASK (0x0fffffff)
+#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
+#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
+
+/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
+struct v4l2_queryctrl {
+ __u32 id;
+ enum v4l2_ctrl_type type;
+ __u8 name[32]; /* Whatever */
+ __s32 minimum;/* Note signedness */
+ __s32 maximum;
+ __s32 step;
+ __s32 default_value;
+ __u32 flags;
+ __u32 reserved[2];
+};
+
+/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
+struct v4l2_querymenu {
+ __u32 id;
+ __u32 index;
+ __u8 name[32]; /* Whatever */
+ __u32 reserved;
+};
+
+/* Control flags */
+#define V4L2_CTRL_FLAG_DISABLED 0x0001
+#define V4L2_CTRL_FLAG_GRABBED 0x0002
+#define V4L2_CTRL_FLAG_READ_ONLY 0x0004
+#define V4L2_CTRL_FLAG_UPDATE 0x0008
+#define V4L2_CTRL_FLAG_INACTIVE 0x0010
+#define V4L2_CTRL_FLAG_SLIDER 0x0020
+
+/* Query flag, to be ORed with the control ID */
+#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
+
+/* User-class control IDs defined by V4L2 */
+#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
+#define V4L2_CID_USER_BASE V4L2_CID_BASE
+/* IDs reserved for driver specific controls */
+#define V4L2_CID_PRIVATE_BASE 0x08000000
+
+#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1)
+#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
+#define V4L2_CID_HUE (V4L2_CID_BASE+3)
+#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
+#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
+#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
+#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
+#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
+#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
+#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11)
+#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
+#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
+#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
+#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
+#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
+#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */
+#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
+#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
+#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
+#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
+#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
+#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
+#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */
+
+/* MPEG-class control IDs defined by V4L2 */
+#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
+#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
+
+/* MPEG streams */
+#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0)
+enum v4l2_mpeg_stream_type {
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible
+ * stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible
+ * stream */
+ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible
+ * stream */
+};
+#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1)
+#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2)
+#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3)
+#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4)
+#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5)
+#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6)
+#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7)
+enum v4l2_mpeg_stream_vbi_fmt {
+ V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */
+ V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets,
+ * IVTV format */
+};
+
+/* MPEG audio */
+#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100)
+enum v4l2_mpeg_audio_sampling_freq {
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101)
+enum v4l2_mpeg_audio_encoding {
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
+enum v4l2_mpeg_audio_l1_bitrate {
+ V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1,
+ V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2,
+ V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3,
+ V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4,
+ V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5,
+ V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6,
+ V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7,
+ V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8,
+ V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9,
+ V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10,
+ V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11,
+ V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
+ V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103)
+enum v4l2_mpeg_audio_l2_bitrate {
+ V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1,
+ V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2,
+ V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3,
+ V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4,
+ V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5,
+ V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6,
+ V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7,
+ V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8,
+ V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9,
+ V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10,
+ V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11,
+ V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
+ V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104)
+enum v4l2_mpeg_audio_l3_bitrate {
+ V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1,
+ V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2,
+ V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3,
+ V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4,
+ V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5,
+ V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6,
+ V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7,
+ V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8,
+ V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9,
+ V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10,
+ V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11,
+ V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
+ V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105)
+enum v4l2_mpeg_audio_mode {
+ V4L2_MPEG_AUDIO_MODE_STEREO = 0,
+ V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
+ V4L2_MPEG_AUDIO_MODE_DUAL = 2,
+ V4L2_MPEG_AUDIO_MODE_MONO = 3,
+};
+#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106)
+enum v4l2_mpeg_audio_mode_extension {
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
+};
+#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107)
+enum v4l2_mpeg_audio_emphasis {
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0,
+ V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
+ V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108)
+enum v4l2_mpeg_audio_crc {
+ V4L2_MPEG_AUDIO_CRC_NONE = 0,
+ V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
+};
+#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109)
+
+/* MPEG video */
+#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
+enum v4l2_mpeg_video_encoding {
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201)
+enum v4l2_mpeg_video_aspect {
+ V4L2_MPEG_VIDEO_ASPECT_1x1 = 0,
+ V4L2_MPEG_VIDEO_ASPECT_4x3 = 1,
+ V4L2_MPEG_VIDEO_ASPECT_16x9 = 2,
+ V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
+};
+#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202)
+#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203)
+#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204)
+#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206)
+enum v4l2_mpeg_video_bitrate_mode {
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
+#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
+#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
+#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
+
+/* MPEG-class control IDs specific to the CX2584x driver as defined by V4L2 */
+#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
+enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2)
+enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3)
+enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4)
+enum v4l2_mpeg_cx2341x_video_temporal_filter_mode {
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6)
+enum v4l2_mpeg_cx2341x_video_median_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
+#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11)
+
+/*
+ * T U N I N G
+ */
+struct v4l2_tuner {
+ __u32 index;
+ __u8 name[32];
+ enum v4l2_tuner_type type;
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 rxsubchans;
+ __u32 audmode;
+ __s32 signal;
+ __s32 afc;
+ __u32 reserved[4];
+};
+
+struct v4l2_modulator {
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 txsubchans;
+ __u32 reserved[4];
+};
+
+/* Flags for the 'capability' field */
+#define V4L2_TUNER_CAP_LOW 0x0001
+#define V4L2_TUNER_CAP_NORM 0x0002
+#define V4L2_TUNER_CAP_STEREO 0x0010
+#define V4L2_TUNER_CAP_LANG2 0x0020
+#define V4L2_TUNER_CAP_SAP 0x0020
+#define V4L2_TUNER_CAP_LANG1 0x0040
+
+/* Flags for the 'rxsubchans' field */
+#define V4L2_TUNER_SUB_MONO 0x0001
+#define V4L2_TUNER_SUB_STEREO 0x0002
+#define V4L2_TUNER_SUB_LANG2 0x0004
+#define V4L2_TUNER_SUB_SAP 0x0004
+#define V4L2_TUNER_SUB_LANG1 0x0008
+
+/* Values for the 'audmode' field */
+#define V4L2_TUNER_MODE_MONO 0x0000
+#define V4L2_TUNER_MODE_STEREO 0x0001
+#define V4L2_TUNER_MODE_LANG2 0x0002
+#define V4L2_TUNER_MODE_SAP 0x0002
+#define V4L2_TUNER_MODE_LANG1 0x0003
+#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004
+
+struct v4l2_frequency {
+ __u32 tuner;
+ enum v4l2_tuner_type type;
+ __u32 frequency;
+ __u32 reserved[8];
+};
+
+/*
+ * A U D I O
+ */
+struct v4l2_audio {
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 mode;
+ __u32 reserved[2];
+};
+
+/* Flags for the 'capability' field */
+#define V4L2_AUDCAP_STEREO 0x00001
+#define V4L2_AUDCAP_AVL 0x00002
+
+/* Flags for the 'mode' field */
+#define V4L2_AUDMODE_AVL 0x00001
+
+struct v4l2_audioout {
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 mode;
+ __u32 reserved[2];
+};
+
+/*
+ * M P E G S E R V I C E S
+ *
+ * NOTE: EXPERIMENTAL API
+ */
+#if 1 /* KEEP */
+#define V4L2_ENC_IDX_FRAME_I (0)
+#define V4L2_ENC_IDX_FRAME_P (1)
+#define V4L2_ENC_IDX_FRAME_B (2)
+#define V4L2_ENC_IDX_FRAME_MASK (0xf)
+
+struct v4l2_enc_idx_entry {
+ __u64 offset;
+ __u64 pts;
+ __u32 length;
+ __u32 flags;
+ __u32 reserved[2];
+};
+
+#define V4L2_ENC_IDX_ENTRIES (64)
+struct v4l2_enc_idx {
+ __u32 entries;
+ __u32 entries_cap;
+ __u32 reserved[4];
+ struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES];
+};
+
+
+#define V4L2_ENC_CMD_START (0)
+#define V4L2_ENC_CMD_STOP (1)
+#define V4L2_ENC_CMD_PAUSE (2)
+#define V4L2_ENC_CMD_RESUME (3)
+
+/* Flags for V4L2_ENC_CMD_STOP */
+#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0)
+
+struct v4l2_encoder_cmd {
+ __u32 cmd;
+ __u32 flags;
+ union {
+ struct {
+ __u32 data[8];
+ } raw;
+ };
+};
+
+#endif
+
+
+/*
+ * D A T A S E R V I C E S ( V B I )
+ *
+ * Data services API by Michael Schimek
+ */
+
+/* Raw VBI */
+struct v4l2_vbi_format {
+ __u32 sampling_rate; /* in 1 Hz */
+ __u32 offset;
+ __u32 samples_per_line;
+ __u32 sample_format; /* V4L2_PIX_FMT_* */
+ __s32 start[2];
+ __u32 count[2];
+ __u32 flags; /* V4L2_VBI_* */
+ __u32 reserved[2]; /* must be zero */
+};
+
+/* VBI flags */
+#define V4L2_VBI_UNSYNC (1<< 0)
+#define V4L2_VBI_INTERLACED (1<< 1)
+
+/*
+ * Sliced VBI
+ *
+ * This implements is a proposal V4L2 API to allow SLICED VBI required for some
+ * hardware encoders. It should change without notice in the definitive
+ * implementation.
+ */
+
+struct v4l2_sliced_vbi_format {
+ __u16 service_set;
+ /*
+ * service_lines[0][...] specifies lines 0-23 (1-23 used) of the
+ * first field service_lines[1][...] specifies lines 0-23 (1-23 used)
+ * of the second field (equals frame lines 313-336 for 625 line video
+ * standards, 263-286 for 525 line standards)
+ */
+ __u16 service_lines[2][24];
+ __u32 io_size;
+ __u32 reserved[2]; /* must be zero */
+};
+
+/*
+ * Teletext World System Teletext (WST), defined on ITU-R BT.653-2
+ */
+#define V4L2_SLICED_TELETEXT_B (0x0001)
+/* Video Program System, defined on ETS 300 231 */
+#define V4L2_SLICED_VPS (0x0400)
+/* Closed Caption, defined on EIA-608 */
+#define V4L2_SLICED_CAPTION_525 (0x1000)
+/* Wide Screen System, defined on ITU-R BT1119.1 */
+#define V4L2_SLICED_WSS_625 (0x4000)
+
+#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525)
+#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
+
+struct v4l2_sliced_vbi_cap {
+ __u16 service_set;
+ /*
+ * service_lines[0][...] specifies lines 0-23 (1-23 used) of the
+ * first field service_lines[1][...] specifies lines 0-23 (1-23 used)
+ * of the second field (equals frame lines 313-336 for 625 line video
+ * standards, 263-286 for 525 line standards)
+ */
+ __u16 service_lines[2][24];
+ enum v4l2_buf_type type;
+ __u32 reserved[3]; /* must be 0 */
+};
+
+struct v4l2_sliced_vbi_data {
+ __u32 id;
+ __u32 field; /* 0: first field, 1: second field */
+ __u32 line; /* 1-23 */
+ __u32 reserved; /* must be 0 */
+ __u8 data[48];
+};
+
+/*
+ * A G G R E G A T E S T R U C T U R E S
+ */
+
+/*
+ * Stream data format
+ */
+struct v4l2_format {
+ enum v4l2_buf_type type;
+ union {
+ struct v4l2_pix_format pix;
+ //V4L2_BUF_TYPE_VIDEO_CAPTURE
+ struct v4l2_window win;
+ //V4L2_BUF_TYPE_VIDEO_OVERLAY
+ struct v4l2_vbi_format vbi;
+ //V4L2_BUF_TYPE_VBI_CAPTURE
+ struct v4l2_sliced_vbi_format sliced;
+ //V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
+ __u8 raw_data[200];
+ //user - defined
+ } fmt;
+};
+
+
+/*
+ * Stream type-dependent parameters
+ */
+struct v4l2_streamparm {
+ enum v4l2_buf_type type;
+ union {
+ struct v4l2_captureparm capture;
+ struct v4l2_outputparm output;
+ __u8 raw_data[200]; /* user-defined */
+ } parm;
+};
+
+/*
+ * A D V A N C E D D E B U G G I N G
+ *
+ * NOTE: EXPERIMENTAL API
+ */
+
+/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
+
+#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0
+ * for the host) */
+#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver ID */
+#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
+
+struct v4l2_register {
+ __u32 match_type; /* Match type */
+ __u32 match_chip; /* Match this chip, meaning
+ * determined by match_type */
+ __u64 reg;
+ __u64 val;
+};
+
+/* VIDIOC_G_CHIP_IDENT */
+struct v4l2_chip_ident {
+ __u32 match_type; /* Match type */
+ __u32 match_chip; /* Match this chip, meaning
+ * determined by match_type */
+ __u32 ident; /* chip identifier as specified in
+ * <media/v4l2-chip-ident.h> */
+ __u32 revision; /* chip revision, chip specific */
+};
+
+/*
+ * I O C T L C O D E S F O R V I D E O D E V I C E S
+ *
+ */
+#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability)
+#define VIDIOC_RESERVED _IO ('V', 1)
+#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
+#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
+#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
+#ifdef __KERNEL__
+#define VIDIOC_G_MPEGCOMP _IOR ('V', 6, struct v4l2_mpeg_compression)
+#define VIDIOC_S_MPEGCOMP _IOW ('V', 7, struct v4l2_mpeg_compression)
+#endif
+#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
+#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
+#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
+#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer)
+#define VIDIOC_OVERLAY _IOW ('V', 14, int)
+#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer)
+#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer)
+#define VIDIOC_STREAMON _IOW ('V', 18, int)
+#define VIDIOC_STREAMOFF _IOW ('V', 19, int)
+#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm)
+#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id)
+#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id)
+#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard)
+#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input)
+#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control)
+#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control)
+#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner)
+#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner)
+#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio)
+#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio)
+#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl)
+#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu)
+#define VIDIOC_G_INPUT _IOR ('V', 38, int)
+#define VIDIOC_S_INPUT _IOWR ('V', 39, int)
+#define VIDIOC_G_OUTPUT _IOR ('V', 46, int)
+#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int)
+#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output)
+#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout)
+#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout)
+#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator)
+#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator)
+#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency)
+#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency)
+#define VIDIOC_CROPCAP _IOWR ('V', 58, struct v4l2_cropcap)
+#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop)
+#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
+#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression)
+#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression)
+#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
+#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio)
+#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
+#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
+#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
+#define VIDIOC_G_SLICED_VBI_CAP _IOWR ('V', 69, struct v4l2_sliced_vbi_cap)
+#define VIDIOC_LOG_STATUS _IO ('V', 70)
+#define VIDIOC_G_EXT_CTRLS _IOWR ('V', 71, struct v4l2_ext_controls)
+#define VIDIOC_S_EXT_CTRLS _IOWR ('V', 72, struct v4l2_ext_controls)
+#define VIDIOC_TRY_EXT_CTRLS _IOWR ('V', 73, struct v4l2_ext_controls)
+#if 1 /* KEEP */
+#define VIDIOC_ENUM_FRAMESIZES _IOWR ('V', 74, struct v4l2_frmsizeenum)
+#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR ('V', 75, struct v4l2_frmivalenum)
+#define VIDIOC_G_ENC_INDEX _IOR ('V', 76, struct v4l2_enc_idx)
+#define VIDIOC_ENCODER_CMD _IOWR ('V', 77, struct v4l2_encoder_cmd)
+#define VIDIOC_TRY_ENCODER_CMD _IOWR ('V', 78, struct v4l2_encoder_cmd)
+
+/* Experimental, only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
+#define VIDIOC_DBG_S_REGISTER _IOW ('V', 79, struct v4l2_register)
+#define VIDIOC_DBG_G_REGISTER _IOWR ('V', 80, struct v4l2_register)
+
+#define VIDIOC_G_CHIP_IDENT _IOWR ('V', 81, struct v4l2_chip_ident)
+#endif
+
+#ifdef __OLD_VIDIOC_
+/* for compatibility, will go away some day */
+#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
+#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
+#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
+#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
+#define VIDIOC_CROPCAP_OLD _IOR ('V', 58, struct v4l2_cropcap)
+#endif
+
+#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
+
+#endif /* _SYS_VIDEOIO_H */