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