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