// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Fujifilm Finepix subdriver
 *
 * Copyright (C) 2008 Frank Zago
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#define MODULE_NAME "finepix"

#include "gspca.h"

MODULE_AUTHOR("Frank Zago <frank@zago.net>");
MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");
MODULE_LICENSE("GPL");

/* Default timeout, in ms */
#define FPIX_TIMEOUT 250

/* Maximum transfer size to use. The windows driver reads by chunks of
 * 0x2000 bytes, so do the same. Note: reading more seems to work
 * too. */
#define FPIX_MAX_TRANSFER 0x2000

/* Structure to hold all of our device specific stuff */
struct usb_fpix {
	struct gspca_dev gspca_dev;	/* !! must be the first item */

	struct work_struct work_struct;
};

/* Delay after which claim the next frame. If the delay is too small,
 * the camera will return old frames. On the 4800Z, 20ms is bad, 25ms
 * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,
 * 30ms is bad while 35ms is perfect. */
#define NEXT_FRAME_DELAY 35

/* These cameras only support 320x200. */
static const struct v4l2_pix_format fpix_mode[1] = {
	{ 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
		.bytesperline = 320,
		.sizeimage = 320 * 240 * 3 / 8 + 590,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = 0}
};

/* send a command to the webcam */
static int command(struct gspca_dev *gspca_dev,
		int order)	/* 0: reset, 1: frame request */
{
	static u8 order_values[2][12] = {
		{0xc6, 0, 0, 0, 0, 0, 0,    0, 0x20, 0, 0, 0},	/* reset */
		{0xd3, 0, 0, 0, 0, 0, 0, 0x01,    0, 0, 0, 0},	/* fr req */
	};

	memcpy(gspca_dev->usb_buf, order_values[order], 12);
	return usb_control_msg(gspca_dev->dev,
			usb_sndctrlpipe(gspca_dev->dev, 0),
			USB_REQ_GET_STATUS,
			USB_DIR_OUT | USB_TYPE_CLASS |
			USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
			12, FPIX_TIMEOUT);
}

/*
 * This function is called as a workqueue function and runs whenever the camera
 * is streaming data. Because it is a workqueue function it is allowed to sleep
 * so we can use synchronous USB calls. To avoid possible collisions with other
 * threads attempting to use gspca_dev->usb_buf we take the usb_lock when
 * performing USB operations using it. In practice we don't really need this
 * as the camera doesn't provide any controls.
 */
static void dostream(struct work_struct *work)
{
	struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);
	struct gspca_dev *gspca_dev = &dev->gspca_dev;
	struct urb *urb = gspca_dev->urb[0];
	u8 *data = urb->transfer_buffer;
	int ret = 0;
	int len;

	gspca_dbg(gspca_dev, D_STREAM, "dostream started\n");

	/* loop reading a frame */
again:
	while (gspca_dev->present && gspca_dev->streaming) {
#ifdef CONFIG_PM
		if (gspca_dev->frozen)
			break;
#endif

		/* request a frame */
		mutex_lock(&gspca_dev->usb_lock);
		ret = command(gspca_dev, 1);
		mutex_unlock(&gspca_dev->usb_lock);
		if (ret < 0)
			break;
#ifdef CONFIG_PM
		if (gspca_dev->frozen)
			break;
#endif
		if (!gspca_dev->present || !gspca_dev->streaming)
			break;

		/* the frame comes in parts */
		for (;;) {
			ret = usb_bulk_msg(gspca_dev->dev,
					urb->pipe,
					data,
					FPIX_MAX_TRANSFER,
					&len, FPIX_TIMEOUT);
			if (ret < 0) {
				/* Most of the time we get a timeout
				 * error. Just restart. */
				goto again;
			}
#ifdef CONFIG_PM
			if (gspca_dev->frozen)
				goto out;
#endif
			if (!gspca_dev->present || !gspca_dev->streaming)
				goto out;
			if (len < FPIX_MAX_TRANSFER ||
				(data[len - 2] == 0xff &&
					data[len - 1] == 0xd9)) {

				/* If the result is less than what was asked
				 * for, then it's the end of the
				 * frame. Sometimes the jpeg is not complete,
				 * but there's nothing we can do. We also end
				 * here if the the jpeg ends right at the end
				 * of the frame. */
				gspca_frame_add(gspca_dev, LAST_PACKET,
						data, len);
				break;
			}

			/* got a partial image */
			gspca_frame_add(gspca_dev,
					gspca_dev->last_packet_type
						== LAST_PACKET
					? FIRST_PACKET : INTER_PACKET,
					data, len);
		}

		/* We must wait before trying reading the next
		 * frame. If we don't, or if the delay is too short,
		 * the camera will disconnect. */
		msleep(NEXT_FRAME_DELAY);
	}

out:
	gspca_dbg(gspca_dev, D_STREAM, "dostream stopped\n");
}

/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
		const struct usb_device_id *id)
{
	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
	struct cam *cam = &gspca_dev->cam;

	cam->cam_mode = fpix_mode;
	cam->nmodes = 1;
	cam->bulk = 1;
	cam->bulk_size = FPIX_MAX_TRANSFER;

	INIT_WORK(&dev->work_struct, dostream);

	return 0;
}

/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
	return 0;
}

/* start the camera */
static int sd_start(struct gspca_dev *gspca_dev)
{
	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
	int ret, len;

	/* Init the device */
	ret = command(gspca_dev, 0);
	if (ret < 0) {
		pr_err("init failed %d\n", ret);
		return ret;
	}

	/* Read the result of the command. Ignore the result, for it
	 * varies with the device. */
	ret = usb_bulk_msg(gspca_dev->dev,
			gspca_dev->urb[0]->pipe,
			gspca_dev->urb[0]->transfer_buffer,
			FPIX_MAX_TRANSFER, &len,
			FPIX_TIMEOUT);
	if (ret < 0) {
		pr_err("usb_bulk_msg failed %d\n", ret);
		return ret;
	}

	/* Request a frame, but don't read it */
	ret = command(gspca_dev, 1);
	if (ret < 0) {
		pr_err("frame request failed %d\n", ret);
		return ret;
	}

	/* Again, reset bulk in endpoint */
	usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);

	schedule_work(&dev->work_struct);

	return 0;
}

/* called on streamoff with alt==0 and on disconnect */
/* the usb_lock is held at entry - restore on exit */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
	struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;

	/* wait for the work queue to terminate */
	mutex_unlock(&gspca_dev->usb_lock);
	flush_work(&dev->work_struct);
	mutex_lock(&gspca_dev->usb_lock);
}

/* Table of supported USB devices */
static const struct usb_device_id device_table[] = {
	{USB_DEVICE(0x04cb, 0x0104)},
	{USB_DEVICE(0x04cb, 0x0109)},
	{USB_DEVICE(0x04cb, 0x010b)},
	{USB_DEVICE(0x04cb, 0x010f)},
	{USB_DEVICE(0x04cb, 0x0111)},
	{USB_DEVICE(0x04cb, 0x0113)},
	{USB_DEVICE(0x04cb, 0x0115)},
	{USB_DEVICE(0x04cb, 0x0117)},
	{USB_DEVICE(0x04cb, 0x0119)},
	{USB_DEVICE(0x04cb, 0x011b)},
	{USB_DEVICE(0x04cb, 0x011d)},
	{USB_DEVICE(0x04cb, 0x0121)},
	{USB_DEVICE(0x04cb, 0x0123)},
	{USB_DEVICE(0x04cb, 0x0125)},
	{USB_DEVICE(0x04cb, 0x0127)},
	{USB_DEVICE(0x04cb, 0x0129)},
	{USB_DEVICE(0x04cb, 0x012b)},
	{USB_DEVICE(0x04cb, 0x012d)},
	{USB_DEVICE(0x04cb, 0x012f)},
	{USB_DEVICE(0x04cb, 0x0131)},
	{USB_DEVICE(0x04cb, 0x013b)},
	{USB_DEVICE(0x04cb, 0x013d)},
	{USB_DEVICE(0x04cb, 0x013f)},
	{}
};

MODULE_DEVICE_TABLE(usb, device_table);

/* sub-driver description */
static const struct sd_desc sd_desc = {
	.name   = MODULE_NAME,
	.config = sd_config,
	.init   = sd_init,
	.start  = sd_start,
	.stop0  = sd_stop0,
};

/* -- device connect -- */
static int sd_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{
	return gspca_dev_probe(intf, id,
			&sd_desc,
			sizeof(struct usb_fpix),
			THIS_MODULE);
}

static struct usb_driver sd_driver = {
	.name       = MODULE_NAME,
	.id_table   = device_table,
	.probe      = sd_probe,
	.disconnect = gspca_disconnect,
#ifdef CONFIG_PM
	.suspend = gspca_suspend,
	.resume  = gspca_resume,
	.reset_resume = gspca_resume,
#endif
};

module_usb_driver(sd_driver);
