MODULE_AUTHOR("Frank Zago ");
MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");
MODULE_LICENSE("GPL");
/* Default timeout, in ms */ #define FPIX_TIMEOUT 250
/* Maximum transfer size to use. The windows driver reads by chunks of * 0x2000 bytes, so do the same. Note: reading more seems to work
* too. */ #define FPIX_MAX_TRANSFER 0x2000
/* Structure to hold all of our device specific stuff */ struct usb_fpix { struct gspca_dev gspca_dev; /* !! must be the first item */
struct work_struct work_struct;
};
/* Delay after which claim the next frame. If the delay is too small, * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,
* 30ms is bad while 35ms is perfect. */ #define NEXT_FRAME_DELAY 35
/* * This function is called as a workqueue function and runs whenever the camera * is streaming data. Because it is a workqueue function it is allowed to sleep * so we can use synchronous USB calls. To avoid possible collisions with other * threads attempting to use gspca_dev->usb_buf we take the usb_lock when * performing USB operations using it. In practice we don't really need this * as the camera doesn't provide any controls.
*/ staticvoid dostream(struct work_struct *work)
{ struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct); struct gspca_dev *gspca_dev = &dev->gspca_dev; struct urb *urb = gspca_dev->urb[0];
u8 *data = urb->transfer_buffer; int ret = 0; int len;
/* loop reading a frame */
again: while (gspca_dev->present && gspca_dev->streaming) { #ifdef CONFIG_PM if (gspca_dev->frozen) break; #endif
/* request a frame */
mutex_lock(&gspca_dev->usb_lock);
ret = command(gspca_dev, 1);
mutex_unlock(&gspca_dev->usb_lock); if (ret < 0) break; #ifdef CONFIG_PM if (gspca_dev->frozen) break; #endif if (!gspca_dev->present || !gspca_dev->streaming) break;
/* the frame comes in parts */ for (;;) {
ret = usb_bulk_msg(gspca_dev->dev,
urb->pipe,
data,
FPIX_MAX_TRANSFER,
&len, FPIX_TIMEOUT); if (ret < 0) { /* Most of the time we get a timeout
* error. Just restart. */ goto again;
} #ifdef CONFIG_PM if (gspca_dev->frozen) goto out; #endif if (!gspca_dev->present || !gspca_dev->streaming) goto out; if (len < FPIX_MAX_TRANSFER ||
(data[len - 2] == 0xff &&
data[len - 1] == 0xd9)) {
/* If the result is less than what was asked * for, then it's the end of the * frame. Sometimes the jpeg is not complete, * but there's nothing we can do. We also end * here if the jpeg ends right at the end
* of the frame. */
gspca_frame_add(gspca_dev, LAST_PACKET,
data, len); break;
}
/* We must wait before trying reading the next * frame. If we don't, or if the delay is too short,
* the camera will disconnect. */
msleep(NEXT_FRAME_DELAY);
}
/* this function is called at probe time */ staticint sd_config(struct gspca_dev *gspca_dev, conststruct usb_device_id *id)
{ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; struct cam *cam = &gspca_dev->cam;
/* this function is called at probe and resume time */ staticint sd_init(struct gspca_dev *gspca_dev)
{ return 0;
}
/* start the camera */ staticint sd_start(struct gspca_dev *gspca_dev)
{ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; int ret, len;
/* Init the device */
ret = command(gspca_dev, 0); if (ret < 0) {
pr_err("init failed %d\n", ret); return ret;
}
/* Read the result of the command. Ignore the result, for it
* varies with the device. */
ret = usb_bulk_msg(gspca_dev->dev,
gspca_dev->urb[0]->pipe,
gspca_dev->urb[0]->transfer_buffer,
FPIX_MAX_TRANSFER, &len,
FPIX_TIMEOUT); if (ret < 0) {
pr_err("usb_bulk_msg failed %d\n", ret); return ret;
}
/* Request a frame, but don't read it */
ret = command(gspca_dev, 1); if (ret < 0) {
pr_err("frame request failed %d\n", ret); return ret;
}
/* Again, reset bulk in endpoint */
usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
schedule_work(&dev->work_struct);
return 0;
}
/* called on streamoff with alt==0 and on disconnect */ /* the usb_lock is held at entry - restore on exit */ staticvoid sd_stop0(struct gspca_dev *gspca_dev)
{ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
/* wait for the work queue to terminate */
mutex_unlock(&gspca_dev->usb_lock);
flush_work(&dev->work_struct);
mutex_lock(&gspca_dev->usb_lock);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.