root/drivers/media/usb/gspca/spca1528.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. reg_r
  2. reg_w
  3. reg_wb
  4. wait_status_0
  5. wait_status_1
  6. setbrightness
  7. setcontrast
  8. sethue
  9. setcolor
  10. setsharpness
  11. sd_config
  12. sd_init
  13. sd_isoc_init
  14. sd_start
  15. sd_stopN
  16. add_packet
  17. sd_pkt_scan
  18. sd_s_ctrl
  19. sd_init_controls
  20. sd_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * spca1528 subdriver
   4  *
   5  * Copyright (C) 2010-2011 Jean-Francois Moine (http://moinejf.free.fr)
   6  */
   7 
   8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9 
  10 #define MODULE_NAME "spca1528"
  11 
  12 #include "gspca.h"
  13 #include "jpeg.h"
  14 
  15 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
  16 MODULE_DESCRIPTION("SPCA1528 USB Camera Driver");
  17 MODULE_LICENSE("GPL");
  18 
  19 /* specific webcam descriptor */
  20 struct sd {
  21         struct gspca_dev gspca_dev;     /* !! must be the first item */
  22 
  23         u8 pkt_seq;
  24 
  25         u8 jpeg_hdr[JPEG_HDR_SZ];
  26 };
  27 
  28 static const struct v4l2_pix_format vga_mode[] = {
  29 /*              (does not work correctly)
  30         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  31                 .bytesperline = 176,
  32                 .sizeimage = 176 * 144 * 5 / 8 + 590,
  33                 .colorspace = V4L2_COLORSPACE_JPEG,
  34                 .priv = 3},
  35 */
  36         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  37                 .bytesperline = 320,
  38                 .sizeimage = 320 * 240 * 4 / 8 + 590,
  39                 .colorspace = V4L2_COLORSPACE_JPEG,
  40                 .priv = 2},
  41         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  42                 .bytesperline = 640,
  43                 .sizeimage = 640 * 480 * 3 / 8 + 590,
  44                 .colorspace = V4L2_COLORSPACE_JPEG,
  45                 .priv = 1},
  46 };
  47 
  48 /* read <len> bytes to gspca usb_buf */
  49 static void reg_r(struct gspca_dev *gspca_dev,
  50                         u8 req,
  51                         u16 index,
  52                         int len)
  53 {
  54 #if USB_BUF_SZ < 64
  55 #error "USB buffer too small"
  56 #endif
  57         struct usb_device *dev = gspca_dev->dev;
  58         int ret;
  59 
  60         if (gspca_dev->usb_err < 0)
  61                 return;
  62         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
  63                         req,
  64                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  65                         0x0000,                 /* value */
  66                         index,
  67                         gspca_dev->usb_buf, len,
  68                         500);
  69         gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n", req, index,
  70                   gspca_dev->usb_buf[0]);
  71         if (ret < 0) {
  72                 pr_err("reg_r err %d\n", ret);
  73                 gspca_dev->usb_err = ret;
  74                 /*
  75                  * Make sure the buffer is zeroed to avoid uninitialized
  76                  * values.
  77                  */
  78                 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
  79         }
  80 }
  81 
  82 static void reg_w(struct gspca_dev *gspca_dev,
  83                         u8 req,
  84                         u16 value,
  85                         u16 index)
  86 {
  87         struct usb_device *dev = gspca_dev->dev;
  88         int ret;
  89 
  90         if (gspca_dev->usb_err < 0)
  91                 return;
  92         gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n", req, value, index);
  93         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
  94                         req,
  95                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  96                         value, index,
  97                         NULL, 0, 500);
  98         if (ret < 0) {
  99                 pr_err("reg_w err %d\n", ret);
 100                 gspca_dev->usb_err = ret;
 101         }
 102 }
 103 
 104 static void reg_wb(struct gspca_dev *gspca_dev,
 105                         u8 req,
 106                         u16 value,
 107                         u16 index,
 108                         u8 byte)
 109 {
 110         struct usb_device *dev = gspca_dev->dev;
 111         int ret;
 112 
 113         if (gspca_dev->usb_err < 0)
 114                 return;
 115         gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x %02x\n",
 116                   req, value, index, byte);
 117         gspca_dev->usb_buf[0] = byte;
 118         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 119                         req,
 120                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 121                         value, index,
 122                         gspca_dev->usb_buf, 1, 500);
 123         if (ret < 0) {
 124                 pr_err("reg_w err %d\n", ret);
 125                 gspca_dev->usb_err = ret;
 126         }
 127 }
 128 
 129 static void wait_status_0(struct gspca_dev *gspca_dev)
 130 {
 131         int i, w;
 132 
 133         i = 16;
 134         w = 0;
 135         do {
 136                 reg_r(gspca_dev, 0x21, 0x0000, 1);
 137                 if (gspca_dev->usb_buf[0] == 0)
 138                         return;
 139                 w += 15;
 140                 msleep(w);
 141         } while (--i > 0);
 142         gspca_err(gspca_dev, "wait_status_0 timeout\n");
 143         gspca_dev->usb_err = -ETIME;
 144 }
 145 
 146 static void wait_status_1(struct gspca_dev *gspca_dev)
 147 {
 148         int i;
 149 
 150         i = 10;
 151         do {
 152                 reg_r(gspca_dev, 0x21, 0x0001, 1);
 153                 msleep(10);
 154                 if (gspca_dev->usb_buf[0] == 1) {
 155                         reg_wb(gspca_dev, 0x21, 0x0000, 0x0001, 0x00);
 156                         reg_r(gspca_dev, 0x21, 0x0001, 1);
 157                         return;
 158                 }
 159         } while (--i > 0);
 160         gspca_err(gspca_dev, "wait_status_1 timeout\n");
 161         gspca_dev->usb_err = -ETIME;
 162 }
 163 
 164 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
 165 {
 166         reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, val);
 167 }
 168 
 169 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
 170 {
 171         reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, val);
 172 }
 173 
 174 static void sethue(struct gspca_dev *gspca_dev, s32 val)
 175 {
 176         reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, val);
 177 }
 178 
 179 static void setcolor(struct gspca_dev *gspca_dev, s32 val)
 180 {
 181         reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, val);
 182 }
 183 
 184 static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
 185 {
 186         reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, val);
 187 }
 188 
 189 /* this function is called at probe time */
 190 static int sd_config(struct gspca_dev *gspca_dev,
 191                         const struct usb_device_id *id)
 192 {
 193         gspca_dev->cam.cam_mode = vga_mode;
 194         gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
 195         gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */
 196                         /*fixme: 256 in ms-win traces*/
 197 
 198         return 0;
 199 }
 200 
 201 /* this function is called at probe and resume time */
 202 static int sd_init(struct gspca_dev *gspca_dev)
 203 {
 204         reg_w(gspca_dev, 0x00, 0x0001, 0x2067);
 205         reg_w(gspca_dev, 0x00, 0x00d0, 0x206b);
 206         reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
 207         reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
 208         msleep(8);
 209         reg_w(gspca_dev, 0x00, 0x00c0, 0x206b);
 210         reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
 211         reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
 212 
 213         reg_r(gspca_dev, 0x20, 0x0000, 1);
 214         reg_r(gspca_dev, 0x20, 0x0000, 5);
 215         reg_r(gspca_dev, 0x23, 0x0000, 64);
 216         gspca_dbg(gspca_dev, D_PROBE, "%s%s\n", &gspca_dev->usb_buf[0x1c],
 217                   &gspca_dev->usb_buf[0x30]);
 218         reg_r(gspca_dev, 0x23, 0x0001, 64);
 219         return gspca_dev->usb_err;
 220 }
 221 
 222 /* function called at start time before URB creation */
 223 static int sd_isoc_init(struct gspca_dev *gspca_dev)
 224 {
 225         u8 mode;
 226 
 227         reg_r(gspca_dev, 0x00, 0x2520, 1);
 228         wait_status_0(gspca_dev);
 229         reg_w(gspca_dev, 0xc5, 0x0003, 0x0000);
 230         wait_status_1(gspca_dev);
 231 
 232         wait_status_0(gspca_dev);
 233         mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 234         reg_wb(gspca_dev, 0x25, 0x0000, 0x0004, mode);
 235         reg_r(gspca_dev, 0x25, 0x0004, 1);
 236         reg_wb(gspca_dev, 0x27, 0x0000, 0x0000, 0x06);  /* 420 */
 237         reg_r(gspca_dev, 0x27, 0x0000, 1);
 238 
 239 /* not useful..
 240         gspca_dev->alt = 4;             * use alternate setting 3 */
 241 
 242         return gspca_dev->usb_err;
 243 }
 244 
 245 /* -- start the camera -- */
 246 static int sd_start(struct gspca_dev *gspca_dev)
 247 {
 248         struct sd *sd = (struct sd *) gspca_dev;
 249 
 250         /* initialize the JPEG header */
 251         jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
 252                         gspca_dev->pixfmt.width,
 253                         0x22);          /* JPEG 411 */
 254 
 255         /* the JPEG quality shall be 85% */
 256         jpeg_set_qual(sd->jpeg_hdr, 85);
 257 
 258         reg_r(gspca_dev, 0x00, 0x2520, 1);
 259         msleep(8);
 260 
 261         /* start the capture */
 262         wait_status_0(gspca_dev);
 263         reg_w(gspca_dev, 0x31, 0x0000, 0x0004); /* start request */
 264         wait_status_1(gspca_dev);
 265         wait_status_0(gspca_dev);
 266         msleep(200);
 267 
 268         sd->pkt_seq = 0;
 269         return gspca_dev->usb_err;
 270 }
 271 
 272 static void sd_stopN(struct gspca_dev *gspca_dev)
 273 {
 274         /* stop the capture */
 275         wait_status_0(gspca_dev);
 276         reg_w(gspca_dev, 0x31, 0x0000, 0x0000); /* stop request */
 277         wait_status_1(gspca_dev);
 278         wait_status_0(gspca_dev);
 279 }
 280 
 281 /* move a packet adding 0x00 after 0xff */
 282 static void add_packet(struct gspca_dev *gspca_dev,
 283                         u8 *data,
 284                         int len)
 285 {
 286         int i;
 287 
 288         i = 0;
 289         do {
 290                 if (data[i] == 0xff) {
 291                         gspca_frame_add(gspca_dev, INTER_PACKET,
 292                                         data, i + 1);
 293                         len -= i;
 294                         data += i;
 295                         *data = 0x00;
 296                         i = 0;
 297                 }
 298         } while (++i < len);
 299         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 300 }
 301 
 302 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 303                         u8 *data,                       /* isoc packet */
 304                         int len)                        /* iso packet length */
 305 {
 306         struct sd *sd = (struct sd *) gspca_dev;
 307         static const u8 ffd9[] = {0xff, 0xd9};
 308 
 309         /* image packets start with:
 310          *      02 8n
 311          * with <n> bit:
 312          *      0x01: even (0) / odd (1) image
 313          *      0x02: end of image when set
 314          */
 315         if (len < 3)
 316                 return;                         /* empty packet */
 317         if (*data == 0x02) {
 318                 if (data[1] & 0x02) {
 319                         sd->pkt_seq = !(data[1] & 1);
 320                         add_packet(gspca_dev, data + 2, len - 2);
 321                         gspca_frame_add(gspca_dev, LAST_PACKET,
 322                                         ffd9, 2);
 323                         return;
 324                 }
 325                 if ((data[1] & 1) != sd->pkt_seq)
 326                         goto err;
 327                 if (gspca_dev->last_packet_type == LAST_PACKET)
 328                         gspca_frame_add(gspca_dev, FIRST_PACKET,
 329                                         sd->jpeg_hdr, JPEG_HDR_SZ);
 330                 add_packet(gspca_dev, data + 2, len - 2);
 331                 return;
 332         }
 333 err:
 334         gspca_dev->last_packet_type = DISCARD_PACKET;
 335 }
 336 
 337 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 338 {
 339         struct gspca_dev *gspca_dev =
 340                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 341 
 342         gspca_dev->usb_err = 0;
 343 
 344         if (!gspca_dev->streaming)
 345                 return 0;
 346 
 347         switch (ctrl->id) {
 348         case V4L2_CID_BRIGHTNESS:
 349                 setbrightness(gspca_dev, ctrl->val);
 350                 break;
 351         case V4L2_CID_CONTRAST:
 352                 setcontrast(gspca_dev, ctrl->val);
 353                 break;
 354         case V4L2_CID_HUE:
 355                 sethue(gspca_dev, ctrl->val);
 356                 break;
 357         case V4L2_CID_SATURATION:
 358                 setcolor(gspca_dev, ctrl->val);
 359                 break;
 360         case V4L2_CID_SHARPNESS:
 361                 setsharpness(gspca_dev, ctrl->val);
 362                 break;
 363         }
 364         return gspca_dev->usb_err;
 365 }
 366 
 367 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 368         .s_ctrl = sd_s_ctrl,
 369 };
 370 
 371 static int sd_init_controls(struct gspca_dev *gspca_dev)
 372 {
 373         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 374 
 375         gspca_dev->vdev.ctrl_handler = hdl;
 376         v4l2_ctrl_handler_init(hdl, 5);
 377         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 378                         V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
 379         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 380                         V4L2_CID_CONTRAST, 0, 8, 1, 1);
 381         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 382                         V4L2_CID_HUE, 0, 255, 1, 0);
 383         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 384                         V4L2_CID_SATURATION, 0, 8, 1, 1);
 385         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 386                         V4L2_CID_SHARPNESS, 0, 255, 1, 0);
 387 
 388         if (hdl->error) {
 389                 pr_err("Could not initialize controls\n");
 390                 return hdl->error;
 391         }
 392         return 0;
 393 }
 394 
 395 /* sub-driver description */
 396 static const struct sd_desc sd_desc = {
 397         .name = MODULE_NAME,
 398         .config = sd_config,
 399         .init = sd_init,
 400         .init_controls = sd_init_controls,
 401         .isoc_init = sd_isoc_init,
 402         .start = sd_start,
 403         .stopN = sd_stopN,
 404         .pkt_scan = sd_pkt_scan,
 405 };
 406 
 407 /* -- module initialisation -- */
 408 static const struct usb_device_id device_table[] = {
 409         {USB_DEVICE(0x04fc, 0x1528)},
 410         {}
 411 };
 412 MODULE_DEVICE_TABLE(usb, device_table);
 413 
 414 /* -- device connect -- */
 415 static int sd_probe(struct usb_interface *intf,
 416                         const struct usb_device_id *id)
 417 {
 418         /* the video interface for isochronous transfer is 1 */
 419         if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
 420                 return -ENODEV;
 421 
 422         return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd),
 423                                 THIS_MODULE);
 424 }
 425 
 426 static struct usb_driver sd_driver = {
 427         .name = MODULE_NAME,
 428         .id_table = device_table,
 429         .probe = sd_probe,
 430         .disconnect = gspca_disconnect,
 431 #ifdef CONFIG_PM
 432         .suspend = gspca_suspend,
 433         .resume = gspca_resume,
 434         .reset_resume = gspca_resume,
 435 #endif
 436 };
 437 
 438 module_usb_driver(sd_driver);

/* [<][>][^][v][top][bottom][index][help] */