Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Syntek DV4000 (STK014) subdriver
0004  *
0005  * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
0006  */
0007 
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 
0010 #define MODULE_NAME "stk014"
0011 
0012 #include "gspca.h"
0013 #include "jpeg.h"
0014 
0015 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
0016 MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
0017 MODULE_LICENSE("GPL");
0018 
0019 #define QUALITY 50
0020 
0021 /* specific webcam descriptor */
0022 struct sd {
0023     struct gspca_dev gspca_dev; /* !! must be the first item */
0024     u8 jpeg_hdr[JPEG_HDR_SZ];
0025 };
0026 
0027 static const struct v4l2_pix_format vga_mode[] = {
0028     {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0029         .bytesperline = 320,
0030         .sizeimage = 320 * 240 * 3 / 8 + 590,
0031         .colorspace = V4L2_COLORSPACE_JPEG,
0032         .priv = 1},
0033     {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0034         .bytesperline = 640,
0035         .sizeimage = 640 * 480 * 3 / 8 + 590,
0036         .colorspace = V4L2_COLORSPACE_JPEG,
0037         .priv = 0},
0038 };
0039 
0040 /* -- read a register -- */
0041 static u8 reg_r(struct gspca_dev *gspca_dev,
0042             __u16 index)
0043 {
0044     struct usb_device *dev = gspca_dev->dev;
0045     int ret;
0046 
0047     if (gspca_dev->usb_err < 0)
0048         return 0;
0049     ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0050             0x00,
0051             USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0052             0x00,
0053             index,
0054             gspca_dev->usb_buf, 1,
0055             500);
0056     if (ret < 0) {
0057         pr_err("reg_r err %d\n", ret);
0058         gspca_dev->usb_err = ret;
0059         return 0;
0060     }
0061     return gspca_dev->usb_buf[0];
0062 }
0063 
0064 /* -- write a register -- */
0065 static void reg_w(struct gspca_dev *gspca_dev,
0066             __u16 index, __u16 value)
0067 {
0068     struct usb_device *dev = gspca_dev->dev;
0069     int ret;
0070 
0071     if (gspca_dev->usb_err < 0)
0072         return;
0073     ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0074             0x01,
0075             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0076             value,
0077             index,
0078             NULL,
0079             0,
0080             500);
0081     if (ret < 0) {
0082         pr_err("reg_w err %d\n", ret);
0083         gspca_dev->usb_err = ret;
0084     }
0085 }
0086 
0087 /* -- get a bulk value (4 bytes) -- */
0088 static void rcv_val(struct gspca_dev *gspca_dev,
0089             int ads)
0090 {
0091     struct usb_device *dev = gspca_dev->dev;
0092     int alen, ret;
0093 
0094     reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
0095     reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
0096     reg_w(gspca_dev, 0x636, ads & 0xff);
0097     reg_w(gspca_dev, 0x637, 0);
0098     reg_w(gspca_dev, 0x638, 4); /* len & 0xff */
0099     reg_w(gspca_dev, 0x639, 0); /* len >> 8 */
0100     reg_w(gspca_dev, 0x63a, 0);
0101     reg_w(gspca_dev, 0x63b, 0);
0102     reg_w(gspca_dev, 0x630, 5);
0103     if (gspca_dev->usb_err < 0)
0104         return;
0105     ret = usb_bulk_msg(dev,
0106             usb_rcvbulkpipe(dev, 0x05),
0107             gspca_dev->usb_buf,
0108             4,      /* length */
0109             &alen,
0110             500);       /* timeout in milliseconds */
0111     if (ret < 0) {
0112         pr_err("rcv_val err %d\n", ret);
0113         gspca_dev->usb_err = ret;
0114     }
0115 }
0116 
0117 /* -- send a bulk value -- */
0118 static void snd_val(struct gspca_dev *gspca_dev,
0119             int ads,
0120             unsigned int val)
0121 {
0122     struct usb_device *dev = gspca_dev->dev;
0123     int alen, ret;
0124     __u8 seq = 0;
0125 
0126     if (ads == 0x003f08) {
0127         reg_r(gspca_dev, 0x0704);
0128         seq = reg_r(gspca_dev, 0x0705);
0129         reg_r(gspca_dev, 0x0650);
0130         reg_w(gspca_dev, 0x654, seq);
0131     } else {
0132         reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
0133     }
0134     reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
0135     reg_w(gspca_dev, 0x656, ads & 0xff);
0136     reg_w(gspca_dev, 0x657, 0);
0137     reg_w(gspca_dev, 0x658, 0x04);  /* size */
0138     reg_w(gspca_dev, 0x659, 0);
0139     reg_w(gspca_dev, 0x65a, 0);
0140     reg_w(gspca_dev, 0x65b, 0);
0141     reg_w(gspca_dev, 0x650, 5);
0142     if (gspca_dev->usb_err < 0)
0143         return;
0144     gspca_dev->usb_buf[0] = val >> 24;
0145     gspca_dev->usb_buf[1] = val >> 16;
0146     gspca_dev->usb_buf[2] = val >> 8;
0147     gspca_dev->usb_buf[3] = val;
0148     ret = usb_bulk_msg(dev,
0149             usb_sndbulkpipe(dev, 6),
0150             gspca_dev->usb_buf,
0151             4,
0152             &alen,
0153             500);   /* timeout in milliseconds */
0154     if (ret < 0) {
0155         pr_err("snd_val err %d\n", ret);
0156         gspca_dev->usb_err = ret;
0157     } else {
0158         if (ads == 0x003f08) {
0159             seq += 4;
0160             seq &= 0x3f;
0161             reg_w(gspca_dev, 0x705, seq);
0162         }
0163     }
0164 }
0165 
0166 /* set a camera parameter */
0167 static void set_par(struct gspca_dev *gspca_dev,
0168            int parval)
0169 {
0170     snd_val(gspca_dev, 0x003f08, parval);
0171 }
0172 
0173 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
0174 {
0175     int parval;
0176 
0177     parval = 0x06000000     /* whiteness */
0178         + (val << 16);
0179     set_par(gspca_dev, parval);
0180 }
0181 
0182 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
0183 {
0184     int parval;
0185 
0186     parval = 0x07000000     /* contrast */
0187         + (val << 16);
0188     set_par(gspca_dev, parval);
0189 }
0190 
0191 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
0192 {
0193     int parval;
0194 
0195     parval = 0x08000000     /* saturation */
0196         + (val << 16);
0197     set_par(gspca_dev, parval);
0198 }
0199 
0200 static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
0201 {
0202     set_par(gspca_dev, val == 1
0203             ? 0x33640000        /* 50 Hz */
0204             : 0x33780000);      /* 60 Hz */
0205 }
0206 
0207 /* this function is called at probe time */
0208 static int sd_config(struct gspca_dev *gspca_dev,
0209             const struct usb_device_id *id)
0210 {
0211     gspca_dev->cam.cam_mode = vga_mode;
0212     gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
0213     return 0;
0214 }
0215 
0216 /* this function is called at probe and resume time */
0217 static int sd_init(struct gspca_dev *gspca_dev)
0218 {
0219     u8 ret;
0220 
0221     /* check if the device responds */
0222     usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
0223     ret = reg_r(gspca_dev, 0x0740);
0224     if (gspca_dev->usb_err >= 0) {
0225         if (ret != 0xff) {
0226             pr_err("init reg: 0x%02x\n", ret);
0227             gspca_dev->usb_err = -EIO;
0228         }
0229     }
0230     return gspca_dev->usb_err;
0231 }
0232 
0233 /* -- start the camera -- */
0234 static int sd_start(struct gspca_dev *gspca_dev)
0235 {
0236     struct sd *sd = (struct sd *) gspca_dev;
0237     int ret, value;
0238 
0239     /* create the JPEG header */
0240     jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
0241             gspca_dev->pixfmt.width,
0242             0x22);      /* JPEG 411 */
0243     jpeg_set_qual(sd->jpeg_hdr, QUALITY);
0244 
0245     /* work on alternate 1 */
0246     usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
0247 
0248     set_par(gspca_dev, 0x10000000);
0249     set_par(gspca_dev, 0x00000000);
0250     set_par(gspca_dev, 0x8002e001);
0251     set_par(gspca_dev, 0x14000000);
0252     if (gspca_dev->pixfmt.width > 320)
0253         value = 0x8002e001;     /* 640x480 */
0254     else
0255         value = 0x4001f000;     /* 320x240 */
0256     set_par(gspca_dev, value);
0257     ret = usb_set_interface(gspca_dev->dev,
0258                     gspca_dev->iface,
0259                     gspca_dev->alt);
0260     if (ret < 0) {
0261         pr_err("set intf %d %d failed\n",
0262                gspca_dev->iface, gspca_dev->alt);
0263         gspca_dev->usb_err = ret;
0264         goto out;
0265     }
0266     reg_r(gspca_dev, 0x0630);
0267     rcv_val(gspca_dev, 0x000020);   /* << (value ff ff ff ff) */
0268     reg_r(gspca_dev, 0x0650);
0269     snd_val(gspca_dev, 0x000020, 0xffffffff);
0270     reg_w(gspca_dev, 0x0620, 0);
0271     reg_w(gspca_dev, 0x0630, 0);
0272     reg_w(gspca_dev, 0x0640, 0);
0273     reg_w(gspca_dev, 0x0650, 0);
0274     reg_w(gspca_dev, 0x0660, 0);
0275     set_par(gspca_dev, 0x09800000);     /* Red ? */
0276     set_par(gspca_dev, 0x0a800000);     /* Green ? */
0277     set_par(gspca_dev, 0x0b800000);     /* Blue ? */
0278     set_par(gspca_dev, 0x0d030000);     /* Gamma ? */
0279 
0280     /* start the video flow */
0281     set_par(gspca_dev, 0x01000000);
0282     set_par(gspca_dev, 0x01000000);
0283     if (gspca_dev->usb_err >= 0)
0284         gspca_dbg(gspca_dev, D_STREAM, "camera started alt: 0x%02x\n",
0285               gspca_dev->alt);
0286 out:
0287     return gspca_dev->usb_err;
0288 }
0289 
0290 static void sd_stopN(struct gspca_dev *gspca_dev)
0291 {
0292     struct usb_device *dev = gspca_dev->dev;
0293 
0294     set_par(gspca_dev, 0x02000000);
0295     set_par(gspca_dev, 0x02000000);
0296     usb_set_interface(dev, gspca_dev->iface, 1);
0297     reg_r(gspca_dev, 0x0630);
0298     rcv_val(gspca_dev, 0x000020);   /* << (value ff ff ff ff) */
0299     reg_r(gspca_dev, 0x0650);
0300     snd_val(gspca_dev, 0x000020, 0xffffffff);
0301     reg_w(gspca_dev, 0x0620, 0);
0302     reg_w(gspca_dev, 0x0630, 0);
0303     reg_w(gspca_dev, 0x0640, 0);
0304     reg_w(gspca_dev, 0x0650, 0);
0305     reg_w(gspca_dev, 0x0660, 0);
0306     gspca_dbg(gspca_dev, D_STREAM, "camera stopped\n");
0307 }
0308 
0309 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
0310             u8 *data,           /* isoc packet */
0311             int len)            /* iso packet length */
0312 {
0313     struct sd *sd = (struct sd *) gspca_dev;
0314     static unsigned char ffd9[] = {0xff, 0xd9};
0315 
0316     /* a frame starts with:
0317      *  - 0xff 0xfe
0318      *  - 0x08 0x00 - length (little endian ?!)
0319      *  - 4 bytes = size of whole frame (BE - including header)
0320      *  - 0x00 0x0c
0321      *  - 0xff 0xd8
0322      *  - ..    JPEG image with escape sequences (ff 00)
0323      *      (without ending - ff d9)
0324      */
0325     if (data[0] == 0xff && data[1] == 0xfe) {
0326         gspca_frame_add(gspca_dev, LAST_PACKET,
0327                 ffd9, 2);
0328 
0329         /* put the JPEG 411 header */
0330         gspca_frame_add(gspca_dev, FIRST_PACKET,
0331             sd->jpeg_hdr, JPEG_HDR_SZ);
0332 
0333         /* beginning of the frame */
0334 #define STKHDRSZ 12
0335         data += STKHDRSZ;
0336         len -= STKHDRSZ;
0337     }
0338     gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
0339 }
0340 
0341 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
0342 {
0343     struct gspca_dev *gspca_dev =
0344         container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
0345 
0346     gspca_dev->usb_err = 0;
0347 
0348     if (!gspca_dev->streaming)
0349         return 0;
0350 
0351     switch (ctrl->id) {
0352     case V4L2_CID_BRIGHTNESS:
0353         setbrightness(gspca_dev, ctrl->val);
0354         break;
0355     case V4L2_CID_CONTRAST:
0356         setcontrast(gspca_dev, ctrl->val);
0357         break;
0358     case V4L2_CID_SATURATION:
0359         setcolors(gspca_dev, ctrl->val);
0360         break;
0361     case V4L2_CID_POWER_LINE_FREQUENCY:
0362         setlightfreq(gspca_dev, ctrl->val);
0363         break;
0364     }
0365     return gspca_dev->usb_err;
0366 }
0367 
0368 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
0369     .s_ctrl = sd_s_ctrl,
0370 };
0371 
0372 static int sd_init_controls(struct gspca_dev *gspca_dev)
0373 {
0374     struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
0375 
0376     gspca_dev->vdev.ctrl_handler = hdl;
0377     v4l2_ctrl_handler_init(hdl, 4);
0378     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0379             V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
0380     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0381             V4L2_CID_CONTRAST, 0, 255, 1, 127);
0382     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0383             V4L2_CID_SATURATION, 0, 255, 1, 127);
0384     v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
0385             V4L2_CID_POWER_LINE_FREQUENCY,
0386             V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
0387             V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
0388 
0389     if (hdl->error) {
0390         pr_err("Could not initialize controls\n");
0391         return hdl->error;
0392     }
0393     return 0;
0394 }
0395 
0396 /* sub-driver description */
0397 static const struct sd_desc sd_desc = {
0398     .name = MODULE_NAME,
0399     .config = sd_config,
0400     .init = sd_init,
0401     .init_controls = sd_init_controls,
0402     .start = sd_start,
0403     .stopN = sd_stopN,
0404     .pkt_scan = sd_pkt_scan,
0405 };
0406 
0407 /* -- module initialisation -- */
0408 static const struct usb_device_id device_table[] = {
0409     {USB_DEVICE(0x05e1, 0x0893)},
0410     {}
0411 };
0412 MODULE_DEVICE_TABLE(usb, device_table);
0413 
0414 /* -- device connect -- */
0415 static int sd_probe(struct usb_interface *intf,
0416             const struct usb_device_id *id)
0417 {
0418     return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
0419                 THIS_MODULE);
0420 }
0421 
0422 static struct usb_driver sd_driver = {
0423     .name = MODULE_NAME,
0424     .id_table = device_table,
0425     .probe = sd_probe,
0426     .disconnect = gspca_disconnect,
0427 #ifdef CONFIG_PM
0428     .suspend = gspca_suspend,
0429     .resume = gspca_resume,
0430     .reset_resume = gspca_resume,
0431 #endif
0432 };
0433 
0434 module_usb_driver(sd_driver);