1*c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 221f1b932SHans de Goede /* 321f1b932SHans de Goede * STV0680 USB Camera Driver 421f1b932SHans de Goede * 51fddcf0eSHans de Goede * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> 621f1b932SHans de Goede * 721f1b932SHans de Goede * This module is adapted from the in kernel v4l1 stv680 driver: 821f1b932SHans de Goede * 921f1b932SHans de Goede * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net) 1021f1b932SHans de Goede * 1121f1b932SHans de Goede * Thanks to STMicroelectronics for information on the usb commands, and 1221f1b932SHans de Goede * to Steve Miller at STM for his help and encouragement while I was 1321f1b932SHans de Goede * writing this driver. 1421f1b932SHans de Goede */ 1521f1b932SHans de Goede 16133a9fe9SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17133a9fe9SJoe Perches 1821f1b932SHans de Goede #define MODULE_NAME "stv0680" 1921f1b932SHans de Goede 2021f1b932SHans de Goede #include "gspca.h" 2121f1b932SHans de Goede 221fddcf0eSHans de Goede MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 2321f1b932SHans de Goede MODULE_DESCRIPTION("STV0680 USB Camera Driver"); 2421f1b932SHans de Goede MODULE_LICENSE("GPL"); 2521f1b932SHans de Goede 2621f1b932SHans de Goede /* specific webcam descriptor */ 2721f1b932SHans de Goede struct sd { 2821f1b932SHans de Goede struct gspca_dev gspca_dev; /* !! must be the first item */ 2921f1b932SHans de Goede struct v4l2_pix_format mode; 3021f1b932SHans de Goede u8 orig_mode; 3121f1b932SHans de Goede u8 video_mode; 3221f1b932SHans de Goede u8 current_mode; 3321f1b932SHans de Goede }; 3421f1b932SHans de Goede 3521f1b932SHans de Goede static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, 3621f1b932SHans de Goede int size) 3721f1b932SHans de Goede { 3821f1b932SHans de Goede int ret = -1; 3921f1b932SHans de Goede u8 req_type = 0; 40388a6d54SHans de Goede unsigned int pipe = 0; 4121f1b932SHans de Goede 4221f1b932SHans de Goede switch (set) { 4321f1b932SHans de Goede case 0: /* 0xc1 */ 4421f1b932SHans de Goede req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; 45388a6d54SHans de Goede pipe = usb_rcvctrlpipe(gspca_dev->dev, 0); 4621f1b932SHans de Goede break; 4721f1b932SHans de Goede case 1: /* 0x41 */ 4821f1b932SHans de Goede req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; 49388a6d54SHans de Goede pipe = usb_sndctrlpipe(gspca_dev->dev, 0); 5021f1b932SHans de Goede break; 5121f1b932SHans de Goede case 2: /* 0x80 */ 5221f1b932SHans de Goede req_type = USB_DIR_IN | USB_RECIP_DEVICE; 53388a6d54SHans de Goede pipe = usb_rcvctrlpipe(gspca_dev->dev, 0); 5421f1b932SHans de Goede break; 5521f1b932SHans de Goede case 3: /* 0x40 */ 5621f1b932SHans de Goede req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; 57388a6d54SHans de Goede pipe = usb_sndctrlpipe(gspca_dev->dev, 0); 5821f1b932SHans de Goede break; 5921f1b932SHans de Goede } 6021f1b932SHans de Goede 61388a6d54SHans de Goede ret = usb_control_msg(gspca_dev->dev, pipe, 6221f1b932SHans de Goede req, req_type, 6321f1b932SHans de Goede val, 0, gspca_dev->usb_buf, size, 500); 6421f1b932SHans de Goede 6521f1b932SHans de Goede if ((ret < 0) && (req != 0x0a)) 66133a9fe9SJoe Perches pr_err("usb_control_msg error %i, request = 0x%x, error = %i\n", 6721f1b932SHans de Goede set, req, ret); 6821f1b932SHans de Goede 6921f1b932SHans de Goede return ret; 7021f1b932SHans de Goede } 7121f1b932SHans de Goede 7221f1b932SHans de Goede static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret) 7321f1b932SHans de Goede { 7421f1b932SHans de Goede stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */ 7552173c5fSJoe Perches gspca_err(gspca_dev, "last error: %i, command = 0x%x\n", 7621f1b932SHans de Goede gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); 7721f1b932SHans de Goede return ret; 7821f1b932SHans de Goede } 7921f1b932SHans de Goede 8021f1b932SHans de Goede static int stv0680_get_video_mode(struct gspca_dev *gspca_dev) 8121f1b932SHans de Goede { 8221f1b932SHans de Goede /* Note not sure if this init of usb_buf is really necessary */ 8321f1b932SHans de Goede memset(gspca_dev->usb_buf, 0, 8); 8421f1b932SHans de Goede gspca_dev->usb_buf[0] = 0x0f; 8521f1b932SHans de Goede 8621f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) { 8752173c5fSJoe Perches gspca_err(gspca_dev, "Get_Camera_Mode failed\n"); 8821f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -EIO); 8921f1b932SHans de Goede } 9021f1b932SHans de Goede 9121f1b932SHans de Goede return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */ 9221f1b932SHans de Goede } 9321f1b932SHans de Goede 9421f1b932SHans de Goede static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode) 9521f1b932SHans de Goede { 9621f1b932SHans de Goede struct sd *sd = (struct sd *) gspca_dev; 9721f1b932SHans de Goede 9821f1b932SHans de Goede if (sd->current_mode == mode) 9921f1b932SHans de Goede return 0; 10021f1b932SHans de Goede 10121f1b932SHans de Goede memset(gspca_dev->usb_buf, 0, 8); 10221f1b932SHans de Goede gspca_dev->usb_buf[0] = mode; 10321f1b932SHans de Goede 10421f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) { 10552173c5fSJoe Perches gspca_err(gspca_dev, "Set_Camera_Mode failed\n"); 10621f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -EIO); 10721f1b932SHans de Goede } 10821f1b932SHans de Goede 10921f1b932SHans de Goede /* Verify we got what we've asked for */ 11021f1b932SHans de Goede if (stv0680_get_video_mode(gspca_dev) != mode) { 11152173c5fSJoe Perches gspca_err(gspca_dev, "Error setting camera video mode!\n"); 11221f1b932SHans de Goede return -EIO; 11321f1b932SHans de Goede } 11421f1b932SHans de Goede 11521f1b932SHans de Goede sd->current_mode = mode; 11621f1b932SHans de Goede 11721f1b932SHans de Goede return 0; 11821f1b932SHans de Goede } 11921f1b932SHans de Goede 12021f1b932SHans de Goede /* this function is called at probe time */ 12121f1b932SHans de Goede static int sd_config(struct gspca_dev *gspca_dev, 12221f1b932SHans de Goede const struct usb_device_id *id) 12321f1b932SHans de Goede { 12421f1b932SHans de Goede int ret; 12521f1b932SHans de Goede struct sd *sd = (struct sd *) gspca_dev; 12621f1b932SHans de Goede struct cam *cam = &gspca_dev->cam; 12721f1b932SHans de Goede 128f58c91ceSJonathan McCrohan /* Give the camera some time to settle, otherwise initialization will 129ab269d30SHans de Goede fail on hotplug, and yes it really needs a full second. */ 130ab269d30SHans de Goede msleep(1000); 131ab269d30SHans de Goede 13221f1b932SHans de Goede /* ping camera to be sure STV0680 is present */ 13321f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 || 13421f1b932SHans de Goede gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) { 13552173c5fSJoe Perches gspca_err(gspca_dev, "STV(e): camera ping failed!!\n"); 13621f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -ENODEV); 13721f1b932SHans de Goede } 13821f1b932SHans de Goede 13921f1b932SHans de Goede /* get camera descriptor */ 14021f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09) 14121f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -ENODEV); 14221f1b932SHans de Goede 14321f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 || 14421f1b932SHans de Goede gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) { 14552173c5fSJoe Perches gspca_err(gspca_dev, "Could not get descriptor 0200\n"); 14621f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -ENODEV); 14721f1b932SHans de Goede } 14821f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02) 14921f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -ENODEV); 15021f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24) 15121f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -ENODEV); 15221f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10) 15321f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -ENODEV); 15421f1b932SHans de Goede 15521f1b932SHans de Goede if (!(gspca_dev->usb_buf[7] & 0x09)) { 15652173c5fSJoe Perches gspca_err(gspca_dev, "Camera supports neither CIF nor QVGA mode\n"); 15721f1b932SHans de Goede return -ENODEV; 15821f1b932SHans de Goede } 15921f1b932SHans de Goede if (gspca_dev->usb_buf[7] & 0x01) 16037d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PROBE, "Camera supports CIF mode\n"); 16121f1b932SHans de Goede if (gspca_dev->usb_buf[7] & 0x02) 16237d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PROBE, "Camera supports VGA mode\n"); 163388a6d54SHans de Goede if (gspca_dev->usb_buf[7] & 0x04) 16437d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PROBE, "Camera supports QCIF mode\n"); 16521f1b932SHans de Goede if (gspca_dev->usb_buf[7] & 0x08) 16637d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PROBE, "Camera supports QVGA mode\n"); 16721f1b932SHans de Goede 16821f1b932SHans de Goede if (gspca_dev->usb_buf[7] & 0x01) 16921f1b932SHans de Goede sd->video_mode = 0x00; /* CIF */ 17021f1b932SHans de Goede else 17121f1b932SHans de Goede sd->video_mode = 0x03; /* QVGA */ 17221f1b932SHans de Goede 17321f1b932SHans de Goede /* FW rev, ASIC rev, sensor ID */ 17437d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PROBE, "Firmware rev is %i.%i\n", 17521f1b932SHans de Goede gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); 17637d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PROBE, "ASIC rev is %i.%i", 17721f1b932SHans de Goede gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]); 17837d5efb0SJoe Perches gspca_dbg(gspca_dev, D_PROBE, "Sensor ID is %i", 17921f1b932SHans de Goede (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4)); 18021f1b932SHans de Goede 18121f1b932SHans de Goede 18221f1b932SHans de Goede ret = stv0680_get_video_mode(gspca_dev); 18321f1b932SHans de Goede if (ret < 0) 18421f1b932SHans de Goede return ret; 18521f1b932SHans de Goede sd->current_mode = sd->orig_mode = ret; 18621f1b932SHans de Goede 18721f1b932SHans de Goede ret = stv0680_set_video_mode(gspca_dev, sd->video_mode); 18821f1b932SHans de Goede if (ret < 0) 18921f1b932SHans de Goede return ret; 19021f1b932SHans de Goede 19121f1b932SHans de Goede /* Get mode details */ 19221f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10) 19321f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -EIO); 19421f1b932SHans de Goede 19521f1b932SHans de Goede cam->bulk = 1; 19621f1b932SHans de Goede cam->bulk_nurbs = 1; /* The cam cannot handle more */ 19721f1b932SHans de Goede cam->bulk_size = (gspca_dev->usb_buf[0] << 24) | 19821f1b932SHans de Goede (gspca_dev->usb_buf[1] << 16) | 19921f1b932SHans de Goede (gspca_dev->usb_buf[2] << 8) | 20021f1b932SHans de Goede (gspca_dev->usb_buf[3]); 20121f1b932SHans de Goede sd->mode.width = (gspca_dev->usb_buf[4] << 8) | 20221f1b932SHans de Goede (gspca_dev->usb_buf[5]); /* 322, 356, 644 */ 20321f1b932SHans de Goede sd->mode.height = (gspca_dev->usb_buf[6] << 8) | 20421f1b932SHans de Goede (gspca_dev->usb_buf[7]); /* 242, 292, 484 */ 20521f1b932SHans de Goede sd->mode.pixelformat = V4L2_PIX_FMT_STV0680; 20621f1b932SHans de Goede sd->mode.field = V4L2_FIELD_NONE; 20721f1b932SHans de Goede sd->mode.bytesperline = sd->mode.width; 20821f1b932SHans de Goede sd->mode.sizeimage = cam->bulk_size; 20921f1b932SHans de Goede sd->mode.colorspace = V4L2_COLORSPACE_SRGB; 21021f1b932SHans de Goede 21121f1b932SHans de Goede /* origGain = gspca_dev->usb_buf[12]; */ 21221f1b932SHans de Goede 21321f1b932SHans de Goede cam->cam_mode = &sd->mode; 21421f1b932SHans de Goede cam->nmodes = 1; 21521f1b932SHans de Goede 21621f1b932SHans de Goede 21721f1b932SHans de Goede ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode); 21821f1b932SHans de Goede if (ret < 0) 21921f1b932SHans de Goede return ret; 22021f1b932SHans de Goede 22121f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 || 22221f1b932SHans de Goede gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) { 223133a9fe9SJoe Perches pr_err("Could not get descriptor 0100\n"); 22421f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -EIO); 22521f1b932SHans de Goede } 22621f1b932SHans de Goede 22721f1b932SHans de Goede return 0; 22821f1b932SHans de Goede } 22921f1b932SHans de Goede 23021f1b932SHans de Goede /* this function is called at probe and resume time */ 23121f1b932SHans de Goede static int sd_init(struct gspca_dev *gspca_dev) 23221f1b932SHans de Goede { 23321f1b932SHans de Goede return 0; 23421f1b932SHans de Goede } 23521f1b932SHans de Goede 23621f1b932SHans de Goede /* -- start the camera -- */ 23721f1b932SHans de Goede static int sd_start(struct gspca_dev *gspca_dev) 23821f1b932SHans de Goede { 23921f1b932SHans de Goede int ret; 24021f1b932SHans de Goede struct sd *sd = (struct sd *) gspca_dev; 24121f1b932SHans de Goede 24221f1b932SHans de Goede ret = stv0680_set_video_mode(gspca_dev, sd->video_mode); 24321f1b932SHans de Goede if (ret < 0) 24421f1b932SHans de Goede return ret; 24521f1b932SHans de Goede 24621f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10) 24721f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -EIO); 24821f1b932SHans de Goede 24921f1b932SHans de Goede /* Start stream at: 25021f1b932SHans de Goede 0x0000 = CIF (352x288) 25121f1b932SHans de Goede 0x0100 = VGA (640x480) 25221f1b932SHans de Goede 0x0300 = QVGA (320x240) */ 25321f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0) 25421f1b932SHans de Goede return stv0680_handle_error(gspca_dev, -EIO); 25521f1b932SHans de Goede 25621f1b932SHans de Goede return 0; 25721f1b932SHans de Goede } 25821f1b932SHans de Goede 25921f1b932SHans de Goede static void sd_stopN(struct gspca_dev *gspca_dev) 26021f1b932SHans de Goede { 26121f1b932SHans de Goede /* This is a high priority command; it stops all lower order cmds */ 26221f1b932SHans de Goede if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0) 26321f1b932SHans de Goede stv0680_handle_error(gspca_dev, -EIO); 26421f1b932SHans de Goede } 26521f1b932SHans de Goede 26621f1b932SHans de Goede static void sd_stop0(struct gspca_dev *gspca_dev) 26721f1b932SHans de Goede { 26821f1b932SHans de Goede struct sd *sd = (struct sd *) gspca_dev; 26921f1b932SHans de Goede 27021f1b932SHans de Goede if (!sd->gspca_dev.present) 27121f1b932SHans de Goede return; 27221f1b932SHans de Goede 27321f1b932SHans de Goede stv0680_set_video_mode(gspca_dev, sd->orig_mode); 27421f1b932SHans de Goede } 27521f1b932SHans de Goede 27621f1b932SHans de Goede static void sd_pkt_scan(struct gspca_dev *gspca_dev, 27776dd272bSJean-Francois Moine u8 *data, 27821f1b932SHans de Goede int len) 27921f1b932SHans de Goede { 28021f1b932SHans de Goede struct sd *sd = (struct sd *) gspca_dev; 28121f1b932SHans de Goede 28221f1b932SHans de Goede /* Every now and then the camera sends a 16 byte packet, no idea 28321f1b932SHans de Goede what it contains, but it is not image data, when this 28421f1b932SHans de Goede happens the frame received before this packet is corrupt, 28521f1b932SHans de Goede so discard it. */ 28621f1b932SHans de Goede if (len != sd->mode.sizeimage) { 28721f1b932SHans de Goede gspca_dev->last_packet_type = DISCARD_PACKET; 28821f1b932SHans de Goede return; 28921f1b932SHans de Goede } 29021f1b932SHans de Goede 29121f1b932SHans de Goede /* Finish the previous frame, we do this upon reception of the next 29221f1b932SHans de Goede packet, even though it is already complete so that the strange 16 29321f1b932SHans de Goede byte packets send after a corrupt frame can discard it. */ 29476dd272bSJean-Francois Moine gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 29521f1b932SHans de Goede 29621f1b932SHans de Goede /* Store the just received frame */ 29776dd272bSJean-Francois Moine gspca_frame_add(gspca_dev, FIRST_PACKET, data, len); 29821f1b932SHans de Goede } 29921f1b932SHans de Goede 30021f1b932SHans de Goede /* sub-driver description */ 30121f1b932SHans de Goede static const struct sd_desc sd_desc = { 30221f1b932SHans de Goede .name = MODULE_NAME, 30321f1b932SHans de Goede .config = sd_config, 30421f1b932SHans de Goede .init = sd_init, 30521f1b932SHans de Goede .start = sd_start, 30621f1b932SHans de Goede .stopN = sd_stopN, 30721f1b932SHans de Goede .stop0 = sd_stop0, 30821f1b932SHans de Goede .pkt_scan = sd_pkt_scan, 30921f1b932SHans de Goede }; 31021f1b932SHans de Goede 31121f1b932SHans de Goede /* -- module initialisation -- */ 31295c967c1SJean-François Moine static const struct usb_device_id device_table[] = { 31321f1b932SHans de Goede {USB_DEVICE(0x0553, 0x0202)}, 31421f1b932SHans de Goede {USB_DEVICE(0x041e, 0x4007)}, 31521f1b932SHans de Goede {} 31621f1b932SHans de Goede }; 31721f1b932SHans de Goede MODULE_DEVICE_TABLE(usb, device_table); 31821f1b932SHans de Goede 31921f1b932SHans de Goede /* -- device connect -- */ 32021f1b932SHans de Goede static int sd_probe(struct usb_interface *intf, 32121f1b932SHans de Goede const struct usb_device_id *id) 32221f1b932SHans de Goede { 32321f1b932SHans de Goede return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 32421f1b932SHans de Goede THIS_MODULE); 32521f1b932SHans de Goede } 32621f1b932SHans de Goede 32721f1b932SHans de Goede static struct usb_driver sd_driver = { 32821f1b932SHans de Goede .name = MODULE_NAME, 32921f1b932SHans de Goede .id_table = device_table, 33021f1b932SHans de Goede .probe = sd_probe, 33121f1b932SHans de Goede .disconnect = gspca_disconnect, 33221f1b932SHans de Goede #ifdef CONFIG_PM 33321f1b932SHans de Goede .suspend = gspca_suspend, 33421f1b932SHans de Goede .resume = gspca_resume, 3358bb58964SHans de Goede .reset_resume = gspca_resume, 33621f1b932SHans de Goede #endif 33721f1b932SHans de Goede }; 33821f1b932SHans de Goede 339ecb3b2b3SGreg Kroah-Hartman module_usb_driver(sd_driver); 340