15b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* 25b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * spca1528 subdriver 35b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * 40dd826962716ff6984a14038d1604be816d759c3Jean-François Moine * Copyright (C) 2010-2011 Jean-Francois Moine (http://moinejf.free.fr) 55b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * 65b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * This program is free software; you can redistribute it and/or modify 75b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * it under the terms of the GNU General Public License as published by 85b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * the Free Software Foundation; either version 2 of the License, or 95b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * any later version. 105b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * 115b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * This program is distributed in the hope that it will be useful, 125b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * but WITHOUT ANY WARRANTY; without even the implied warranty of 135b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 145b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * GNU General Public License for more details. 155b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * 165b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * You should have received a copy of the GNU General Public License 175b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * along with this program; if not, write to the Free Software 185b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 195b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine */ 205b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 21133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches 235b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#define MODULE_NAME "spca1528" 245b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 255b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#include "gspca.h" 265b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#include "jpeg.h" 275b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 285b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François MoineMODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); 295b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François MoineMODULE_DESCRIPTION("SPCA1528 USB Camera Driver"); 305b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François MoineMODULE_LICENSE("GPL"); 315b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 325b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* specific webcam descriptor */ 335b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestruct sd { 345b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct gspca_dev gspca_dev; /* !! must be the first item */ 355b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 365b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 brightness; 375b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 contrast; 385b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 hue; 395b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 color; 405b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 sharpness; 415b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 425b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 pkt_seq; 435b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 445b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 jpeg_hdr[JPEG_HDR_SZ]; 455b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine}; 465b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 475b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* V4L2 controls supported by the driver */ 485b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 495b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 505b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 515b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 525b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); 535b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); 545b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_setcolor(struct gspca_dev *gspca_dev, __s32 val); 555b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_getcolor(struct gspca_dev *gspca_dev, __s32 *val); 565b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 575b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 585b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 595b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic const struct ctrl sd_ctrls[] = { 605b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 615b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 625b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .id = V4L2_CID_BRIGHTNESS, 635b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .type = V4L2_CTRL_TYPE_INTEGER, 645b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .name = "Brightness", 655b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .minimum = 0, 665b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .maximum = 255, 675b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .step = 1, 685b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#define BRIGHTNESS_DEF 128 695b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .default_value = BRIGHTNESS_DEF, 705b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 715b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .set = sd_setbrightness, 725b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .get = sd_getbrightness, 735b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 745b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 755b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 765b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .id = V4L2_CID_CONTRAST, 775b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .type = V4L2_CTRL_TYPE_INTEGER, 785b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .name = "Contrast", 795b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .minimum = 0, 805b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .maximum = 8, 815b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .step = 1, 825b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#define CONTRAST_DEF 1 835b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .default_value = CONTRAST_DEF, 845b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 855b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .set = sd_setcontrast, 865b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .get = sd_getcontrast, 875b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 885b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 895b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 905b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .id = V4L2_CID_HUE, 915b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .type = V4L2_CTRL_TYPE_INTEGER, 925b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .name = "Hue", 935b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .minimum = 0, 945b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .maximum = 255, 955b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .step = 1, 965b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#define HUE_DEF 0 975b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .default_value = HUE_DEF, 985b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 995b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .set = sd_sethue, 1005b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .get = sd_gethue, 1015b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 1025b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 1035b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 1045b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .id = V4L2_CID_SATURATION, 1055b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .type = V4L2_CTRL_TYPE_INTEGER, 1065b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .name = "Saturation", 1075b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .minimum = 0, 1085b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .maximum = 8, 1095b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .step = 1, 1105b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#define COLOR_DEF 1 1115b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .default_value = COLOR_DEF, 1125b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 1135b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .set = sd_setcolor, 1145b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .get = sd_getcolor, 1155b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 1165b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 1175b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine { 1185b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .id = V4L2_CID_SHARPNESS, 1195b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .type = V4L2_CTRL_TYPE_INTEGER, 1205b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .name = "Sharpness", 1215b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .minimum = 0, 1225b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .maximum = 255, 1235b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .step = 1, 1245b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#define SHARPNESS_DEF 0 1255b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .default_value = SHARPNESS_DEF, 1265b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 1275b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .set = sd_setsharpness, 1285b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .get = sd_getsharpness, 1295b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine }, 1305b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine}; 1315b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 1325b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic const struct v4l2_pix_format vga_mode[] = { 1335b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* (does not work correctly) 1345b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 1355b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .bytesperline = 176, 1365b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .sizeimage = 176 * 144 * 5 / 8 + 590, 1375b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .colorspace = V4L2_COLORSPACE_JPEG, 1385b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .priv = 3}, 1395b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine*/ 1405b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 1415b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .bytesperline = 320, 1425b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .sizeimage = 320 * 240 * 4 / 8 + 590, 1435b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .colorspace = V4L2_COLORSPACE_JPEG, 1445b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .priv = 2}, 1455b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 1465b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .bytesperline = 640, 1475b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .sizeimage = 640 * 480 * 3 / 8 + 590, 1485b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .colorspace = V4L2_COLORSPACE_JPEG, 1495b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .priv = 1}, 1505b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine}; 1515b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 1525b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* read <len> bytes to gspca usb_buf */ 1535b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void reg_r(struct gspca_dev *gspca_dev, 1545b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 req, 1555b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u16 index, 1565b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine int len) 1575b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 1585b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#if USB_BUF_SZ < 64 1595b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#error "USB buffer too small" 1605b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#endif 1615b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct usb_device *dev = gspca_dev->dev; 1625b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine int ret; 1635b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 1645b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->usb_err < 0) 1655b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return; 1665b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 1675b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine req, 1685b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1695b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 0x0000, /* value */ 1705b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine index, 1715b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_buf, len, 1725b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 500); 1735b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index, 1745b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_buf[0]); 1755b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (ret < 0) { 176133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches pr_err("reg_r err %d\n", ret); 1775b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_err = ret; 1785b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } 1795b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 1805b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 1815b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void reg_w(struct gspca_dev *gspca_dev, 1825b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 req, 1835b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u16 value, 1845b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u16 index) 1855b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 1865b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct usb_device *dev = gspca_dev->dev; 1875b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine int ret; 1885b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 1895b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->usb_err < 0) 1905b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return; 1915b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index); 1925b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1935b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine req, 1945b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1955b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine value, index, 1965b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine NULL, 0, 500); 1975b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (ret < 0) { 198133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches pr_err("reg_w err %d\n", ret); 1995b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_err = ret; 2005b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } 2015b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2025b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2035b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void reg_wb(struct gspca_dev *gspca_dev, 2045b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 req, 2055b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u16 value, 2065b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u16 index, 2075b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 byte) 2085b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 2095b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct usb_device *dev = gspca_dev->dev; 2105b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine int ret; 2115b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2125b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->usb_err < 0) 2135b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return; 2145b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine PDEBUG(D_USBO, "SET %02x %04x %04x %02x", req, value, index, byte); 2155b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_buf[0] = byte; 2165b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 2175b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine req, 2185b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 2195b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine value, index, 2205b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_buf, 1, 500); 2215b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (ret < 0) { 222133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches pr_err("reg_w err %d\n", ret); 2235b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_err = ret; 2245b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } 2255b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2265b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2275b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void wait_status_0(struct gspca_dev *gspca_dev) 2285b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 2299ba4a4ba3c170e618f75213fb03fe2deda754195Jean-François Moine int i, w; 2305b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2319ba4a4ba3c170e618f75213fb03fe2deda754195Jean-François Moine i = 16; 2329ba4a4ba3c170e618f75213fb03fe2deda754195Jean-François Moine w = 0; 2335b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine do { 2345b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x21, 0x0000, 1); 2355b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->usb_buf[0] == 0) 2365b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return; 2379ba4a4ba3c170e618f75213fb03fe2deda754195Jean-François Moine w += 15; 2389ba4a4ba3c170e618f75213fb03fe2deda754195Jean-François Moine msleep(w); 2395b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } while (--i > 0); 2405b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine PDEBUG(D_ERR, "wait_status_0 timeout"); 2415b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_err = -ETIME; 2425b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2435b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2445b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void wait_status_1(struct gspca_dev *gspca_dev) 2455b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 2465b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine int i; 2475b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2485b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine i = 10; 2495b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine do { 2505b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x21, 0x0001, 1); 2515b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine msleep(10); 2525b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->usb_buf[0] == 1) { 2535b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_wb(gspca_dev, 0x21, 0x0000, 0x0001, 0x00); 2545b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x21, 0x0001, 1); 2555b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return; 2565b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } 2575b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } while (--i > 0); 2585b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine PDEBUG(D_ERR, "wait_status_1 timeout"); 2595b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->usb_err = -ETIME; 2605b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2615b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2625b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void setbrightness(struct gspca_dev *gspca_dev) 2635b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 2645b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 2655b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2665b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, sd->brightness); 2675b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2685b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2695b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void setcontrast(struct gspca_dev *gspca_dev) 2705b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 2715b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 2725b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2735b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, sd->contrast); 2745b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2755b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2765b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void sethue(struct gspca_dev *gspca_dev) 2775b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 2785b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 2795b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2805b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, sd->hue); 2815b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2825b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2835b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void setcolor(struct gspca_dev *gspca_dev) 2845b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 2855b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 2865b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2875b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, sd->color); 2885b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2895b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2905b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void setsharpness(struct gspca_dev *gspca_dev) 2915b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 2925b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 2935b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2945b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, sd->sharpness); 2955b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 2965b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 2975b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* this function is called at probe time */ 2985b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_config(struct gspca_dev *gspca_dev, 2995b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine const struct usb_device_id *id) 3005b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 3015b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 3025b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3035b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->cam.cam_mode = vga_mode; 3045b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); 3055b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */ 3065b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine /*fixme: 256 in ms-win traces*/ 3075b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3085b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->brightness = BRIGHTNESS_DEF; 3095b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->contrast = CONTRAST_DEF; 3105b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->hue = HUE_DEF; 3115b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->color = COLOR_DEF; 3125b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->sharpness = SHARPNESS_DEF; 3135b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3145b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return 0; 3155b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 3165b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3175b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* this function is called at probe and resume time */ 3185b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_init(struct gspca_dev *gspca_dev) 3195b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 3205b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_w(gspca_dev, 0x00, 0x0001, 0x2067); 3215b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_w(gspca_dev, 0x00, 0x00d0, 0x206b); 3225b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_w(gspca_dev, 0x00, 0x0000, 0x206c); 3235b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_w(gspca_dev, 0x00, 0x0001, 0x2069); 3245b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine msleep(8); 3255b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_w(gspca_dev, 0x00, 0x00c0, 0x206b); 3265b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_w(gspca_dev, 0x00, 0x0000, 0x206c); 3275b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_w(gspca_dev, 0x00, 0x0001, 0x2069); 3285b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3295b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x20, 0x0000, 1); 3305b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x20, 0x0000, 5); 3315b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x23, 0x0000, 64); 3325b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine PDEBUG(D_PROBE, "%s%s", &gspca_dev->usb_buf[0x1c], 3335b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine &gspca_dev->usb_buf[0x30]); 3345b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x23, 0x0001, 64); 3355b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev->usb_err; 3365b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 3375b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3385b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* function called at start time before URB creation */ 3395b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_isoc_init(struct gspca_dev *gspca_dev) 3405b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 3415b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 mode; 3425b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3435b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x00, 0x2520, 1); 3445b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_0(gspca_dev); 3455b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_w(gspca_dev, 0xc5, 0x0003, 0x0000); 3465b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_1(gspca_dev); 3475b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3485b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_0(gspca_dev); 3495b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 3505b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_wb(gspca_dev, 0x25, 0x0000, 0x0004, mode); 3515b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x25, 0x0004, 1); 3520dd826962716ff6984a14038d1604be816d759c3Jean-François Moine reg_wb(gspca_dev, 0x27, 0x0000, 0x0000, 0x06); /* 420 */ 3535b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x27, 0x0000, 1); 3546507b4232c2e136ccc338c3ed5c2f54b32b961b7Jean-François Moine 3556507b4232c2e136ccc338c3ed5c2f54b32b961b7Jean-François Moine/* not useful.. 3566507b4232c2e136ccc338c3ed5c2f54b32b961b7Jean-François Moine gspca_dev->alt = 4; * use alternate setting 3 */ 3576507b4232c2e136ccc338c3ed5c2f54b32b961b7Jean-François Moine 3585b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev->usb_err; 3595b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 3605b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3615b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* -- start the camera -- */ 3625b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_start(struct gspca_dev *gspca_dev) 3635b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 3645b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 3655b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3665b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine /* initialize the JPEG header */ 3675b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 3685b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 0x22); /* JPEG 411 */ 3695b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3703e12950d86d695bdaf762476446a60ed5073eedcJean-François Moine /* the JPEG quality shall be 85% */ 3713e12950d86d695bdaf762476446a60ed5073eedcJean-François Moine jpeg_set_qual(sd->jpeg_hdr, 85); 3725b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3735b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine /* set the controls */ 3745b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine setbrightness(gspca_dev); 3755b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine setcontrast(gspca_dev); 3765b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sethue(gspca_dev); 3775b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine setcolor(gspca_dev); 3785b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine setsharpness(gspca_dev); 3795b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3805b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine msleep(5); 3815b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine reg_r(gspca_dev, 0x00, 0x2520, 1); 3825b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine msleep(8); 3835b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3845b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine /* start the capture */ 3855b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_0(gspca_dev); 3860dd826962716ff6984a14038d1604be816d759c3Jean-François Moine reg_w(gspca_dev, 0x31, 0x0000, 0x0004); /* start request */ 3875b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_1(gspca_dev); 3885b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_0(gspca_dev); 3895b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine msleep(200); 3905b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3915b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->pkt_seq = 0; 3925b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev->usb_err; 3935b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 3945b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 3955b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void sd_stopN(struct gspca_dev *gspca_dev) 3965b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 3975b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine /* stop the capture */ 3985b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_0(gspca_dev); 3990dd826962716ff6984a14038d1604be816d759c3Jean-François Moine reg_w(gspca_dev, 0x31, 0x0000, 0x0000); /* stop request */ 4005b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_1(gspca_dev); 4015b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine wait_status_0(gspca_dev); 4025b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 4035b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4045b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* move a packet adding 0x00 after 0xff */ 4055b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void add_packet(struct gspca_dev *gspca_dev, 4065b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 *data, 4075b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine int len) 4085b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 4095b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine int i; 4105b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4115b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine i = 0; 4125b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine do { 4135b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (data[i] == 0xff) { 4145b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_frame_add(gspca_dev, INTER_PACKET, 4155b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine data, i + 1); 4165b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine len -= i; 4175b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine data += i; 4185b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine *data = 0x00; 4195b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine i = 0; 4205b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } 4215b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } while (++i < len); 4225b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 4235b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 4245b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4255b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic void sd_pkt_scan(struct gspca_dev *gspca_dev, 4265b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine u8 *data, /* isoc packet */ 4275b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine int len) /* iso packet length */ 4285b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 4295b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 4305b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine static const u8 ffd9[] = {0xff, 0xd9}; 4315b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4325b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine /* image packets start with: 4335b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * 02 8n 4345b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * with <n> bit: 4355b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * 0x01: even (0) / odd (1) image 4365b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine * 0x02: end of image when set 4375b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine */ 4385b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (len < 3) 4395b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return; /* empty packet */ 4405b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (*data == 0x02) { 4415b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (data[1] & 0x02) { 4425b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->pkt_seq = !(data[1] & 1); 4435b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine add_packet(gspca_dev, data + 2, len - 2); 4445b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_frame_add(gspca_dev, LAST_PACKET, 4455b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine ffd9, 2); 4465b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return; 4475b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } 4485b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if ((data[1] & 1) != sd->pkt_seq) 4495b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine goto err; 4505b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->last_packet_type == LAST_PACKET) 4515b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_frame_add(gspca_dev, FIRST_PACKET, 4525b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->jpeg_hdr, JPEG_HDR_SZ); 4535b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine add_packet(gspca_dev, data + 2, len - 2); 4545b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return; 4555b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine } 4565b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moineerr: 4575b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine gspca_dev->last_packet_type = DISCARD_PACKET; 4585b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 4595b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4605b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 4615b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 4625b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 4635b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4645b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->brightness = val; 4655b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->streaming) 4665b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine setbrightness(gspca_dev); 4675b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev->usb_err; 4685b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 4695b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4705b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 4715b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 4725b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 4735b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4745b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine *val = sd->brightness; 4755b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return 0; 4765b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 4775b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4785b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 4795b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 4805b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 4815b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4825b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->contrast = val; 4835b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->streaming) 4845b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine setcontrast(gspca_dev); 4855b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev->usb_err; 4865b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 4875b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4885b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 4895b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 4905b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 4915b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4925b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine *val = sd->contrast; 4935b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return 0; 4945b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 4955b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 4965b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) 4975b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 4985b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 4995b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5005b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->hue = val; 5015b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->streaming) 5025b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sethue(gspca_dev); 5035b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev->usb_err; 5045b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 5055b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5065b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) 5075b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 5085b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 5095b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5105b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine *val = sd->hue; 5115b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return 0; 5125b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 5135b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5145b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_setcolor(struct gspca_dev *gspca_dev, __s32 val) 5155b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 5165b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 5175b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5185b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->color = val; 5195b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->streaming) 5205b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine setcolor(gspca_dev); 5215b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev->usb_err; 5225b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 5235b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5245b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_getcolor(struct gspca_dev *gspca_dev, __s32 *val) 5255b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 5265b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 5275b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5285b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine *val = sd->color; 5295b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return 0; 5305b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 5315b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5325b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) 5335b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 5345b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 5355b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5365b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine sd->sharpness = val; 5375b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (gspca_dev->streaming) 5385b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine setsharpness(gspca_dev); 5395b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev->usb_err; 5405b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 5415b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5425b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) 5435b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 5445b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine struct sd *sd = (struct sd *) gspca_dev; 5455b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5465b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine *val = sd->sharpness; 5475b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return 0; 5485b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 5495b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5505b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* sub-driver description */ 5515b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic const struct sd_desc sd_desc = { 5525b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .name = MODULE_NAME, 5535b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .ctrls = sd_ctrls, 5545b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .nctrls = ARRAY_SIZE(sd_ctrls), 5555b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .config = sd_config, 5565b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .init = sd_init, 5575b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .isoc_init = sd_isoc_init, 5585b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .start = sd_start, 5595b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .stopN = sd_stopN, 5605b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .pkt_scan = sd_pkt_scan, 5615b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine}; 5625b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5635b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* -- module initialisation -- */ 56495c967c167785eb991cf6b22fb854dd8d61d0ff8Jean-François Moinestatic const struct usb_device_id device_table[] = { 5655b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine {USB_DEVICE(0x04fc, 0x1528)}, 5665b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine {} 5675b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine}; 5685b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François MoineMODULE_DEVICE_TABLE(usb, device_table); 5695b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5705b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine/* -- device connect -- */ 5715b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic int sd_probe(struct usb_interface *intf, 5725b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine const struct usb_device_id *id) 5735b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine{ 5745b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine /* the video interface for isochronous transfer is 1 */ 5755b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine if (intf->cur_altsetting->desc.bInterfaceNumber != 1) 5765b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return -ENODEV; 5775b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5785b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd), 5795b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine THIS_MODULE); 5805b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine} 5815b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 5825b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moinestatic struct usb_driver sd_driver = { 5835b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .name = MODULE_NAME, 5845b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .id_table = device_table, 5855b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .probe = sd_probe, 5865b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .disconnect = gspca_disconnect, 5875b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#ifdef CONFIG_PM 5885b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .suspend = gspca_suspend, 5895b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine .resume = gspca_resume, 5905b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine#endif 5915b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine}; 5925b0ff8c43afefbd42a1aa3cd89808eec829bbbb7Jean-François Moine 593ecb3b2b35db49778b6d89e3ffd0c400776c20735Greg Kroah-Hartmanmodule_usb_driver(sd_driver); 594