Path: blob/master/drivers/media/video/gspca/finepix.c
17633 views
/*1* Fujifilm Finepix subdriver2*3* Copyright (C) 2008 Frank Zago4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License16* along with this program; if not, write to the Free Software17* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18*/1920#define MODULE_NAME "finepix"2122#include "gspca.h"2324MODULE_AUTHOR("Frank Zago <[email protected]>");25MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");26MODULE_LICENSE("GPL");2728/* Default timeout, in ms */29#define FPIX_TIMEOUT 2503031/* Maximum transfer size to use. The windows driver reads by chunks of32* 0x2000 bytes, so do the same. Note: reading more seems to work33* too. */34#define FPIX_MAX_TRANSFER 0x20003536/* Structure to hold all of our device specific stuff */37struct usb_fpix {38struct gspca_dev gspca_dev; /* !! must be the first item */3940struct work_struct work_struct;41struct workqueue_struct *work_thread;42};4344/* Delay after which claim the next frame. If the delay is too small,45* the camera will return old frames. On the 4800Z, 20ms is bad, 25ms46* will fail every 4 or 5 frames, but 30ms is perfect. On the A210,47* 30ms is bad while 35ms is perfect. */48#define NEXT_FRAME_DELAY 354950/* These cameras only support 320x200. */51static const struct v4l2_pix_format fpix_mode[1] = {52{ 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,53.bytesperline = 320,54.sizeimage = 320 * 240 * 3 / 8 + 590,55.colorspace = V4L2_COLORSPACE_SRGB,56.priv = 0}57};5859/* send a command to the webcam */60static int command(struct gspca_dev *gspca_dev,61int order) /* 0: reset, 1: frame request */62{63static u8 order_values[2][12] = {64{0xc6, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0}, /* reset */65{0xd3, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}, /* fr req */66};6768memcpy(gspca_dev->usb_buf, order_values[order], 12);69return usb_control_msg(gspca_dev->dev,70usb_sndctrlpipe(gspca_dev->dev, 0),71USB_REQ_GET_STATUS,72USB_DIR_OUT | USB_TYPE_CLASS |73USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,7412, FPIX_TIMEOUT);75}7677/* workqueue */78static void dostream(struct work_struct *work)79{80struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);81struct gspca_dev *gspca_dev = &dev->gspca_dev;82struct urb *urb = gspca_dev->urb[0];83u8 *data = urb->transfer_buffer;84int ret = 0;85int len;8687/* synchronize with the main driver */88mutex_lock(&gspca_dev->usb_lock);89mutex_unlock(&gspca_dev->usb_lock);90PDEBUG(D_STREAM, "dostream started");9192/* loop reading a frame */93again:94while (gspca_dev->present && gspca_dev->streaming) {9596/* request a frame */97mutex_lock(&gspca_dev->usb_lock);98ret = command(gspca_dev, 1);99mutex_unlock(&gspca_dev->usb_lock);100if (ret < 0)101break;102if (!gspca_dev->present || !gspca_dev->streaming)103break;104105/* the frame comes in parts */106for (;;) {107ret = usb_bulk_msg(gspca_dev->dev,108urb->pipe,109data,110FPIX_MAX_TRANSFER,111&len, FPIX_TIMEOUT);112if (ret < 0) {113/* Most of the time we get a timeout114* error. Just restart. */115goto again;116}117if (!gspca_dev->present || !gspca_dev->streaming)118goto out;119if (len < FPIX_MAX_TRANSFER ||120(data[len - 2] == 0xff &&121data[len - 1] == 0xd9)) {122123/* If the result is less than what was asked124* for, then it's the end of the125* frame. Sometimes the jpeg is not complete,126* but there's nothing we can do. We also end127* here if the the jpeg ends right at the end128* of the frame. */129gspca_frame_add(gspca_dev, LAST_PACKET,130data, len);131break;132}133134/* got a partial image */135gspca_frame_add(gspca_dev,136gspca_dev->last_packet_type137== LAST_PACKET138? FIRST_PACKET : INTER_PACKET,139data, len);140}141142/* We must wait before trying reading the next143* frame. If we don't, or if the delay is too short,144* the camera will disconnect. */145msleep(NEXT_FRAME_DELAY);146}147148out:149PDEBUG(D_STREAM, "dostream stopped");150}151152/* this function is called at probe time */153static int sd_config(struct gspca_dev *gspca_dev,154const struct usb_device_id *id)155{156struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;157struct cam *cam = &gspca_dev->cam;158159cam->cam_mode = fpix_mode;160cam->nmodes = 1;161cam->bulk = 1;162cam->bulk_size = FPIX_MAX_TRANSFER;163164INIT_WORK(&dev->work_struct, dostream);165166return 0;167}168169/* this function is called at probe and resume time */170static int sd_init(struct gspca_dev *gspca_dev)171{172return 0;173}174175/* start the camera */176static int sd_start(struct gspca_dev *gspca_dev)177{178struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;179int ret, len;180181/* Init the device */182ret = command(gspca_dev, 0);183if (ret < 0) {184err("init failed %d", ret);185return ret;186}187188/* Read the result of the command. Ignore the result, for it189* varies with the device. */190ret = usb_bulk_msg(gspca_dev->dev,191gspca_dev->urb[0]->pipe,192gspca_dev->urb[0]->transfer_buffer,193FPIX_MAX_TRANSFER, &len,194FPIX_TIMEOUT);195if (ret < 0) {196err("usb_bulk_msg failed %d", ret);197return ret;198}199200/* Request a frame, but don't read it */201ret = command(gspca_dev, 1);202if (ret < 0) {203err("frame request failed %d", ret);204return ret;205}206207/* Again, reset bulk in endpoint */208usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);209210/* Start the workqueue function to do the streaming */211dev->work_thread = create_singlethread_workqueue(MODULE_NAME);212queue_work(dev->work_thread, &dev->work_struct);213214return 0;215}216217/* called on streamoff with alt==0 and on disconnect */218/* the usb_lock is held at entry - restore on exit */219static void sd_stop0(struct gspca_dev *gspca_dev)220{221struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;222223/* wait for the work queue to terminate */224mutex_unlock(&gspca_dev->usb_lock);225destroy_workqueue(dev->work_thread);226mutex_lock(&gspca_dev->usb_lock);227dev->work_thread = NULL;228}229230/* Table of supported USB devices */231static const struct usb_device_id device_table[] = {232{USB_DEVICE(0x04cb, 0x0104)},233{USB_DEVICE(0x04cb, 0x0109)},234{USB_DEVICE(0x04cb, 0x010b)},235{USB_DEVICE(0x04cb, 0x010f)},236{USB_DEVICE(0x04cb, 0x0111)},237{USB_DEVICE(0x04cb, 0x0113)},238{USB_DEVICE(0x04cb, 0x0115)},239{USB_DEVICE(0x04cb, 0x0117)},240{USB_DEVICE(0x04cb, 0x0119)},241{USB_DEVICE(0x04cb, 0x011b)},242{USB_DEVICE(0x04cb, 0x011d)},243{USB_DEVICE(0x04cb, 0x0121)},244{USB_DEVICE(0x04cb, 0x0123)},245{USB_DEVICE(0x04cb, 0x0125)},246{USB_DEVICE(0x04cb, 0x0127)},247{USB_DEVICE(0x04cb, 0x0129)},248{USB_DEVICE(0x04cb, 0x012b)},249{USB_DEVICE(0x04cb, 0x012d)},250{USB_DEVICE(0x04cb, 0x012f)},251{USB_DEVICE(0x04cb, 0x0131)},252{USB_DEVICE(0x04cb, 0x013b)},253{USB_DEVICE(0x04cb, 0x013d)},254{USB_DEVICE(0x04cb, 0x013f)},255{}256};257258MODULE_DEVICE_TABLE(usb, device_table);259260/* sub-driver description */261static const struct sd_desc sd_desc = {262.name = MODULE_NAME,263.config = sd_config,264.init = sd_init,265.start = sd_start,266.stop0 = sd_stop0,267};268269/* -- device connect -- */270static int sd_probe(struct usb_interface *intf,271const struct usb_device_id *id)272{273return gspca_dev_probe(intf, id,274&sd_desc,275sizeof(struct usb_fpix),276THIS_MODULE);277}278279static struct usb_driver sd_driver = {280.name = MODULE_NAME,281.id_table = device_table,282.probe = sd_probe,283.disconnect = gspca_disconnect,284#ifdef CONFIG_PM285.suspend = gspca_suspend,286.resume = gspca_resume,287#endif288};289290/* -- module insert / remove -- */291static int __init sd_mod_init(void)292{293return usb_register(&sd_driver);294}295296static void __exit sd_mod_exit(void)297{298usb_deregister(&sd_driver);299}300301module_init(sd_mod_init);302module_exit(sd_mod_exit);303304305