xref: /linux/drivers/media/usb/gspca/finepix.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1fd9871f7SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
20c0d06caSMauro Carvalho Chehab /*
30c0d06caSMauro Carvalho Chehab  * Fujifilm Finepix subdriver
40c0d06caSMauro Carvalho Chehab  *
50c0d06caSMauro Carvalho Chehab  * Copyright (C) 2008 Frank Zago
60c0d06caSMauro Carvalho Chehab  */
70c0d06caSMauro Carvalho Chehab 
80c0d06caSMauro Carvalho Chehab #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
90c0d06caSMauro Carvalho Chehab 
100c0d06caSMauro Carvalho Chehab #define MODULE_NAME "finepix"
110c0d06caSMauro Carvalho Chehab 
120c0d06caSMauro Carvalho Chehab #include "gspca.h"
130c0d06caSMauro Carvalho Chehab 
140c0d06caSMauro Carvalho Chehab MODULE_AUTHOR("Frank Zago <frank@zago.net>");
150c0d06caSMauro Carvalho Chehab MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");
160c0d06caSMauro Carvalho Chehab MODULE_LICENSE("GPL");
170c0d06caSMauro Carvalho Chehab 
180c0d06caSMauro Carvalho Chehab /* Default timeout, in ms */
190c0d06caSMauro Carvalho Chehab #define FPIX_TIMEOUT 250
200c0d06caSMauro Carvalho Chehab 
210c0d06caSMauro Carvalho Chehab /* Maximum transfer size to use. The windows driver reads by chunks of
220c0d06caSMauro Carvalho Chehab  * 0x2000 bytes, so do the same. Note: reading more seems to work
230c0d06caSMauro Carvalho Chehab  * too. */
240c0d06caSMauro Carvalho Chehab #define FPIX_MAX_TRANSFER 0x2000
250c0d06caSMauro Carvalho Chehab 
260c0d06caSMauro Carvalho Chehab /* Structure to hold all of our device specific stuff */
270c0d06caSMauro Carvalho Chehab struct usb_fpix {
280c0d06caSMauro Carvalho Chehab 	struct gspca_dev gspca_dev;	/* !! must be the first item */
290c0d06caSMauro Carvalho Chehab 
300c0d06caSMauro Carvalho Chehab 	struct work_struct work_struct;
310c0d06caSMauro Carvalho Chehab };
320c0d06caSMauro Carvalho Chehab 
330c0d06caSMauro Carvalho Chehab /* Delay after which claim the next frame. If the delay is too small,
340c0d06caSMauro Carvalho Chehab  * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms
350c0d06caSMauro Carvalho Chehab  * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,
360c0d06caSMauro Carvalho Chehab  * 30ms is bad while 35ms is perfect. */
370c0d06caSMauro Carvalho Chehab #define NEXT_FRAME_DELAY 35
380c0d06caSMauro Carvalho Chehab 
390c0d06caSMauro Carvalho Chehab /* These cameras only support 320x200. */
400c0d06caSMauro Carvalho Chehab static const struct v4l2_pix_format fpix_mode[1] = {
410c0d06caSMauro Carvalho Chehab 	{ 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
420c0d06caSMauro Carvalho Chehab 		.bytesperline = 320,
430c0d06caSMauro Carvalho Chehab 		.sizeimage = 320 * 240 * 3 / 8 + 590,
440c0d06caSMauro Carvalho Chehab 		.colorspace = V4L2_COLORSPACE_SRGB,
450c0d06caSMauro Carvalho Chehab 		.priv = 0}
460c0d06caSMauro Carvalho Chehab };
470c0d06caSMauro Carvalho Chehab 
480c0d06caSMauro Carvalho Chehab /* send a command to the webcam */
command(struct gspca_dev * gspca_dev,int order)490c0d06caSMauro Carvalho Chehab static int command(struct gspca_dev *gspca_dev,
500c0d06caSMauro Carvalho Chehab 		int order)	/* 0: reset, 1: frame request */
510c0d06caSMauro Carvalho Chehab {
520c0d06caSMauro Carvalho Chehab 	static u8 order_values[2][12] = {
530c0d06caSMauro Carvalho Chehab 		{0xc6, 0, 0, 0, 0, 0, 0,    0, 0x20, 0, 0, 0},	/* reset */
540c0d06caSMauro Carvalho Chehab 		{0xd3, 0, 0, 0, 0, 0, 0, 0x01,    0, 0, 0, 0},	/* fr req */
550c0d06caSMauro Carvalho Chehab 	};
560c0d06caSMauro Carvalho Chehab 
570c0d06caSMauro Carvalho Chehab 	memcpy(gspca_dev->usb_buf, order_values[order], 12);
580c0d06caSMauro Carvalho Chehab 	return usb_control_msg(gspca_dev->dev,
590c0d06caSMauro Carvalho Chehab 			usb_sndctrlpipe(gspca_dev->dev, 0),
600c0d06caSMauro Carvalho Chehab 			USB_REQ_GET_STATUS,
610c0d06caSMauro Carvalho Chehab 			USB_DIR_OUT | USB_TYPE_CLASS |
620c0d06caSMauro Carvalho Chehab 			USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
630c0d06caSMauro Carvalho Chehab 			12, FPIX_TIMEOUT);
640c0d06caSMauro Carvalho Chehab }
650c0d06caSMauro Carvalho Chehab 
66844db450SHans de Goede /*
67844db450SHans de Goede  * This function is called as a workqueue function and runs whenever the camera
68844db450SHans de Goede  * is streaming data. Because it is a workqueue function it is allowed to sleep
69844db450SHans de Goede  * so we can use synchronous USB calls. To avoid possible collisions with other
70844db450SHans de Goede  * threads attempting to use gspca_dev->usb_buf we take the usb_lock when
71844db450SHans de Goede  * performing USB operations using it. In practice we don't really need this
72844db450SHans de Goede  * as the camera doesn't provide any controls.
73844db450SHans de Goede  */
dostream(struct work_struct * work)740c0d06caSMauro Carvalho Chehab static void dostream(struct work_struct *work)
750c0d06caSMauro Carvalho Chehab {
760c0d06caSMauro Carvalho Chehab 	struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);
770c0d06caSMauro Carvalho Chehab 	struct gspca_dev *gspca_dev = &dev->gspca_dev;
780c0d06caSMauro Carvalho Chehab 	struct urb *urb = gspca_dev->urb[0];
790c0d06caSMauro Carvalho Chehab 	u8 *data = urb->transfer_buffer;
800c0d06caSMauro Carvalho Chehab 	int ret = 0;
810c0d06caSMauro Carvalho Chehab 	int len;
820c0d06caSMauro Carvalho Chehab 
8337d5efb0SJoe Perches 	gspca_dbg(gspca_dev, D_STREAM, "dostream started\n");
840c0d06caSMauro Carvalho Chehab 
850c0d06caSMauro Carvalho Chehab 	/* loop reading a frame */
860c0d06caSMauro Carvalho Chehab again:
87345321dcSHans de Goede 	while (gspca_dev->present && gspca_dev->streaming) {
880c0d06caSMauro Carvalho Chehab #ifdef CONFIG_PM
890c0d06caSMauro Carvalho Chehab 		if (gspca_dev->frozen)
900c0d06caSMauro Carvalho Chehab 			break;
910c0d06caSMauro Carvalho Chehab #endif
920c0d06caSMauro Carvalho Chehab 
930c0d06caSMauro Carvalho Chehab 		/* request a frame */
940c0d06caSMauro Carvalho Chehab 		mutex_lock(&gspca_dev->usb_lock);
950c0d06caSMauro Carvalho Chehab 		ret = command(gspca_dev, 1);
960c0d06caSMauro Carvalho Chehab 		mutex_unlock(&gspca_dev->usb_lock);
970c0d06caSMauro Carvalho Chehab 		if (ret < 0)
980c0d06caSMauro Carvalho Chehab 			break;
990c0d06caSMauro Carvalho Chehab #ifdef CONFIG_PM
1000c0d06caSMauro Carvalho Chehab 		if (gspca_dev->frozen)
1010c0d06caSMauro Carvalho Chehab 			break;
1020c0d06caSMauro Carvalho Chehab #endif
103345321dcSHans de Goede 		if (!gspca_dev->present || !gspca_dev->streaming)
1040c0d06caSMauro Carvalho Chehab 			break;
1050c0d06caSMauro Carvalho Chehab 
1060c0d06caSMauro Carvalho Chehab 		/* the frame comes in parts */
1070c0d06caSMauro Carvalho Chehab 		for (;;) {
1080c0d06caSMauro Carvalho Chehab 			ret = usb_bulk_msg(gspca_dev->dev,
1090c0d06caSMauro Carvalho Chehab 					urb->pipe,
1100c0d06caSMauro Carvalho Chehab 					data,
1110c0d06caSMauro Carvalho Chehab 					FPIX_MAX_TRANSFER,
1120c0d06caSMauro Carvalho Chehab 					&len, FPIX_TIMEOUT);
1130c0d06caSMauro Carvalho Chehab 			if (ret < 0) {
1140c0d06caSMauro Carvalho Chehab 				/* Most of the time we get a timeout
1150c0d06caSMauro Carvalho Chehab 				 * error. Just restart. */
1160c0d06caSMauro Carvalho Chehab 				goto again;
1170c0d06caSMauro Carvalho Chehab 			}
1180c0d06caSMauro Carvalho Chehab #ifdef CONFIG_PM
1190c0d06caSMauro Carvalho Chehab 			if (gspca_dev->frozen)
1200c0d06caSMauro Carvalho Chehab 				goto out;
1210c0d06caSMauro Carvalho Chehab #endif
122345321dcSHans de Goede 			if (!gspca_dev->present || !gspca_dev->streaming)
1230c0d06caSMauro Carvalho Chehab 				goto out;
1240c0d06caSMauro Carvalho Chehab 			if (len < FPIX_MAX_TRANSFER ||
1250c0d06caSMauro Carvalho Chehab 				(data[len - 2] == 0xff &&
1260c0d06caSMauro Carvalho Chehab 					data[len - 1] == 0xd9)) {
1270c0d06caSMauro Carvalho Chehab 
1280c0d06caSMauro Carvalho Chehab 				/* If the result is less than what was asked
1290c0d06caSMauro Carvalho Chehab 				 * for, then it's the end of the
1300c0d06caSMauro Carvalho Chehab 				 * frame. Sometimes the jpeg is not complete,
1310c0d06caSMauro Carvalho Chehab 				 * but there's nothing we can do. We also end
132*031d8af1SSlark Xiao 				 * here if the jpeg ends right at the end
1330c0d06caSMauro Carvalho Chehab 				 * of the frame. */
1340c0d06caSMauro Carvalho Chehab 				gspca_frame_add(gspca_dev, LAST_PACKET,
1350c0d06caSMauro Carvalho Chehab 						data, len);
1360c0d06caSMauro Carvalho Chehab 				break;
1370c0d06caSMauro Carvalho Chehab 			}
1380c0d06caSMauro Carvalho Chehab 
1390c0d06caSMauro Carvalho Chehab 			/* got a partial image */
1400c0d06caSMauro Carvalho Chehab 			gspca_frame_add(gspca_dev,
1410c0d06caSMauro Carvalho Chehab 					gspca_dev->last_packet_type
1420c0d06caSMauro Carvalho Chehab 						== LAST_PACKET
1430c0d06caSMauro Carvalho Chehab 					? FIRST_PACKET : INTER_PACKET,
1440c0d06caSMauro Carvalho Chehab 					data, len);
1450c0d06caSMauro Carvalho Chehab 		}
1460c0d06caSMauro Carvalho Chehab 
1470c0d06caSMauro Carvalho Chehab 		/* We must wait before trying reading the next
1480c0d06caSMauro Carvalho Chehab 		 * frame. If we don't, or if the delay is too short,
1490c0d06caSMauro Carvalho Chehab 		 * the camera will disconnect. */
1500c0d06caSMauro Carvalho Chehab 		msleep(NEXT_FRAME_DELAY);
1510c0d06caSMauro Carvalho Chehab 	}
1520c0d06caSMauro Carvalho Chehab 
1530c0d06caSMauro Carvalho Chehab out:
15437d5efb0SJoe Perches 	gspca_dbg(gspca_dev, D_STREAM, "dostream stopped\n");
1550c0d06caSMauro Carvalho Chehab }
1560c0d06caSMauro Carvalho Chehab 
1570c0d06caSMauro Carvalho Chehab /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)1580c0d06caSMauro Carvalho Chehab static int sd_config(struct gspca_dev *gspca_dev,
1590c0d06caSMauro Carvalho Chehab 		const struct usb_device_id *id)
1600c0d06caSMauro Carvalho Chehab {
1610c0d06caSMauro Carvalho Chehab 	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
1620c0d06caSMauro Carvalho Chehab 	struct cam *cam = &gspca_dev->cam;
1630c0d06caSMauro Carvalho Chehab 
1640c0d06caSMauro Carvalho Chehab 	cam->cam_mode = fpix_mode;
1650c0d06caSMauro Carvalho Chehab 	cam->nmodes = 1;
1660c0d06caSMauro Carvalho Chehab 	cam->bulk = 1;
1670c0d06caSMauro Carvalho Chehab 	cam->bulk_size = FPIX_MAX_TRANSFER;
1680c0d06caSMauro Carvalho Chehab 
1690c0d06caSMauro Carvalho Chehab 	INIT_WORK(&dev->work_struct, dostream);
1700c0d06caSMauro Carvalho Chehab 
1710c0d06caSMauro Carvalho Chehab 	return 0;
1720c0d06caSMauro Carvalho Chehab }
1730c0d06caSMauro Carvalho Chehab 
1740c0d06caSMauro Carvalho Chehab /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)1750c0d06caSMauro Carvalho Chehab static int sd_init(struct gspca_dev *gspca_dev)
1760c0d06caSMauro Carvalho Chehab {
1770c0d06caSMauro Carvalho Chehab 	return 0;
1780c0d06caSMauro Carvalho Chehab }
1790c0d06caSMauro Carvalho Chehab 
1800c0d06caSMauro Carvalho Chehab /* start the camera */
sd_start(struct gspca_dev * gspca_dev)1810c0d06caSMauro Carvalho Chehab static int sd_start(struct gspca_dev *gspca_dev)
1820c0d06caSMauro Carvalho Chehab {
1830c0d06caSMauro Carvalho Chehab 	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
1840c0d06caSMauro Carvalho Chehab 	int ret, len;
1850c0d06caSMauro Carvalho Chehab 
1860c0d06caSMauro Carvalho Chehab 	/* Init the device */
1870c0d06caSMauro Carvalho Chehab 	ret = command(gspca_dev, 0);
1880c0d06caSMauro Carvalho Chehab 	if (ret < 0) {
1890c0d06caSMauro Carvalho Chehab 		pr_err("init failed %d\n", ret);
1900c0d06caSMauro Carvalho Chehab 		return ret;
1910c0d06caSMauro Carvalho Chehab 	}
1920c0d06caSMauro Carvalho Chehab 
1930c0d06caSMauro Carvalho Chehab 	/* Read the result of the command. Ignore the result, for it
1940c0d06caSMauro Carvalho Chehab 	 * varies with the device. */
1950c0d06caSMauro Carvalho Chehab 	ret = usb_bulk_msg(gspca_dev->dev,
1960c0d06caSMauro Carvalho Chehab 			gspca_dev->urb[0]->pipe,
1970c0d06caSMauro Carvalho Chehab 			gspca_dev->urb[0]->transfer_buffer,
1980c0d06caSMauro Carvalho Chehab 			FPIX_MAX_TRANSFER, &len,
1990c0d06caSMauro Carvalho Chehab 			FPIX_TIMEOUT);
2000c0d06caSMauro Carvalho Chehab 	if (ret < 0) {
2010c0d06caSMauro Carvalho Chehab 		pr_err("usb_bulk_msg failed %d\n", ret);
2020c0d06caSMauro Carvalho Chehab 		return ret;
2030c0d06caSMauro Carvalho Chehab 	}
2040c0d06caSMauro Carvalho Chehab 
2050c0d06caSMauro Carvalho Chehab 	/* Request a frame, but don't read it */
2060c0d06caSMauro Carvalho Chehab 	ret = command(gspca_dev, 1);
2070c0d06caSMauro Carvalho Chehab 	if (ret < 0) {
2080c0d06caSMauro Carvalho Chehab 		pr_err("frame request failed %d\n", ret);
2090c0d06caSMauro Carvalho Chehab 		return ret;
2100c0d06caSMauro Carvalho Chehab 	}
2110c0d06caSMauro Carvalho Chehab 
2120c0d06caSMauro Carvalho Chehab 	/* Again, reset bulk in endpoint */
2130c0d06caSMauro Carvalho Chehab 	usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
2140c0d06caSMauro Carvalho Chehab 
21553eebd84SBhaktipriya Shridhar 	schedule_work(&dev->work_struct);
2160c0d06caSMauro Carvalho Chehab 
2170c0d06caSMauro Carvalho Chehab 	return 0;
2180c0d06caSMauro Carvalho Chehab }
2190c0d06caSMauro Carvalho Chehab 
2200c0d06caSMauro Carvalho Chehab /* called on streamoff with alt==0 and on disconnect */
2210c0d06caSMauro Carvalho Chehab /* the usb_lock is held at entry - restore on exit */
sd_stop0(struct gspca_dev * gspca_dev)2220c0d06caSMauro Carvalho Chehab static void sd_stop0(struct gspca_dev *gspca_dev)
2230c0d06caSMauro Carvalho Chehab {
2240c0d06caSMauro Carvalho Chehab 	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
2250c0d06caSMauro Carvalho Chehab 
2260c0d06caSMauro Carvalho Chehab 	/* wait for the work queue to terminate */
2270c0d06caSMauro Carvalho Chehab 	mutex_unlock(&gspca_dev->usb_lock);
22853eebd84SBhaktipriya Shridhar 	flush_work(&dev->work_struct);
2290c0d06caSMauro Carvalho Chehab 	mutex_lock(&gspca_dev->usb_lock);
2300c0d06caSMauro Carvalho Chehab }
2310c0d06caSMauro Carvalho Chehab 
2320c0d06caSMauro Carvalho Chehab /* Table of supported USB devices */
2330c0d06caSMauro Carvalho Chehab static const struct usb_device_id device_table[] = {
2340c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0104)},
2350c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0109)},
2360c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x010b)},
2370c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x010f)},
2380c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0111)},
2390c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0113)},
2400c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0115)},
2410c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0117)},
2420c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0119)},
2430c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x011b)},
2440c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x011d)},
2450c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0121)},
2460c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0123)},
2470c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0125)},
2480c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0127)},
2490c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0129)},
2500c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x012b)},
2510c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x012d)},
2520c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x012f)},
2530c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x0131)},
2540c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x013b)},
2550c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x013d)},
2560c0d06caSMauro Carvalho Chehab 	{USB_DEVICE(0x04cb, 0x013f)},
2570c0d06caSMauro Carvalho Chehab 	{}
2580c0d06caSMauro Carvalho Chehab };
2590c0d06caSMauro Carvalho Chehab 
2600c0d06caSMauro Carvalho Chehab MODULE_DEVICE_TABLE(usb, device_table);
2610c0d06caSMauro Carvalho Chehab 
2620c0d06caSMauro Carvalho Chehab /* sub-driver description */
2630c0d06caSMauro Carvalho Chehab static const struct sd_desc sd_desc = {
2640c0d06caSMauro Carvalho Chehab 	.name   = MODULE_NAME,
2650c0d06caSMauro Carvalho Chehab 	.config = sd_config,
2660c0d06caSMauro Carvalho Chehab 	.init   = sd_init,
2670c0d06caSMauro Carvalho Chehab 	.start  = sd_start,
2680c0d06caSMauro Carvalho Chehab 	.stop0  = sd_stop0,
2690c0d06caSMauro Carvalho Chehab };
2700c0d06caSMauro Carvalho Chehab 
2710c0d06caSMauro Carvalho Chehab /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)2720c0d06caSMauro Carvalho Chehab static int sd_probe(struct usb_interface *intf,
2730c0d06caSMauro Carvalho Chehab 		const struct usb_device_id *id)
2740c0d06caSMauro Carvalho Chehab {
2750c0d06caSMauro Carvalho Chehab 	return gspca_dev_probe(intf, id,
2760c0d06caSMauro Carvalho Chehab 			&sd_desc,
2770c0d06caSMauro Carvalho Chehab 			sizeof(struct usb_fpix),
2780c0d06caSMauro Carvalho Chehab 			THIS_MODULE);
2790c0d06caSMauro Carvalho Chehab }
2800c0d06caSMauro Carvalho Chehab 
2810c0d06caSMauro Carvalho Chehab static struct usb_driver sd_driver = {
2820c0d06caSMauro Carvalho Chehab 	.name       = MODULE_NAME,
2830c0d06caSMauro Carvalho Chehab 	.id_table   = device_table,
2840c0d06caSMauro Carvalho Chehab 	.probe      = sd_probe,
2850c0d06caSMauro Carvalho Chehab 	.disconnect = gspca_disconnect,
2860c0d06caSMauro Carvalho Chehab #ifdef CONFIG_PM
2870c0d06caSMauro Carvalho Chehab 	.suspend = gspca_suspend,
2880c0d06caSMauro Carvalho Chehab 	.resume  = gspca_resume,
2890c0d06caSMauro Carvalho Chehab 	.reset_resume = gspca_resume,
2900c0d06caSMauro Carvalho Chehab #endif
2910c0d06caSMauro Carvalho Chehab };
2920c0d06caSMauro Carvalho Chehab 
2930c0d06caSMauro Carvalho Chehab module_usb_driver(sd_driver);
294