brintos

brintos / linux-shallow public Read only

0
0
Text · 7.4 KiB · bc6133b Raw
294 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Fujifilm Finepix subdriver4 *5 * Copyright (C) 2008 Frank Zago6 */7 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt9 10#define MODULE_NAME "finepix"11 12#include "gspca.h"13 14MODULE_AUTHOR("Frank Zago <frank@zago.net>");15MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");16MODULE_LICENSE("GPL");17 18/* Default timeout, in ms */19#define FPIX_TIMEOUT 25020 21/* Maximum transfer size to use. The windows driver reads by chunks of22 * 0x2000 bytes, so do the same. Note: reading more seems to work23 * too. */24#define FPIX_MAX_TRANSFER 0x200025 26/* Structure to hold all of our device specific stuff */27struct usb_fpix {28	struct gspca_dev gspca_dev;	/* !! must be the first item */29 30	struct work_struct work_struct;31};32 33/* Delay after which claim the next frame. If the delay is too small,34 * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms35 * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,36 * 30ms is bad while 35ms is perfect. */37#define NEXT_FRAME_DELAY 3538 39/* These cameras only support 320x200. */40static const struct v4l2_pix_format fpix_mode[1] = {41	{ 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,42		.bytesperline = 320,43		.sizeimage = 320 * 240 * 3 / 8 + 590,44		.colorspace = V4L2_COLORSPACE_SRGB,45		.priv = 0}46};47 48/* send a command to the webcam */49static int command(struct gspca_dev *gspca_dev,50		int order)	/* 0: reset, 1: frame request */51{52	static u8 order_values[2][12] = {53		{0xc6, 0, 0, 0, 0, 0, 0,    0, 0x20, 0, 0, 0},	/* reset */54		{0xd3, 0, 0, 0, 0, 0, 0, 0x01,    0, 0, 0, 0},	/* fr req */55	};56 57	memcpy(gspca_dev->usb_buf, order_values[order], 12);58	return usb_control_msg(gspca_dev->dev,59			usb_sndctrlpipe(gspca_dev->dev, 0),60			USB_REQ_GET_STATUS,61			USB_DIR_OUT | USB_TYPE_CLASS |62			USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,63			12, FPIX_TIMEOUT);64}65 66/*67 * This function is called as a workqueue function and runs whenever the camera68 * is streaming data. Because it is a workqueue function it is allowed to sleep69 * so we can use synchronous USB calls. To avoid possible collisions with other70 * threads attempting to use gspca_dev->usb_buf we take the usb_lock when71 * performing USB operations using it. In practice we don't really need this72 * as the camera doesn't provide any controls.73 */74static void dostream(struct work_struct *work)75{76	struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);77	struct gspca_dev *gspca_dev = &dev->gspca_dev;78	struct urb *urb = gspca_dev->urb[0];79	u8 *data = urb->transfer_buffer;80	int ret = 0;81	int len;82 83	gspca_dbg(gspca_dev, D_STREAM, "dostream started\n");84 85	/* loop reading a frame */86again:87	while (gspca_dev->present && gspca_dev->streaming) {88#ifdef CONFIG_PM89		if (gspca_dev->frozen)90			break;91#endif92 93		/* request a frame */94		mutex_lock(&gspca_dev->usb_lock);95		ret = command(gspca_dev, 1);96		mutex_unlock(&gspca_dev->usb_lock);97		if (ret < 0)98			break;99#ifdef CONFIG_PM100		if (gspca_dev->frozen)101			break;102#endif103		if (!gspca_dev->present || !gspca_dev->streaming)104			break;105 106		/* the frame comes in parts */107		for (;;) {108			ret = usb_bulk_msg(gspca_dev->dev,109					urb->pipe,110					data,111					FPIX_MAX_TRANSFER,112					&len, FPIX_TIMEOUT);113			if (ret < 0) {114				/* Most of the time we get a timeout115				 * error. Just restart. */116				goto again;117			}118#ifdef CONFIG_PM119			if (gspca_dev->frozen)120				goto out;121#endif122			if (!gspca_dev->present || !gspca_dev->streaming)123				goto out;124			if (len < FPIX_MAX_TRANSFER ||125				(data[len - 2] == 0xff &&126					data[len - 1] == 0xd9)) {127 128				/* If the result is less than what was asked129				 * for, then it's the end of the130				 * frame. Sometimes the jpeg is not complete,131				 * but there's nothing we can do. We also end132				 * here if the jpeg ends right at the end133				 * of the frame. */134				gspca_frame_add(gspca_dev, LAST_PACKET,135						data, len);136				break;137			}138 139			/* got a partial image */140			gspca_frame_add(gspca_dev,141					gspca_dev->last_packet_type142						== LAST_PACKET143					? FIRST_PACKET : INTER_PACKET,144					data, len);145		}146 147		/* We must wait before trying reading the next148		 * frame. If we don't, or if the delay is too short,149		 * the camera will disconnect. */150		msleep(NEXT_FRAME_DELAY);151	}152 153out:154	gspca_dbg(gspca_dev, D_STREAM, "dostream stopped\n");155}156 157/* this function is called at probe time */158static int sd_config(struct gspca_dev *gspca_dev,159		const struct usb_device_id *id)160{161	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;162	struct cam *cam = &gspca_dev->cam;163 164	cam->cam_mode = fpix_mode;165	cam->nmodes = 1;166	cam->bulk = 1;167	cam->bulk_size = FPIX_MAX_TRANSFER;168 169	INIT_WORK(&dev->work_struct, dostream);170 171	return 0;172}173 174/* this function is called at probe and resume time */175static int sd_init(struct gspca_dev *gspca_dev)176{177	return 0;178}179 180/* start the camera */181static int sd_start(struct gspca_dev *gspca_dev)182{183	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;184	int ret, len;185 186	/* Init the device */187	ret = command(gspca_dev, 0);188	if (ret < 0) {189		pr_err("init failed %d\n", ret);190		return ret;191	}192 193	/* Read the result of the command. Ignore the result, for it194	 * varies with the device. */195	ret = usb_bulk_msg(gspca_dev->dev,196			gspca_dev->urb[0]->pipe,197			gspca_dev->urb[0]->transfer_buffer,198			FPIX_MAX_TRANSFER, &len,199			FPIX_TIMEOUT);200	if (ret < 0) {201		pr_err("usb_bulk_msg failed %d\n", ret);202		return ret;203	}204 205	/* Request a frame, but don't read it */206	ret = command(gspca_dev, 1);207	if (ret < 0) {208		pr_err("frame request failed %d\n", ret);209		return ret;210	}211 212	/* Again, reset bulk in endpoint */213	usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);214 215	schedule_work(&dev->work_struct);216 217	return 0;218}219 220/* called on streamoff with alt==0 and on disconnect */221/* the usb_lock is held at entry - restore on exit */222static void sd_stop0(struct gspca_dev *gspca_dev)223{224	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;225 226	/* wait for the work queue to terminate */227	mutex_unlock(&gspca_dev->usb_lock);228	flush_work(&dev->work_struct);229	mutex_lock(&gspca_dev->usb_lock);230}231 232/* Table of supported USB devices */233static const struct usb_device_id device_table[] = {234	{USB_DEVICE(0x04cb, 0x0104)},235	{USB_DEVICE(0x04cb, 0x0109)},236	{USB_DEVICE(0x04cb, 0x010b)},237	{USB_DEVICE(0x04cb, 0x010f)},238	{USB_DEVICE(0x04cb, 0x0111)},239	{USB_DEVICE(0x04cb, 0x0113)},240	{USB_DEVICE(0x04cb, 0x0115)},241	{USB_DEVICE(0x04cb, 0x0117)},242	{USB_DEVICE(0x04cb, 0x0119)},243	{USB_DEVICE(0x04cb, 0x011b)},244	{USB_DEVICE(0x04cb, 0x011d)},245	{USB_DEVICE(0x04cb, 0x0121)},246	{USB_DEVICE(0x04cb, 0x0123)},247	{USB_DEVICE(0x04cb, 0x0125)},248	{USB_DEVICE(0x04cb, 0x0127)},249	{USB_DEVICE(0x04cb, 0x0129)},250	{USB_DEVICE(0x04cb, 0x012b)},251	{USB_DEVICE(0x04cb, 0x012d)},252	{USB_DEVICE(0x04cb, 0x012f)},253	{USB_DEVICE(0x04cb, 0x0131)},254	{USB_DEVICE(0x04cb, 0x013b)},255	{USB_DEVICE(0x04cb, 0x013d)},256	{USB_DEVICE(0x04cb, 0x013f)},257	{}258};259 260MODULE_DEVICE_TABLE(usb, device_table);261 262/* sub-driver description */263static const struct sd_desc sd_desc = {264	.name   = MODULE_NAME,265	.config = sd_config,266	.init   = sd_init,267	.start  = sd_start,268	.stop0  = sd_stop0,269};270 271/* -- device connect -- */272static int sd_probe(struct usb_interface *intf,273		const struct usb_device_id *id)274{275	return gspca_dev_probe(intf, id,276			&sd_desc,277			sizeof(struct usb_fpix),278			THIS_MODULE);279}280 281static struct usb_driver sd_driver = {282	.name       = MODULE_NAME,283	.id_table   = device_table,284	.probe      = sd_probe,285	.disconnect = gspca_disconnect,286#ifdef CONFIG_PM287	.suspend = gspca_suspend,288	.resume  = gspca_resume,289	.reset_resume = gspca_resume,290#endif291};292 293module_usb_driver(sd_driver);294