197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* 297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * Fujifilm Finepix subdriver 397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * 497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * Copyright (C) 2008 Frank Zago 597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * 697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * This program is free software; you can redistribute it and/or modify 797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * it under the terms of the GNU General Public License as published by 897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * the Free Software Foundation; either version 2 of the License, or 997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * any later version. 1097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * 1197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * This program is distributed in the hope that it will be useful, 1297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * but WITHOUT ANY WARRANTY; without even the implied warranty of 1397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * GNU General Public License for more details. 1597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * 1697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * You should have received a copy of the GNU General Public License 1797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * along with this program; if not, write to the Free Software 1897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago */ 2097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 2170a429954799bbf71f87abf12aaa35bf52cd9913Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2270a429954799bbf71f87abf12aaa35bf52cd9913Joe Perches 2397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago#define MODULE_NAME "finepix" 2497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 2597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago#include "gspca.h" 2697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 2797076859590ada76dc4bee46b6ccad86d89e82cfFrank ZagoMODULE_AUTHOR("Frank Zago <frank@zago.net>"); 2897076859590ada76dc4bee46b6ccad86d89e82cfFrank ZagoMODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver"); 2997076859590ada76dc4bee46b6ccad86d89e82cfFrank ZagoMODULE_LICENSE("GPL"); 3097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 3197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* Default timeout, in ms */ 32c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine#define FPIX_TIMEOUT 250 3397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 3497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* Maximum transfer size to use. The windows driver reads by chunks of 3597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * 0x2000 bytes, so do the same. Note: reading more seems to work 3697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * too. */ 3797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago#define FPIX_MAX_TRANSFER 0x2000 3897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 3997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* Structure to hold all of our device specific stuff */ 4097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zagostruct usb_fpix { 4197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago struct gspca_dev gspca_dev; /* !! must be the first item */ 4297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 43c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine struct work_struct work_struct; 44c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine struct workqueue_struct *work_thread; 4597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago}; 4697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 4797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* Delay after which claim the next frame. If the delay is too small, 4897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms 49c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * will fail every 4 or 5 frames, but 30ms is perfect. On the A210, 50c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * 30ms is bad while 35ms is perfect. */ 51c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine#define NEXT_FRAME_DELAY 35 5297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 5397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* These cameras only support 320x200. */ 54cc611b8aef7a8a9a2e614f1bdf3e2b8f066c8c8dJean-Francois Moinestatic const struct v4l2_pix_format fpix_mode[1] = { 5597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 5697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago .bytesperline = 320, 5797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago .sizeimage = 320 * 240 * 3 / 8 + 590, 5897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago .colorspace = V4L2_COLORSPACE_SRGB, 5997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago .priv = 0} 6097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago}; 6197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 62c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine/* send a command to the webcam */ 63c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moinestatic int command(struct gspca_dev *gspca_dev, 64c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine int order) /* 0: reset, 1: frame request */ 6597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago{ 66c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine static u8 order_values[2][12] = { 67c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine {0xc6, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0}, /* reset */ 68c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine {0xd3, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}, /* fr req */ 69c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine }; 7097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 71c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine memcpy(gspca_dev->usb_buf, order_values[order], 12); 72c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine return usb_control_msg(gspca_dev->dev, 73c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine usb_sndctrlpipe(gspca_dev->dev, 0), 74c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine USB_REQ_GET_STATUS, 75c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine USB_DIR_OUT | USB_TYPE_CLASS | 76c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf, 77c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine 12, FPIX_TIMEOUT); 7897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago} 7997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 80c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine/* workqueue */ 81c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moinestatic void dostream(struct work_struct *work) 8297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago{ 83c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct); 84c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine struct gspca_dev *gspca_dev = &dev->gspca_dev; 85c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine struct urb *urb = gspca_dev->urb[0]; 86c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine u8 *data = urb->transfer_buffer; 87c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine int ret = 0; 88c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine int len; 89c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine 90c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* synchronize with the main driver */ 91c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine mutex_lock(&gspca_dev->usb_lock); 92c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine mutex_unlock(&gspca_dev->usb_lock); 93c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine PDEBUG(D_STREAM, "dostream started"); 94c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine 95c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* loop reading a frame */ 96c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moineagain: 97c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine while (gspca_dev->present && gspca_dev->streaming) { 98c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine 99c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* request a frame */ 100c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine mutex_lock(&gspca_dev->usb_lock); 101c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine ret = command(gspca_dev, 1); 102c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine mutex_unlock(&gspca_dev->usb_lock); 103c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine if (ret < 0) 104c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine break; 105c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine if (!gspca_dev->present || !gspca_dev->streaming) 106c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine break; 107c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine 108c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* the frame comes in parts */ 109c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine for (;;) { 110c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine ret = usb_bulk_msg(gspca_dev->dev, 111c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine urb->pipe, 112c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine data, 113c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine FPIX_MAX_TRANSFER, 114c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine &len, FPIX_TIMEOUT); 115c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine if (ret < 0) { 116c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* Most of the time we get a timeout 117c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * error. Just restart. */ 118c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine goto again; 119c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine } 120c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine if (!gspca_dev->present || !gspca_dev->streaming) 121c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine goto out; 122c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine if (len < FPIX_MAX_TRANSFER || 123c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine (data[len - 2] == 0xff && 124c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine data[len - 1] == 0xd9)) { 125c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine 126c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* If the result is less than what was asked 127c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * for, then it's the end of the 128c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * frame. Sometimes the jpeg is not complete, 129c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * but there's nothing we can do. We also end 130c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * here if the the jpeg ends right at the end 131c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * of the frame. */ 13276dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, LAST_PACKET, 13376dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine data, len); 134c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine break; 135c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine } 13697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 13797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago /* got a partial image */ 13876dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_frame_add(gspca_dev, 13976dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine gspca_dev->last_packet_type 14076dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine == LAST_PACKET 14176dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine ? FIRST_PACKET : INTER_PACKET, 14276dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine data, len); 14397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago } 14497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 145c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* We must wait before trying reading the next 146c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * frame. If we don't, or if the delay is too short, 147c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine * the camera will disconnect. */ 148c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine msleep(NEXT_FRAME_DELAY); 14997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago } 15097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 151c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moineout: 152c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine PDEBUG(D_STREAM, "dostream stopped"); 15397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago} 15497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 15597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* this function is called at probe time */ 15697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zagostatic int sd_config(struct gspca_dev *gspca_dev, 15797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago const struct usb_device_id *id) 15897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago{ 159c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; 16097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago struct cam *cam = &gspca_dev->cam; 16197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 16297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago cam->cam_mode = fpix_mode; 16397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago cam->nmodes = 1; 1646929dc6b30dc3a6c9c411f677a11b866e8dd28aaJean-Francois Moine cam->bulk = 1; 16597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago cam->bulk_size = FPIX_MAX_TRANSFER; 16697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 167c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine INIT_WORK(&dev->work_struct, dostream); 16897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 169c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine return 0; 17097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago} 17197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 17297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* this function is called at probe and resume time */ 17397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zagostatic int sd_init(struct gspca_dev *gspca_dev) 17497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago{ 17597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago return 0; 17697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago} 17797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 178c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine/* start the camera */ 17997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zagostatic int sd_start(struct gspca_dev *gspca_dev) 18097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago{ 18197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; 182c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine int ret, len; 18397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 18497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago /* Init the device */ 185c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine ret = command(gspca_dev, 0); 186c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine if (ret < 0) { 18770a429954799bbf71f87abf12aaa35bf52cd9913Joe Perches pr_err("init failed %d\n", ret); 188c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine return ret; 18997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago } 19097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 19197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago /* Read the result of the command. Ignore the result, for it 19297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago * varies with the device. */ 19397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago ret = usb_bulk_msg(gspca_dev->dev, 19450e06dee958bdb81229cb42486f7fdc4917fa4daJean-Francois Moine gspca_dev->urb[0]->pipe, 195c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine gspca_dev->urb[0]->transfer_buffer, 196c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine FPIX_MAX_TRANSFER, &len, 19797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago FPIX_TIMEOUT); 198c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine if (ret < 0) { 19970a429954799bbf71f87abf12aaa35bf52cd9913Joe Perches pr_err("usb_bulk_msg failed %d\n", ret); 200c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine return ret; 20197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago } 20297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 20397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago /* Request a frame, but don't read it */ 204c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine ret = command(gspca_dev, 1); 205c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine if (ret < 0) { 20670a429954799bbf71f87abf12aaa35bf52cd9913Joe Perches pr_err("frame request failed %d\n", ret); 207c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine return ret; 20897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago } 20997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 21097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago /* Again, reset bulk in endpoint */ 21150e06dee958bdb81229cb42486f7fdc4917fa4daJean-Francois Moine usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe); 21297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 213c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* Start the workqueue function to do the streaming */ 214c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine dev->work_thread = create_singlethread_workqueue(MODULE_NAME); 215c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine queue_work(dev->work_thread, &dev->work_struct); 21697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 21797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago return 0; 218c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine} 219c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine 220c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine/* called on streamoff with alt==0 and on disconnect */ 221c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine/* the usb_lock is held at entry - restore on exit */ 222c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moinestatic void sd_stop0(struct gspca_dev *gspca_dev) 223c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine{ 224c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine struct usb_fpix *dev = (struct usb_fpix *) gspca_dev; 22597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 226c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine /* wait for the work queue to terminate */ 227c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine mutex_unlock(&gspca_dev->usb_lock); 228c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine destroy_workqueue(dev->work_thread); 229c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine mutex_lock(&gspca_dev->usb_lock); 230c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine dev->work_thread = NULL; 23197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago} 23297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 23397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* Table of supported USB devices */ 23495c967c167785eb991cf6b22fb854dd8d61d0ff8Jean-François Moinestatic const struct usb_device_id device_table[] = { 23597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0104)}, 23697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0109)}, 23797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x010b)}, 23897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x010f)}, 23997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0111)}, 24097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0113)}, 24197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0115)}, 24297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0117)}, 24397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0119)}, 24497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x011b)}, 24597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x011d)}, 24697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0121)}, 24797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0123)}, 24897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0125)}, 24997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0127)}, 25097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0129)}, 25197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x012b)}, 25297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x012d)}, 25397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x012f)}, 25497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x0131)}, 25597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x013b)}, 25697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x013d)}, 25797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {USB_DEVICE(0x04cb, 0x013f)}, 25897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago {} 25997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago}; 26097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 26197076859590ada76dc4bee46b6ccad86d89e82cfFrank ZagoMODULE_DEVICE_TABLE(usb, device_table); 26297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 26397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* sub-driver description */ 26497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zagostatic const struct sd_desc sd_desc = { 265c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine .name = MODULE_NAME, 26697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago .config = sd_config, 267c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine .init = sd_init, 268c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine .start = sd_start, 269c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine .stop0 = sd_stop0, 27097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago}; 27197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 27297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago/* -- device connect -- */ 27397076859590ada76dc4bee46b6ccad86d89e82cfFrank Zagostatic int sd_probe(struct usb_interface *intf, 27497076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago const struct usb_device_id *id) 27597076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago{ 27697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago return gspca_dev_probe(intf, id, 27797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago &sd_desc, 27897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago sizeof(struct usb_fpix), 27997076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago THIS_MODULE); 28097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago} 28197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 28297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zagostatic struct usb_driver sd_driver = { 283c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine .name = MODULE_NAME, 284c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine .id_table = device_table, 285c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine .probe = sd_probe, 28697076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago .disconnect = gspca_disconnect, 28797076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago#ifdef CONFIG_PM 28897076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago .suspend = gspca_suspend, 289c0c4c8937a7e84ab366ed8d8ea8855b57cb698dfJean-Francois Moine .resume = gspca_resume, 29097076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago#endif 29197076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago}; 29297076859590ada76dc4bee46b6ccad86d89e82cfFrank Zago 293ecb3b2b35db49778b6d89e3ffd0c400776c20735Greg Kroah-Hartmanmodule_usb_driver(sd_driver); 294