Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * spca1528 subdriver
0004  *
0005  * Copyright (C) 2010-2011 Jean-Francois Moine (http://moinejf.free.fr)
0006  */
0007 
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 
0010 #define MODULE_NAME "spca1528"
0011 
0012 #include "gspca.h"
0013 #include "jpeg.h"
0014 
0015 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
0016 MODULE_DESCRIPTION("SPCA1528 USB Camera Driver");
0017 MODULE_LICENSE("GPL");
0018 
0019 /* specific webcam descriptor */
0020 struct sd {
0021     struct gspca_dev gspca_dev; /* !! must be the first item */
0022 
0023     u8 pkt_seq;
0024 
0025     u8 jpeg_hdr[JPEG_HDR_SZ];
0026 };
0027 
0028 static const struct v4l2_pix_format vga_mode[] = {
0029 /*      (does not work correctly)
0030     {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0031         .bytesperline = 176,
0032         .sizeimage = 176 * 144 * 5 / 8 + 590,
0033         .colorspace = V4L2_COLORSPACE_JPEG,
0034         .priv = 3},
0035 */
0036     {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0037         .bytesperline = 320,
0038         .sizeimage = 320 * 240 * 4 / 8 + 590,
0039         .colorspace = V4L2_COLORSPACE_JPEG,
0040         .priv = 2},
0041     {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0042         .bytesperline = 640,
0043         .sizeimage = 640 * 480 * 3 / 8 + 590,
0044         .colorspace = V4L2_COLORSPACE_JPEG,
0045         .priv = 1},
0046 };
0047 
0048 /* read <len> bytes to gspca usb_buf */
0049 static void reg_r(struct gspca_dev *gspca_dev,
0050             u8 req,
0051             u16 index,
0052             int len)
0053 {
0054 #if USB_BUF_SZ < 64
0055 #error "USB buffer too small"
0056 #endif
0057     struct usb_device *dev = gspca_dev->dev;
0058     int ret;
0059 
0060     if (gspca_dev->usb_err < 0)
0061         return;
0062     ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0063             req,
0064             USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0065             0x0000,         /* value */
0066             index,
0067             gspca_dev->usb_buf, len,
0068             500);
0069     gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n", req, index,
0070           gspca_dev->usb_buf[0]);
0071     if (ret < 0) {
0072         pr_err("reg_r err %d\n", ret);
0073         gspca_dev->usb_err = ret;
0074         /*
0075          * Make sure the buffer is zeroed to avoid uninitialized
0076          * values.
0077          */
0078         memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
0079     }
0080 }
0081 
0082 static void reg_w(struct gspca_dev *gspca_dev,
0083             u8 req,
0084             u16 value,
0085             u16 index)
0086 {
0087     struct usb_device *dev = gspca_dev->dev;
0088     int ret;
0089 
0090     if (gspca_dev->usb_err < 0)
0091         return;
0092     gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n", req, value, index);
0093     ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0094             req,
0095             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0096             value, index,
0097             NULL, 0, 500);
0098     if (ret < 0) {
0099         pr_err("reg_w err %d\n", ret);
0100         gspca_dev->usb_err = ret;
0101     }
0102 }
0103 
0104 static void reg_wb(struct gspca_dev *gspca_dev,
0105             u8 req,
0106             u16 value,
0107             u16 index,
0108             u8 byte)
0109 {
0110     struct usb_device *dev = gspca_dev->dev;
0111     int ret;
0112 
0113     if (gspca_dev->usb_err < 0)
0114         return;
0115     gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x %02x\n",
0116           req, value, index, byte);
0117     gspca_dev->usb_buf[0] = byte;
0118     ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0119             req,
0120             USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0121             value, index,
0122             gspca_dev->usb_buf, 1, 500);
0123     if (ret < 0) {
0124         pr_err("reg_w err %d\n", ret);
0125         gspca_dev->usb_err = ret;
0126     }
0127 }
0128 
0129 static void wait_status_0(struct gspca_dev *gspca_dev)
0130 {
0131     int i, w;
0132 
0133     i = 16;
0134     w = 0;
0135     do {
0136         reg_r(gspca_dev, 0x21, 0x0000, 1);
0137         if (gspca_dev->usb_buf[0] == 0)
0138             return;
0139         w += 15;
0140         msleep(w);
0141     } while (--i > 0);
0142     gspca_err(gspca_dev, "wait_status_0 timeout\n");
0143     gspca_dev->usb_err = -ETIME;
0144 }
0145 
0146 static void wait_status_1(struct gspca_dev *gspca_dev)
0147 {
0148     int i;
0149 
0150     i = 10;
0151     do {
0152         reg_r(gspca_dev, 0x21, 0x0001, 1);
0153         msleep(10);
0154         if (gspca_dev->usb_buf[0] == 1) {
0155             reg_wb(gspca_dev, 0x21, 0x0000, 0x0001, 0x00);
0156             reg_r(gspca_dev, 0x21, 0x0001, 1);
0157             return;
0158         }
0159     } while (--i > 0);
0160     gspca_err(gspca_dev, "wait_status_1 timeout\n");
0161     gspca_dev->usb_err = -ETIME;
0162 }
0163 
0164 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
0165 {
0166     reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, val);
0167 }
0168 
0169 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
0170 {
0171     reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, val);
0172 }
0173 
0174 static void sethue(struct gspca_dev *gspca_dev, s32 val)
0175 {
0176     reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, val);
0177 }
0178 
0179 static void setcolor(struct gspca_dev *gspca_dev, s32 val)
0180 {
0181     reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, val);
0182 }
0183 
0184 static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
0185 {
0186     reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, val);
0187 }
0188 
0189 /* this function is called at probe time */
0190 static int sd_config(struct gspca_dev *gspca_dev,
0191             const struct usb_device_id *id)
0192 {
0193     gspca_dev->cam.cam_mode = vga_mode;
0194     gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
0195     gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */
0196             /*fixme: 256 in ms-win traces*/
0197 
0198     return 0;
0199 }
0200 
0201 /* this function is called at probe and resume time */
0202 static int sd_init(struct gspca_dev *gspca_dev)
0203 {
0204     reg_w(gspca_dev, 0x00, 0x0001, 0x2067);
0205     reg_w(gspca_dev, 0x00, 0x00d0, 0x206b);
0206     reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
0207     reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
0208     msleep(8);
0209     reg_w(gspca_dev, 0x00, 0x00c0, 0x206b);
0210     reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
0211     reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
0212 
0213     reg_r(gspca_dev, 0x20, 0x0000, 1);
0214     reg_r(gspca_dev, 0x20, 0x0000, 5);
0215     reg_r(gspca_dev, 0x23, 0x0000, 64);
0216     gspca_dbg(gspca_dev, D_PROBE, "%s%s\n", &gspca_dev->usb_buf[0x1c],
0217           &gspca_dev->usb_buf[0x30]);
0218     reg_r(gspca_dev, 0x23, 0x0001, 64);
0219     return gspca_dev->usb_err;
0220 }
0221 
0222 /* function called at start time before URB creation */
0223 static int sd_isoc_init(struct gspca_dev *gspca_dev)
0224 {
0225     u8 mode;
0226 
0227     reg_r(gspca_dev, 0x00, 0x2520, 1);
0228     wait_status_0(gspca_dev);
0229     reg_w(gspca_dev, 0xc5, 0x0003, 0x0000);
0230     wait_status_1(gspca_dev);
0231 
0232     wait_status_0(gspca_dev);
0233     mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
0234     reg_wb(gspca_dev, 0x25, 0x0000, 0x0004, mode);
0235     reg_r(gspca_dev, 0x25, 0x0004, 1);
0236     reg_wb(gspca_dev, 0x27, 0x0000, 0x0000, 0x06);  /* 420 */
0237     reg_r(gspca_dev, 0x27, 0x0000, 1);
0238 
0239 /* not useful..
0240     gspca_dev->alt = 4;     * use alternate setting 3 */
0241 
0242     return gspca_dev->usb_err;
0243 }
0244 
0245 /* -- start the camera -- */
0246 static int sd_start(struct gspca_dev *gspca_dev)
0247 {
0248     struct sd *sd = (struct sd *) gspca_dev;
0249 
0250     /* initialize the JPEG header */
0251     jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
0252             gspca_dev->pixfmt.width,
0253             0x22);      /* JPEG 411 */
0254 
0255     /* the JPEG quality shall be 85% */
0256     jpeg_set_qual(sd->jpeg_hdr, 85);
0257 
0258     reg_r(gspca_dev, 0x00, 0x2520, 1);
0259     msleep(8);
0260 
0261     /* start the capture */
0262     wait_status_0(gspca_dev);
0263     reg_w(gspca_dev, 0x31, 0x0000, 0x0004); /* start request */
0264     wait_status_1(gspca_dev);
0265     wait_status_0(gspca_dev);
0266     msleep(200);
0267 
0268     sd->pkt_seq = 0;
0269     return gspca_dev->usb_err;
0270 }
0271 
0272 static void sd_stopN(struct gspca_dev *gspca_dev)
0273 {
0274     /* stop the capture */
0275     wait_status_0(gspca_dev);
0276     reg_w(gspca_dev, 0x31, 0x0000, 0x0000); /* stop request */
0277     wait_status_1(gspca_dev);
0278     wait_status_0(gspca_dev);
0279 }
0280 
0281 /* move a packet adding 0x00 after 0xff */
0282 static void add_packet(struct gspca_dev *gspca_dev,
0283             u8 *data,
0284             int len)
0285 {
0286     int i;
0287 
0288     i = 0;
0289     do {
0290         if (data[i] == 0xff) {
0291             gspca_frame_add(gspca_dev, INTER_PACKET,
0292                     data, i + 1);
0293             len -= i;
0294             data += i;
0295             *data = 0x00;
0296             i = 0;
0297         }
0298     } while (++i < len);
0299     gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
0300 }
0301 
0302 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
0303             u8 *data,           /* isoc packet */
0304             int len)            /* iso packet length */
0305 {
0306     struct sd *sd = (struct sd *) gspca_dev;
0307     static const u8 ffd9[] = {0xff, 0xd9};
0308 
0309     /* image packets start with:
0310      *  02 8n
0311      * with <n> bit:
0312      *  0x01: even (0) / odd (1) image
0313      *  0x02: end of image when set
0314      */
0315     if (len < 3)
0316         return;             /* empty packet */
0317     if (*data == 0x02) {
0318         if (data[1] & 0x02) {
0319             sd->pkt_seq = !(data[1] & 1);
0320             add_packet(gspca_dev, data + 2, len - 2);
0321             gspca_frame_add(gspca_dev, LAST_PACKET,
0322                     ffd9, 2);
0323             return;
0324         }
0325         if ((data[1] & 1) != sd->pkt_seq)
0326             goto err;
0327         if (gspca_dev->last_packet_type == LAST_PACKET)
0328             gspca_frame_add(gspca_dev, FIRST_PACKET,
0329                     sd->jpeg_hdr, JPEG_HDR_SZ);
0330         add_packet(gspca_dev, data + 2, len - 2);
0331         return;
0332     }
0333 err:
0334     gspca_dev->last_packet_type = DISCARD_PACKET;
0335 }
0336 
0337 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
0338 {
0339     struct gspca_dev *gspca_dev =
0340         container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
0341 
0342     gspca_dev->usb_err = 0;
0343 
0344     if (!gspca_dev->streaming)
0345         return 0;
0346 
0347     switch (ctrl->id) {
0348     case V4L2_CID_BRIGHTNESS:
0349         setbrightness(gspca_dev, ctrl->val);
0350         break;
0351     case V4L2_CID_CONTRAST:
0352         setcontrast(gspca_dev, ctrl->val);
0353         break;
0354     case V4L2_CID_HUE:
0355         sethue(gspca_dev, ctrl->val);
0356         break;
0357     case V4L2_CID_SATURATION:
0358         setcolor(gspca_dev, ctrl->val);
0359         break;
0360     case V4L2_CID_SHARPNESS:
0361         setsharpness(gspca_dev, ctrl->val);
0362         break;
0363     }
0364     return gspca_dev->usb_err;
0365 }
0366 
0367 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
0368     .s_ctrl = sd_s_ctrl,
0369 };
0370 
0371 static int sd_init_controls(struct gspca_dev *gspca_dev)
0372 {
0373     struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
0374 
0375     gspca_dev->vdev.ctrl_handler = hdl;
0376     v4l2_ctrl_handler_init(hdl, 5);
0377     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0378             V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
0379     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0380             V4L2_CID_CONTRAST, 0, 8, 1, 1);
0381     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0382             V4L2_CID_HUE, 0, 255, 1, 0);
0383     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0384             V4L2_CID_SATURATION, 0, 8, 1, 1);
0385     v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0386             V4L2_CID_SHARPNESS, 0, 255, 1, 0);
0387 
0388     if (hdl->error) {
0389         pr_err("Could not initialize controls\n");
0390         return hdl->error;
0391     }
0392     return 0;
0393 }
0394 
0395 /* sub-driver description */
0396 static const struct sd_desc sd_desc = {
0397     .name = MODULE_NAME,
0398     .config = sd_config,
0399     .init = sd_init,
0400     .init_controls = sd_init_controls,
0401     .isoc_init = sd_isoc_init,
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(0x04fc, 0x1528)},
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     /* the video interface for isochronous transfer is 1 */
0419     if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
0420         return -ENODEV;
0421 
0422     return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd),
0423                 THIS_MODULE);
0424 }
0425 
0426 static struct usb_driver sd_driver = {
0427     .name = MODULE_NAME,
0428     .id_table = device_table,
0429     .probe = sd_probe,
0430     .disconnect = gspca_disconnect,
0431 #ifdef CONFIG_PM
0432     .suspend = gspca_suspend,
0433     .resume = gspca_resume,
0434     .reset_resume = gspca_resume,
0435 #endif
0436 };
0437 
0438 module_usb_driver(sd_driver);