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

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

DEFINITIONS

This source file includes following definitions.
  1. reg_r
  2. reg_w
  3. rcv_val
  4. snd_val
  5. set_par
  6. setbrightness
  7. setcontrast
  8. setcolors
  9. setlightfreq
  10. sd_config
  11. sd_init
  12. sd_start
  13. sd_stopN
  14. sd_pkt_scan
  15. sd_s_ctrl
  16. sd_init_controls
  17. sd_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Syntek DV4000 (STK014) subdriver
   4  *
   5  * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
   6  */
   7 
   8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9 
  10 #define MODULE_NAME "stk014"
  11 
  12 #include "gspca.h"
  13 #include "jpeg.h"
  14 
  15 MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
  16 MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
  17 MODULE_LICENSE("GPL");
  18 
  19 #define QUALITY 50
  20 
  21 /* specific webcam descriptor */
  22 struct sd {
  23         struct gspca_dev gspca_dev;     /* !! must be the first item */
  24         u8 jpeg_hdr[JPEG_HDR_SZ];
  25 };
  26 
  27 static const struct v4l2_pix_format vga_mode[] = {
  28         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  29                 .bytesperline = 320,
  30                 .sizeimage = 320 * 240 * 3 / 8 + 590,
  31                 .colorspace = V4L2_COLORSPACE_JPEG,
  32                 .priv = 1},
  33         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  34                 .bytesperline = 640,
  35                 .sizeimage = 640 * 480 * 3 / 8 + 590,
  36                 .colorspace = V4L2_COLORSPACE_JPEG,
  37                 .priv = 0},
  38 };
  39 
  40 /* -- read a register -- */
  41 static u8 reg_r(struct gspca_dev *gspca_dev,
  42                         __u16 index)
  43 {
  44         struct usb_device *dev = gspca_dev->dev;
  45         int ret;
  46 
  47         if (gspca_dev->usb_err < 0)
  48                 return 0;
  49         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
  50                         0x00,
  51                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  52                         0x00,
  53                         index,
  54                         gspca_dev->usb_buf, 1,
  55                         500);
  56         if (ret < 0) {
  57                 pr_err("reg_r err %d\n", ret);
  58                 gspca_dev->usb_err = ret;
  59                 return 0;
  60         }
  61         return gspca_dev->usb_buf[0];
  62 }
  63 
  64 /* -- write a register -- */
  65 static void reg_w(struct gspca_dev *gspca_dev,
  66                         __u16 index, __u16 value)
  67 {
  68         struct usb_device *dev = gspca_dev->dev;
  69         int ret;
  70 
  71         if (gspca_dev->usb_err < 0)
  72                 return;
  73         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
  74                         0x01,
  75                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  76                         value,
  77                         index,
  78                         NULL,
  79                         0,
  80                         500);
  81         if (ret < 0) {
  82                 pr_err("reg_w err %d\n", ret);
  83                 gspca_dev->usb_err = ret;
  84         }
  85 }
  86 
  87 /* -- get a bulk value (4 bytes) -- */
  88 static void rcv_val(struct gspca_dev *gspca_dev,
  89                         int ads)
  90 {
  91         struct usb_device *dev = gspca_dev->dev;
  92         int alen, ret;
  93 
  94         reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
  95         reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
  96         reg_w(gspca_dev, 0x636, ads & 0xff);
  97         reg_w(gspca_dev, 0x637, 0);
  98         reg_w(gspca_dev, 0x638, 4);     /* len & 0xff */
  99         reg_w(gspca_dev, 0x639, 0);     /* len >> 8 */
 100         reg_w(gspca_dev, 0x63a, 0);
 101         reg_w(gspca_dev, 0x63b, 0);
 102         reg_w(gspca_dev, 0x630, 5);
 103         if (gspca_dev->usb_err < 0)
 104                 return;
 105         ret = usb_bulk_msg(dev,
 106                         usb_rcvbulkpipe(dev, 0x05),
 107                         gspca_dev->usb_buf,
 108                         4,              /* length */
 109                         &alen,
 110                         500);           /* timeout in milliseconds */
 111         if (ret < 0) {
 112                 pr_err("rcv_val err %d\n", ret);
 113                 gspca_dev->usb_err = ret;
 114         }
 115 }
 116 
 117 /* -- send a bulk value -- */
 118 static void snd_val(struct gspca_dev *gspca_dev,
 119                         int ads,
 120                         unsigned int val)
 121 {
 122         struct usb_device *dev = gspca_dev->dev;
 123         int alen, ret;
 124         __u8 seq = 0;
 125 
 126         if (ads == 0x003f08) {
 127                 reg_r(gspca_dev, 0x0704);
 128                 seq = reg_r(gspca_dev, 0x0705);
 129                 reg_r(gspca_dev, 0x0650);
 130                 reg_w(gspca_dev, 0x654, seq);
 131         } else {
 132                 reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
 133         }
 134         reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
 135         reg_w(gspca_dev, 0x656, ads & 0xff);
 136         reg_w(gspca_dev, 0x657, 0);
 137         reg_w(gspca_dev, 0x658, 0x04);  /* size */
 138         reg_w(gspca_dev, 0x659, 0);
 139         reg_w(gspca_dev, 0x65a, 0);
 140         reg_w(gspca_dev, 0x65b, 0);
 141         reg_w(gspca_dev, 0x650, 5);
 142         if (gspca_dev->usb_err < 0)
 143                 return;
 144         gspca_dev->usb_buf[0] = val >> 24;
 145         gspca_dev->usb_buf[1] = val >> 16;
 146         gspca_dev->usb_buf[2] = val >> 8;
 147         gspca_dev->usb_buf[3] = val;
 148         ret = usb_bulk_msg(dev,
 149                         usb_sndbulkpipe(dev, 6),
 150                         gspca_dev->usb_buf,
 151                         4,
 152                         &alen,
 153                         500);   /* timeout in milliseconds */
 154         if (ret < 0) {
 155                 pr_err("snd_val err %d\n", ret);
 156                 gspca_dev->usb_err = ret;
 157         } else {
 158                 if (ads == 0x003f08) {
 159                         seq += 4;
 160                         seq &= 0x3f;
 161                         reg_w(gspca_dev, 0x705, seq);
 162                 }
 163         }
 164 }
 165 
 166 /* set a camera parameter */
 167 static void set_par(struct gspca_dev *gspca_dev,
 168                    int parval)
 169 {
 170         snd_val(gspca_dev, 0x003f08, parval);
 171 }
 172 
 173 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
 174 {
 175         int parval;
 176 
 177         parval = 0x06000000             /* whiteness */
 178                 + (val << 16);
 179         set_par(gspca_dev, parval);
 180 }
 181 
 182 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
 183 {
 184         int parval;
 185 
 186         parval = 0x07000000             /* contrast */
 187                 + (val << 16);
 188         set_par(gspca_dev, parval);
 189 }
 190 
 191 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
 192 {
 193         int parval;
 194 
 195         parval = 0x08000000             /* saturation */
 196                 + (val << 16);
 197         set_par(gspca_dev, parval);
 198 }
 199 
 200 static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
 201 {
 202         set_par(gspca_dev, val == 1
 203                         ? 0x33640000            /* 50 Hz */
 204                         : 0x33780000);          /* 60 Hz */
 205 }
 206 
 207 /* this function is called at probe time */
 208 static int sd_config(struct gspca_dev *gspca_dev,
 209                         const struct usb_device_id *id)
 210 {
 211         gspca_dev->cam.cam_mode = vga_mode;
 212         gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
 213         return 0;
 214 }
 215 
 216 /* this function is called at probe and resume time */
 217 static int sd_init(struct gspca_dev *gspca_dev)
 218 {
 219         u8 ret;
 220 
 221         /* check if the device responds */
 222         usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
 223         ret = reg_r(gspca_dev, 0x0740);
 224         if (gspca_dev->usb_err >= 0) {
 225                 if (ret != 0xff) {
 226                         pr_err("init reg: 0x%02x\n", ret);
 227                         gspca_dev->usb_err = -EIO;
 228                 }
 229         }
 230         return gspca_dev->usb_err;
 231 }
 232 
 233 /* -- start the camera -- */
 234 static int sd_start(struct gspca_dev *gspca_dev)
 235 {
 236         struct sd *sd = (struct sd *) gspca_dev;
 237         int ret, value;
 238 
 239         /* create the JPEG header */
 240         jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
 241                         gspca_dev->pixfmt.width,
 242                         0x22);          /* JPEG 411 */
 243         jpeg_set_qual(sd->jpeg_hdr, QUALITY);
 244 
 245         /* work on alternate 1 */
 246         usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
 247 
 248         set_par(gspca_dev, 0x10000000);
 249         set_par(gspca_dev, 0x00000000);
 250         set_par(gspca_dev, 0x8002e001);
 251         set_par(gspca_dev, 0x14000000);
 252         if (gspca_dev->pixfmt.width > 320)
 253                 value = 0x8002e001;             /* 640x480 */
 254         else
 255                 value = 0x4001f000;             /* 320x240 */
 256         set_par(gspca_dev, value);
 257         ret = usb_set_interface(gspca_dev->dev,
 258                                         gspca_dev->iface,
 259                                         gspca_dev->alt);
 260         if (ret < 0) {
 261                 pr_err("set intf %d %d failed\n",
 262                        gspca_dev->iface, gspca_dev->alt);
 263                 gspca_dev->usb_err = ret;
 264                 goto out;
 265         }
 266         reg_r(gspca_dev, 0x0630);
 267         rcv_val(gspca_dev, 0x000020);   /* << (value ff ff ff ff) */
 268         reg_r(gspca_dev, 0x0650);
 269         snd_val(gspca_dev, 0x000020, 0xffffffff);
 270         reg_w(gspca_dev, 0x0620, 0);
 271         reg_w(gspca_dev, 0x0630, 0);
 272         reg_w(gspca_dev, 0x0640, 0);
 273         reg_w(gspca_dev, 0x0650, 0);
 274         reg_w(gspca_dev, 0x0660, 0);
 275         set_par(gspca_dev, 0x09800000);         /* Red ? */
 276         set_par(gspca_dev, 0x0a800000);         /* Green ? */
 277         set_par(gspca_dev, 0x0b800000);         /* Blue ? */
 278         set_par(gspca_dev, 0x0d030000);         /* Gamma ? */
 279 
 280         /* start the video flow */
 281         set_par(gspca_dev, 0x01000000);
 282         set_par(gspca_dev, 0x01000000);
 283         if (gspca_dev->usb_err >= 0)
 284                 gspca_dbg(gspca_dev, D_STREAM, "camera started alt: 0x%02x\n",
 285                           gspca_dev->alt);
 286 out:
 287         return gspca_dev->usb_err;
 288 }
 289 
 290 static void sd_stopN(struct gspca_dev *gspca_dev)
 291 {
 292         struct usb_device *dev = gspca_dev->dev;
 293 
 294         set_par(gspca_dev, 0x02000000);
 295         set_par(gspca_dev, 0x02000000);
 296         usb_set_interface(dev, gspca_dev->iface, 1);
 297         reg_r(gspca_dev, 0x0630);
 298         rcv_val(gspca_dev, 0x000020);   /* << (value ff ff ff ff) */
 299         reg_r(gspca_dev, 0x0650);
 300         snd_val(gspca_dev, 0x000020, 0xffffffff);
 301         reg_w(gspca_dev, 0x0620, 0);
 302         reg_w(gspca_dev, 0x0630, 0);
 303         reg_w(gspca_dev, 0x0640, 0);
 304         reg_w(gspca_dev, 0x0650, 0);
 305         reg_w(gspca_dev, 0x0660, 0);
 306         gspca_dbg(gspca_dev, D_STREAM, "camera stopped\n");
 307 }
 308 
 309 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 310                         u8 *data,                       /* isoc packet */
 311                         int len)                        /* iso packet length */
 312 {
 313         struct sd *sd = (struct sd *) gspca_dev;
 314         static unsigned char ffd9[] = {0xff, 0xd9};
 315 
 316         /* a frame starts with:
 317          *      - 0xff 0xfe
 318          *      - 0x08 0x00     - length (little endian ?!)
 319          *      - 4 bytes = size of whole frame (BE - including header)
 320          *      - 0x00 0x0c
 321          *      - 0xff 0xd8
 322          *      - ..    JPEG image with escape sequences (ff 00)
 323          *              (without ending - ff d9)
 324          */
 325         if (data[0] == 0xff && data[1] == 0xfe) {
 326                 gspca_frame_add(gspca_dev, LAST_PACKET,
 327                                 ffd9, 2);
 328 
 329                 /* put the JPEG 411 header */
 330                 gspca_frame_add(gspca_dev, FIRST_PACKET,
 331                         sd->jpeg_hdr, JPEG_HDR_SZ);
 332 
 333                 /* beginning of the frame */
 334 #define STKHDRSZ 12
 335                 data += STKHDRSZ;
 336                 len -= STKHDRSZ;
 337         }
 338         gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 339 }
 340 
 341 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 342 {
 343         struct gspca_dev *gspca_dev =
 344                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 345 
 346         gspca_dev->usb_err = 0;
 347 
 348         if (!gspca_dev->streaming)
 349                 return 0;
 350 
 351         switch (ctrl->id) {
 352         case V4L2_CID_BRIGHTNESS:
 353                 setbrightness(gspca_dev, ctrl->val);
 354                 break;
 355         case V4L2_CID_CONTRAST:
 356                 setcontrast(gspca_dev, ctrl->val);
 357                 break;
 358         case V4L2_CID_SATURATION:
 359                 setcolors(gspca_dev, ctrl->val);
 360                 break;
 361         case V4L2_CID_POWER_LINE_FREQUENCY:
 362                 setlightfreq(gspca_dev, ctrl->val);
 363                 break;
 364         }
 365         return gspca_dev->usb_err;
 366 }
 367 
 368 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 369         .s_ctrl = sd_s_ctrl,
 370 };
 371 
 372 static int sd_init_controls(struct gspca_dev *gspca_dev)
 373 {
 374         struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 375 
 376         gspca_dev->vdev.ctrl_handler = hdl;
 377         v4l2_ctrl_handler_init(hdl, 4);
 378         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 379                         V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
 380         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 381                         V4L2_CID_CONTRAST, 0, 255, 1, 127);
 382         v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 383                         V4L2_CID_SATURATION, 0, 255, 1, 127);
 384         v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
 385                         V4L2_CID_POWER_LINE_FREQUENCY,
 386                         V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
 387                         V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
 388 
 389         if (hdl->error) {
 390                 pr_err("Could not initialize controls\n");
 391                 return hdl->error;
 392         }
 393         return 0;
 394 }
 395 
 396 /* sub-driver description */
 397 static const struct sd_desc sd_desc = {
 398         .name = MODULE_NAME,
 399         .config = sd_config,
 400         .init = sd_init,
 401         .init_controls = sd_init_controls,
 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(0x05e1, 0x0893)},
 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         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 419                                 THIS_MODULE);
 420 }
 421 
 422 static struct usb_driver sd_driver = {
 423         .name = MODULE_NAME,
 424         .id_table = device_table,
 425         .probe = sd_probe,
 426         .disconnect = gspca_disconnect,
 427 #ifdef CONFIG_PM
 428         .suspend = gspca_suspend,
 429         .resume = gspca_resume,
 430         .reset_resume = gspca_resume,
 431 #endif
 432 };
 433 
 434 module_usb_driver(sd_driver);

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