MODULE_AUTHOR("Frank Zago <frank@zago.net>");
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 *0x2000bytes,sodothesame.Note:readingmoreseemstowork
* 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, *thecamerawillreturnoldframes.Onthe4800Z,20msisbad,25ms *willfailevery4or5frames,but30msisperfect.OntheA210,
* 30ms is bad while 35ms is perfect. */ #define NEXT_FRAME_DELAY 35
/* 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,thenit'stheendofthe *frame.Sometimesthejpegisnotcomplete, *butthere'snothingwecando.Wealsoend *hereifthejpegendsrightattheend
* of the frame. */
gspca_frame_add(gspca_dev, LAST_PACKET,
data, len); break;
}
/* 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)
{ return0;
}
/* 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);
return0;
}
/* 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.