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