Commit 17a4de9d authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

patch from dimitry for the usb ibmcam driver that does:

  	- Updates the documentation
  	- Adds Veo Stingray support
  	- Fixes hotplug table dependency upon now-defunct symbol
  	- deletes drivers/usb/ibmcam.h
parent 040fdeaf
......@@ -25,12 +25,19 @@ Supported controls:
SUPPORTED CAMERAS:
IBM "C-It" camera, also known as "Xirlink PC Camera"
Xirlink "C-It" camera, also known as "IBM PC Camera".
The device uses proprietary ASIC (and compression method);
it is manufactured by Xirlink. See http://www.xirlink.com/
http://www.ibmpccamera.com or http://www.c-itnow.com/ for
details and pictures.
This very chipset ("X Chip", as marked at the factory)
is used in several other cameras, and they are supported
as well:
- IBM NetCamera
- Veo Stingray
The Linux driver was developed with camera with following
model number (or FCC ID): KSX-XVP510. This camera has three
interfaces, each with one endpoint (control, iso, iso). This
......@@ -50,12 +57,30 @@ These cameras have two interfaces, one endpoint in each (iso, bulk).
Such type of cameras is referred to as "model 2". They are supported
(with exception of 352x288 native mode).
Some IBM NetCameras (Model 4) are made to generate only compressed
video streams. This is great for performance, but unfortunately
nobody knows how to decompress the stream :-( Therefore, these
cameras are *unsupported* and if you try to use one of those, all
you get is random colored horizontal streaks, not the image!
If you have one of those cameras, you probably should return it
to the store and get something that is supported.
Tell me more about all that "model" business
--------------------------------------------
I just invented model numbers to uniquely identify flavors of the
hardware/firmware that were sold. It was very confusing to use
brand names or some other internal numbering schemes. So I found
by experimentation that all Xirlink chipsets fall into four big
classes, and I called them "models". Each model is programmed in
its own way, and each model sends back the video in its own way.
Quirks of Model 2 cameras:
-------------------------
Model 2 does not have hardware contrast control. Corresponding V4L
control is not used at the moment. It may be possible to implement
contrast control in software, at cost of extra processor cycles.
control is implemented in software, which is not very nice to your
CPU, but at least it works.
This driver provides 352x288 mode by switching the camera into
quasi-352x288 RGB mode (800 Kbits per frame) essentially limiting
......@@ -67,17 +92,24 @@ be good at one brightness and broken at another! I did not want to fix
the frame rate at slowest setting, but I had to move it pretty much down
the scale (so that framerate option barely matters). I also noticed that
camera after first powering up produces frames slightly faster than during
consecutive uses. All this means that if you use videosize=2 (which is
consecutive uses. All this means that if you use 352x288 (which is
default), be warned - you may encounter broken picture on first connect;
try to adjust brightness - brighter image is slower, so USB will be able
to send all data. However if you regularly use Model 2 cameras you may
prefer videosize=1 which makes perfectly good I420, with no scaling and
prefer 176x144 which makes perfectly good I420, with no scaling and
lesser demands on USB (300 Kbits per second, or 26 frames per second).
Another strange effect of 352x288 mode is the fine vertical grid visible
on some colored surfaces. I am sure it is caused by me not understanding
what the camera is trying to say. Blame trade secrets for that.
The camera that I had also has a hardware quirk: if disconnected,
it needs few minutes to "relax" before it can be plugged in again
(poorly designed USB processor reset circuit?)
[Veo Stingray with Product ID 0x800C is also Model 2, but I haven't
observed this particular flaw in it.]
Model 2 camera can be programmed for very high sensitivity (even starlight
may be enough), this makes it convenient for tinkering with. The driver
code has enough comments to help a programmer to tweak the camera
......@@ -98,12 +130,14 @@ or if you want to make changes to the code. Most distributions
precompile all modules, so you can go directly to the next
section "HOW TO USE THE DRIVER".
The driver consists of two files in usb/ directory:
ibmcam.c and ibmcam.h These files are included into the
Linux kernel build process if you configure the kernel
for CONFIG_USB_IBMCAM. Run "make xconfig" and in USB section
you will find the IBM camera driver. Select it, save the
configuration and recompile.
The ibmcam driver uses usbvideo helper library (module),
so if you are studying the ibmcam code you will be led there.
The driver itself consists of only one file in usb/ directory:
ibmcam.c. This file is included into the Linux kernel build
process if you configure the kernel for CONFIG_USB_IBMCAM.
Run "make xconfig" and in USB section you will find the IBM
camera driver. Select it, save the configuration and recompile.
HOW TO USE THE DRIVER:
......@@ -112,6 +146,13 @@ easier access to its configuration. The camera has many more
settings than V4L can operate, so some settings are done using
module options.
To begin with, on most modern Linux distributions the driver
will be automatically loaded whenever you plug the supported
camera in. Therefore, you don't need to do anything. However
if you want to experiment with some module parameters then
you can load and unload the driver manually, with camera
plugged in or unplugged.
Typically module is installed with command 'modprobe', like this:
# modprobe ibmcam framerate=1
......@@ -138,7 +179,7 @@ init_color Integer 0-255 [128] init_color=130
init_hue Integer 0-255 [128] init_hue=115
lighting Integer 0-2* [1] lighting=2
sharpness Integer 0-6* [4] sharpness=3
videosize Integer 0-2* [2] videosize=1
size Integer 0-2* [2] size=1
Options for Model 2 only:
......@@ -181,6 +222,11 @@ flags This is a bit mask, and you can combine any number of
this is a little faster but may
produce flicker if frame rate is
too high and Isoc data gets lost.
FLAGS_NO_DECODING 128 This flag turns the video stream
decoder off, and dumps the raw
Isoc data from the camera into
the reading process. Useful to
developers, but not to users.
framerate This setting controls frame rate of the camera. This is
an approximate setting (in terms of "worst" ... "best")
......@@ -227,35 +273,38 @@ sharpness This option controls smoothing (noise reduction)
be greeted with "snowy" image. Default is 4. Model 2
cameras do not support this feature.
videosize This setting chooses one if three image sizes that are
supported by this driver. Camera supports more, but
size This setting chooses one of several image sizes that are
supported by this driver. Cameras may support more, but
it's difficult to reverse-engineer all formats.
Following video sizes are supported:
videosize=0 128x96 (Model 1 only)
videosize=1 176x144
videosize=2 352x288
videosize=3 320x240 (Model 2 only)
videosize=4 352x240 (Model 2 only)
size=0 128x96 (Model 1 only)
size=1 160x120
size=2 176x144
size=3 320x240 (Model 2 only)
size=4 352x240 (Model 2 only)
size=5 352x288
size=6 640x480 (Model 3 only)
The last one (352x288) is the native size of the sensor
array, so it's the best resolution camera (Model 1) can
The 352x288 is the native size of the Model 1 sensor
array, so it's the best resolution the camera can
yield. The best resolution of Model 2 is 176x144, and
larger images are produced by stretching the bitmap.
Model 3 has sensor with 640x480 grid, and it works too,
but the frame rate will be exceptionally low (1-2 FPS);
it may be still OK for some applications, like security.
Choose the image size you need. The smaller image can
support faster frame rate. Default is 352x288.
For more information and the Troubleshooting FAQ visit this URL:
http://www.linux-usb.org/ibmcam/
WHAT NEEDS TO BE DONE:
- The box freezes if camera is unplugged after being used (OHCI).
Workaround: remove usb-ohci module first.
- On occasion camera (model 1) does not start properly (xawtv reports
errors), or camera produces negative image (funny colors.)
Workaround: reload the driver module. Reason: [1].
- The button on the camera is not used. I don't know how to get to it.
I know now how to read button on Model 2, but what to do with it?
[1]
- Camera reports its status back to the driver; however I don't know
what returned data means. If camera fails at some initialization
stage then something should be done, and I don't do that because
......@@ -263,26 +312,13 @@ WHAT NEEDS TO BE DONE:
concern because Model 2 uses different commands which do not return
status (and seem to complete successfully every time).
VIDEO SIZE AND IMAGE SIZE
Camera produces picture X by Y pixels. This is camera-specific and can be
altered by programming the camera accordingly. This image is placed onto
larger (or equal) area W by H, this is V4L image. At this time the driver
uses V4L image size (W by H) 352x288 pixels because many programs (such
as xawtv) expect quite specific sizes and don't want to deal with arbitrary,
camera-specific sizes. However this approach "hides" real image size, and
application always sees the camera as producing only 352x288 image. It is
possible to change the V4L image size to 128x96, and then if camera is
switched to 128x96 mode then xawtv will correctly accept this image size. But
many other popular sizes (such as 176x144) will not be welcomed. This is the
reason why all camera images are at this time placed onto 352x288 "canvas",
and size of that canvas (V4L) is reported to applications. It will be easy
to add options to control the canvas size, but it will be application-
specific because not all applications are ready to work with variety of
camera-specific sizes.
- Some flavors of Model 4 NetCameras produce only compressed video
streams, and I don't know how to decode them.
CREDITS:
The code is based in no small part on the CPiA driver by Johannes Erdfelt,
Randy Dunlap, and others. Big thanks to them for their pioneering work on that
and the USB stack.
I also thank John Lightsey for his donation of the Veo Stingray camera.
/*
* USB IBM C-It Video Camera driver
*
* Supports IBM C-It Video Camera.
* Supports Xirlink C-It Video Camera, IBM PC Camera,
* IBM NetCamera and Veo Stingray.
*
* This driver is based on earlier work of:
*
......@@ -36,6 +37,8 @@
#define IBMCAM_VENDOR_ID 0x0545
#define IBMCAM_PRODUCT_ID 0x8080
#define NETCAM_PRODUCT_ID 0x8002 /* IBM NetCamera, close to model 2 */
#define VEO_800C_PRODUCT_ID 0x800C /* Veo Stingray, repackaged Model 2 */
#define VEO_800D_PRODUCT_ID 0x800D /* Veo Stingray, repackaged Model 4 */
#define MAX_IBMCAM 4 /* How many devices we allow to connect */
#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */
......@@ -3671,6 +3674,8 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru
if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID)
return NULL;
if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) &&
(dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) &&
(dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) &&
(dev->descriptor.idProduct != NETCAM_PRODUCT_ID))
return NULL;
......@@ -3684,7 +3689,8 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru
case 0x030A:
if (ifnum != 0)
return NULL;
if (dev->descriptor.idProduct == NETCAM_PRODUCT_ID)
if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) ||
(dev->descriptor.idProduct == VEO_800D_PRODUCT_ID))
model = IBMCAM_MODEL_4;
else
model = IBMCAM_MODEL_2;
......@@ -3699,8 +3705,28 @@ static void *ibmcam_probe(struct usb_device *dev, unsigned int ifnum, const stru
dev->descriptor.bcdDevice);
return NULL;
}
info("IBM USB camera found (model %d, rev. 0x%04x)",
model, dev->descriptor.bcdDevice);
/* Print detailed info on what we found so far */
do {
char *brand = NULL;
switch (dev->descriptor.idProduct) {
case NETCAM_PRODUCT_ID:
brand = "IBM NetCamera";
break;
case VEO_800C_PRODUCT_ID:
brand = "Veo Stingray [800C]";
break;
case VEO_800D_PRODUCT_ID:
brand = "Veo Stingray [800D]";
break;
case IBMCAM_PRODUCT_ID:
default:
brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */
break;
}
info("%s USB camera found (model %d, rev. 0x%04x)",
brand, model, dev->descriptor.bcdDevice);
} while (0);
/* Validate found interface: must have one ISO endpoint */
nas = dev->actconfig->interface[ifnum].num_altsetting;
......@@ -3908,18 +3934,16 @@ static void __exit ibmcam_cleanup(void)
usbvideo_Deregister(&cams);
}
#if defined(usb_device_id_ver)
static __devinitdata struct usb_device_id id_table[] = {
{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) }, /* Model 1 */
{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) }, /* Model 3 */
{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 2 */
{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) }, /* Model 4 */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
#endif /* defined(usb_device_id_ver) */
module_init(ibmcam_init);
module_exit(ibmcam_cleanup);
/*
* Header file for USB IBM C-It Video Camera driver.
*
* Supports IBM C-It Video Camera.
*
* This driver is based on earlier work of:
*
* (C) Copyright 1999 Johannes Erdfelt
* (C) Copyright 1999 Randy Dunlap
*/
#ifndef __LINUX_IBMCAM_H
#define __LINUX_IBMCAM_H
#include <linux/list.h>
#define USES_IBMCAM_PUTPIXEL 0 /* 0=Fast/oops 1=Slow/secure */
/* Video Size 384 x 288 x 3 bytes for RGB */
/* 384 because xawtv tries to grab 384 even though we tell it 352 is our max */
#define V4L_FRAME_WIDTH 384
#define V4L_FRAME_WIDTH_USED 352
#define V4L_FRAME_HEIGHT 288
#define V4L_BYTES_PER_PIXEL 3
#define MAX_FRAME_SIZE (V4L_FRAME_WIDTH * V4L_FRAME_HEIGHT * V4L_BYTES_PER_PIXEL)
/* Camera capabilities (maximum) */
#define CAMERA_IMAGE_WIDTH 352
#define CAMERA_IMAGE_HEIGHT 288
#define CAMERA_IMAGE_LINE_SZ ((CAMERA_IMAGE_WIDTH * 3) / 2) /* Bytes */
#define CAMERA_URB_FRAMES 32
#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */
#define IBMCAM_NUMFRAMES 2
#define IBMCAM_NUMSBUF 2
#define FRAMES_PER_DESC (CAMERA_URB_FRAMES)
#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET)
/* This macro restricts an int variable to an inclusive range */
#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
/*
* This macro performs bounds checking - use it when working with
* new formats, or else you may get oopses all over the place.
* If pixel falls out of bounds then it gets shoved back (as close
* to place of offence as possible) and is painted bright red.
*/
#define IBMCAM_PUTPIXEL(fr, ix, iy, vr, vg, vb) { \
register unsigned char *pf; \
int limiter = 0, mx, my; \
mx = ix; \
my = iy; \
if (mx < 0) { \
mx=0; \
limiter++; \
} else if (mx >= 352) { \
mx=351; \
limiter++; \
} \
if (my < 0) { \
my = 0; \
limiter++; \
} else if (my >= V4L_FRAME_HEIGHT) { \
my = V4L_FRAME_HEIGHT - 1; \
limiter++; \
} \
pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*352 + (ix)); \
if (limiter) { \
*pf++ = 0; \
*pf++ = 0; \
*pf++ = 0xFF; \
} else { \
*pf++ = (vb); \
*pf++ = (vg); \
*pf++ = (vr); \
} \
}
/*
* We use macros to do YUV -> RGB conversion because this is
* very important for speed and totally unimportant for size.
*
* YUV -> RGB Conversion
* ---------------------
*
* B = 1.164*(Y-16) + 2.018*(V-128)
* G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
* R = 1.164*(Y-16) + 1.596*(U-128)
*
* If you fancy integer arithmetics (as you should), hear this:
*
* 65536*B = 76284*(Y-16) + 132252*(V-128)
* 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128)
* 65536*R = 76284*(Y-16) + 104595*(U-128)
*
* Make sure the output values are within [0..255] range.
*/
#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
mm_y = (my) - 16; \
mm_u = (mu) - 128; \
mm_v = (mv) - 128; \
mm_yc= mm_y * 76284; \
mm_b = (mm_yc + 132252*mm_v ) >> 16; \
mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \
mm_r = (mm_yc + 104595*mm_u ) >> 16; \
mb = LIMIT_RGB(mm_b); \
mg = LIMIT_RGB(mm_g); \
mr = LIMIT_RGB(mm_r); \
}
/* Debugging aid */
#define IBMCAM_SAY_AND_WAIT(what) { \
wait_queue_head_t wq; \
init_waitqueue_head(&wq); \
printk(KERN_INFO "Say: %s\n", what); \
interruptible_sleep_on_timeout (&wq, HZ*3); \
}
/*
* This macro checks if ibmcam is still operational. The 'ibmcam'
* pointer must be valid, ibmcam->dev must be valid, we are not
* removing the device and the device has not erred on us.
*/
#define IBMCAM_IS_OPERATIONAL(ibm_cam) (\
(ibm_cam != NULL) && \
((ibm_cam)->dev != NULL) && \
((ibm_cam)->last_error == 0) && \
(!(ibm_cam)->remove_pending))
enum {
STATE_SCANNING, /* Scanning for header */
STATE_LINES, /* Parsing lines */
};
enum {
FRAME_UNUSED, /* Unused (no MCAPTURE) */
FRAME_READY, /* Ready to start grabbing */
FRAME_GRABBING, /* In the process of being grabbed into */
FRAME_DONE, /* Finished grabbing, but not been synced yet */
FRAME_ERROR, /* Something bad happened while processing */
};
struct usb_device;
struct ibmcam_sbuf {
char *data;
struct urb *urb;
};
struct ibmcam_frame {
char *data; /* Frame buffer */
int order_uv; /* True=UV False=VU */
int order_yc; /* True=Yc False=cY ('c'=either U or V) */
unsigned char hdr_sig; /* "00 FF 00 ??" where 'hdr_sig' is '??' */
int width; /* Width application is expecting */
int height; /* Height */
int frmwidth; /* Width the frame actually is */
int frmheight; /* Height */
volatile int grabstate; /* State of grabbing */
int scanstate; /* State of scanning */
int curline; /* Line of frame we're working on */
long scanlength; /* uncompressed, raw data length of frame */
long bytes_read; /* amount of scanlength that has been read from *data */
wait_queue_head_t wq; /* Processes waiting */
};
#define IBMCAM_MODEL_1 1 /* XVP-501, 3 interfaces, rev. 0.02 */
#define IBMCAM_MODEL_2 2 /* KSX-X9903, 2 interfaces, rev. 3.0a */
struct usb_ibmcam {
struct video_device vdev;
/* Device structure */
struct usb_device *dev;
unsigned char iface; /* Video interface number */
unsigned char ifaceAltActive, ifaceAltInactive; /* Alt settings */
struct semaphore lock;
int user; /* user count for exclusive use */
int ibmcam_used; /* Is this structure in use? */
int initialized; /* Had we already sent init sequence? */
int camera_model; /* What type of IBM camera we got? */
int streaming; /* Are we streaming Isochronous? */
int grabbing; /* Are we grabbing? */
int last_error; /* What calamity struck us? */
int compress; /* Should the next frame be compressed? */
char *fbuf; /* Videodev buffer area */
int fbuf_size; /* Videodev buffer size */
int curframe;
struct ibmcam_frame frame[IBMCAM_NUMFRAMES]; /* Double buffering */
int cursbuf; /* Current receiving sbuf */
struct ibmcam_sbuf sbuf[IBMCAM_NUMSBUF]; /* Double buffering */
volatile int remove_pending; /* If set then about to exit */
/*
* Scratch space from the Isochronous pipe.
* Scratch buffer should contain at least one pair of lines
* (CAMERA_IMAGE_LINE_SZ). We set it to two pairs here.
* This will be approximately 2 KB. HOWEVER in reality this
* buffer must be as large as hundred of KB because otherwise
* you'll get lots of overflows because V4L client may request
* frames not as uniformly as USB sources them.
*/
unsigned char *scratch;
int scratchlen;
struct video_picture vpic, vpic_old; /* Picture settings */
struct video_capability vcap; /* Video capabilities */
struct video_channel vchan; /* May be used for tuner support */
unsigned char video_endp; /* 0x82 for IBM camera */
int has_hdr;
int frame_num;
int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */
/* Statistics that can be overlayed on screen */
unsigned long urb_count; /* How many URBs we received so far */
unsigned long urb_length; /* Length of last URB */
unsigned long data_count; /* How many bytes we received */
unsigned long header_count; /* How many frame headers we found */
unsigned long scratch_ovf_count;/* How many times we overflowed scratch */
unsigned long iso_skip_count; /* How many empty ISO packets received */
unsigned long iso_err_count; /* How many bad ISO packets received */
};
#endif /* __LINUX_IBMCAM_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment