linux/drivers/media/video/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/* controls */
  33enum e_ctrl {
  34        BRIGHTNESS,
  35        CONTRAST,
  36        COLORS,
  37        LIGHTFREQ,
  38        NCTRLS          /* number of controls */
  39};
  40
  41/* specific webcam descriptor */
  42struct sd {
  43        struct gspca_dev gspca_dev;     /* !! must be the first item */
  44
  45        struct gspca_ctrl ctrls[NCTRLS];
  46
  47        u8 quality;
  48#define QUALITY_MIN 70
  49#define QUALITY_MAX 95
  50#define QUALITY_DEF 88
  51
  52        u8 jpeg_hdr[JPEG_HDR_SZ];
  53};
  54
  55/* V4L2 controls supported by the driver */
  56static void setbrightness(struct gspca_dev *gspca_dev);
  57static void setcontrast(struct gspca_dev *gspca_dev);
  58static void setcolors(struct gspca_dev *gspca_dev);
  59static void setlightfreq(struct gspca_dev *gspca_dev);
  60
  61static const struct ctrl sd_ctrls[NCTRLS] = {
  62[BRIGHTNESS] = {
  63            {
  64                .id      = V4L2_CID_BRIGHTNESS,
  65                .type    = V4L2_CTRL_TYPE_INTEGER,
  66                .name    = "Brightness",
  67                .minimum = 0,
  68                .maximum = 255,
  69                .step    = 1,
  70                .default_value = 127,
  71            },
  72            .set_control = setbrightness
  73        },
  74[CONTRAST] = {
  75            {
  76                .id      = V4L2_CID_CONTRAST,
  77                .type    = V4L2_CTRL_TYPE_INTEGER,
  78                .name    = "Contrast",
  79                .minimum = 0,
  80                .maximum = 255,
  81                .step    = 1,
  82                .default_value = 127,
  83            },
  84            .set_control = setcontrast
  85        },
  86[COLORS] = {
  87            {
  88                .id      = V4L2_CID_SATURATION,
  89                .type    = V4L2_CTRL_TYPE_INTEGER,
  90                .name    = "Color",
  91                .minimum = 0,
  92                .maximum = 255,
  93                .step    = 1,
  94                .default_value = 127,
  95            },
  96            .set_control = setcolors
  97        },
  98[LIGHTFREQ] = {
  99            {
 100                .id      = V4L2_CID_POWER_LINE_FREQUENCY,
 101                .type    = V4L2_CTRL_TYPE_MENU,
 102                .name    = "Light frequency filter",
 103                .minimum = 1,
 104                .maximum = 2,   /* 0: 0, 1: 50Hz, 2:60Hz */
 105                .step    = 1,
 106                .default_value = 1,
 107            },
 108            .set_control = setlightfreq
 109        },
 110};
 111
 112static const struct v4l2_pix_format vga_mode[] = {
 113        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 114                .bytesperline = 320,
 115                .sizeimage = 320 * 240 * 3 / 8 + 590,
 116                .colorspace = V4L2_COLORSPACE_JPEG,
 117                .priv = 1},
 118        {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
 119                .bytesperline = 640,
 120                .sizeimage = 640 * 480 * 3 / 8 + 590,
 121                .colorspace = V4L2_COLORSPACE_JPEG,
 122                .priv = 0},
 123};
 124
 125/* -- read a register -- */
 126static u8 reg_r(struct gspca_dev *gspca_dev,
 127                        __u16 index)
 128{
 129        struct usb_device *dev = gspca_dev->dev;
 130        int ret;
 131
 132        if (gspca_dev->usb_err < 0)
 133                return 0;
 134        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 135                        0x00,
 136                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 137                        0x00,
 138                        index,
 139                        gspca_dev->usb_buf, 1,
 140                        500);
 141        if (ret < 0) {
 142                pr_err("reg_r err %d\n", ret);
 143                gspca_dev->usb_err = ret;
 144                return 0;
 145        }
 146        return gspca_dev->usb_buf[0];
 147}
 148
 149/* -- write a register -- */
 150static void reg_w(struct gspca_dev *gspca_dev,
 151                        __u16 index, __u16 value)
 152{
 153        struct usb_device *dev = gspca_dev->dev;
 154        int ret;
 155
 156        if (gspca_dev->usb_err < 0)
 157                return;
 158        ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 159                        0x01,
 160                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 161                        value,
 162                        index,
 163                        NULL,
 164                        0,
 165                        500);
 166        if (ret < 0) {
 167                pr_err("reg_w err %d\n", ret);
 168                gspca_dev->usb_err = ret;
 169        }
 170}
 171
 172/* -- get a bulk value (4 bytes) -- */
 173static void rcv_val(struct gspca_dev *gspca_dev,
 174                        int ads)
 175{
 176        struct usb_device *dev = gspca_dev->dev;
 177        int alen, ret;
 178
 179        reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
 180        reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
 181        reg_w(gspca_dev, 0x636, ads & 0xff);
 182        reg_w(gspca_dev, 0x637, 0);
 183        reg_w(gspca_dev, 0x638, 4);     /* len & 0xff */
 184        reg_w(gspca_dev, 0x639, 0);     /* len >> 8 */
 185        reg_w(gspca_dev, 0x63a, 0);
 186        reg_w(gspca_dev, 0x63b, 0);
 187        reg_w(gspca_dev, 0x630, 5);
 188        if (gspca_dev->usb_err < 0)
 189                return;
 190        ret = usb_bulk_msg(dev,
 191                        usb_rcvbulkpipe(dev, 0x05),
 192                        gspca_dev->usb_buf,
 193                        4,              /* length */
 194                        &alen,
 195                        500);           /* timeout in milliseconds */
 196        if (ret < 0) {
 197                pr_err("rcv_val err %d\n", ret);
 198                gspca_dev->usb_err = ret;
 199        }
 200}
 201
 202/* -- send a bulk value -- */
 203static void snd_val(struct gspca_dev *gspca_dev,
 204                        int ads,
 205                        unsigned int val)
 206{
 207        struct usb_device *dev = gspca_dev->dev;
 208        int alen, ret;
 209        __u8 seq = 0;
 210
 211        if (ads == 0x003f08) {
 212                reg_r(gspca_dev, 0x0704);
 213                seq = reg_r(gspca_dev, 0x0705);
 214                reg_r(gspca_dev, 0x0650);
 215                reg_w(gspca_dev, 0x654, seq);
 216        } else {
 217                reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
 218        }
 219        reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
 220        reg_w(gspca_dev, 0x656, ads & 0xff);
 221        reg_w(gspca_dev, 0x657, 0);
 222        reg_w(gspca_dev, 0x658, 0x04);  /* size */
 223        reg_w(gspca_dev, 0x659, 0);
 224        reg_w(gspca_dev, 0x65a, 0);
 225        reg_w(gspca_dev, 0x65b, 0);
 226        reg_w(gspca_dev, 0x650, 5);
 227        if (gspca_dev->usb_err < 0)
 228                return;
 229        gspca_dev->usb_buf[0] = val >> 24;
 230        gspca_dev->usb_buf[1] = val >> 16;
 231        gspca_dev->usb_buf[2] = val >> 8;
 232        gspca_dev->usb_buf[3] = val;
 233        ret = usb_bulk_msg(dev,
 234                        usb_sndbulkpipe(dev, 6),
 235                        gspca_dev->usb_buf,
 236                        4,
 237                        &alen,
 238                        500);   /* timeout in milliseconds */
 239        if (ret < 0) {
 240                pr_err("snd_val err %d\n", ret);
 241                gspca_dev->usb_err = ret;
 242        } else {
 243                if (ads == 0x003f08) {
 244                        seq += 4;
 245                        seq &= 0x3f;
 246                        reg_w(gspca_dev, 0x705, seq);
 247                }
 248        }
 249}
 250
 251/* set a camera parameter */
 252static void set_par(struct gspca_dev *gspca_dev,
 253                   int parval)
 254{
 255        snd_val(gspca_dev, 0x003f08, parval);
 256}
 257
 258static void setbrightness(struct gspca_dev *gspca_dev)
 259{
 260        struct sd *sd = (struct sd *) gspca_dev;
 261        int parval;
 262
 263        parval = 0x06000000             /* whiteness */
 264                + (sd->ctrls[BRIGHTNESS].val << 16);
 265        set_par(gspca_dev, parval);
 266}
 267
 268static void setcontrast(struct gspca_dev *gspca_dev)
 269{
 270        struct sd *sd = (struct sd *) gspca_dev;
 271        int parval;
 272
 273        parval = 0x07000000             /* contrast */
 274                + (sd->ctrls[CONTRAST].val << 16);
 275        set_par(gspca_dev, parval);
 276}
 277
 278static void setcolors(struct gspca_dev *gspca_dev)
 279{
 280        struct sd *sd = (struct sd *) gspca_dev;
 281        int parval;
 282
 283        parval = 0x08000000             /* saturation */
 284                + (sd->ctrls[COLORS].val << 16);
 285        set_par(gspca_dev, parval);
 286}
 287
 288static void setlightfreq(struct gspca_dev *gspca_dev)
 289{
 290        struct sd *sd = (struct sd *) gspca_dev;
 291
 292        set_par(gspca_dev, sd->ctrls[LIGHTFREQ].val == 1
 293                        ? 0x33640000            /* 50 Hz */
 294                        : 0x33780000);          /* 60 Hz */
 295}
 296
 297/* this function is called at probe time */
 298static int sd_config(struct gspca_dev *gspca_dev,
 299                        const struct usb_device_id *id)
 300{
 301        struct sd *sd = (struct sd *) gspca_dev;
 302
 303        gspca_dev->cam.cam_mode = vga_mode;
 304        gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
 305        gspca_dev->cam.ctrls = sd->ctrls;
 306        sd->quality = QUALITY_DEF;
 307        return 0;
 308}
 309
 310/* this function is called at probe and resume time */
 311static int sd_init(struct gspca_dev *gspca_dev)
 312{
 313        u8 ret;
 314
 315        /* check if the device responds */
 316        usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
 317        ret = reg_r(gspca_dev, 0x0740);
 318        if (gspca_dev->usb_err >= 0) {
 319                if (ret != 0xff) {
 320                        pr_err("init reg: 0x%02x\n", ret);
 321                        gspca_dev->usb_err = -EIO;
 322                }
 323        }
 324        return gspca_dev->usb_err;
 325}
 326
 327/* -- start the camera -- */
 328static int sd_start(struct gspca_dev *gspca_dev)
 329{
 330        struct sd *sd = (struct sd *) gspca_dev;
 331        int ret, value;
 332
 333        /* create the JPEG header */
 334        jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
 335                        0x22);          /* JPEG 411 */
 336        jpeg_set_qual(sd->jpeg_hdr, sd->quality);
 337
 338        /* work on alternate 1 */
 339        usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
 340
 341        set_par(gspca_dev, 0x10000000);
 342        set_par(gspca_dev, 0x00000000);
 343        set_par(gspca_dev, 0x8002e001);
 344        set_par(gspca_dev, 0x14000000);
 345        if (gspca_dev->width > 320)
 346                value = 0x8002e001;             /* 640x480 */
 347        else
 348                value = 0x4001f000;             /* 320x240 */
 349        set_par(gspca_dev, value);
 350        ret = usb_set_interface(gspca_dev->dev,
 351                                        gspca_dev->iface,
 352                                        gspca_dev->alt);
 353        if (ret < 0) {
 354                pr_err("set intf %d %d failed\n",
 355                       gspca_dev->iface, gspca_dev->alt);
 356                gspca_dev->usb_err = ret;
 357                goto out;
 358        }
 359         reg_r(gspca_dev, 0x0630);
 360        rcv_val(gspca_dev, 0x000020);   /* << (value ff ff ff ff) */
 361        reg_r(gspca_dev, 0x0650);
 362        snd_val(gspca_dev, 0x000020, 0xffffffff);
 363        reg_w(gspca_dev, 0x0620, 0);
 364        reg_w(gspca_dev, 0x0630, 0);
 365        reg_w(gspca_dev, 0x0640, 0);
 366        reg_w(gspca_dev, 0x0650, 0);
 367        reg_w(gspca_dev, 0x0660, 0);
 368        setbrightness(gspca_dev);               /* whiteness */
 369        setcontrast(gspca_dev);                 /* contrast */
 370        setcolors(gspca_dev);                   /* saturation */
 371        set_par(gspca_dev, 0x09800000);         /* Red ? */
 372        set_par(gspca_dev, 0x0a800000);         /* Green ? */
 373        set_par(gspca_dev, 0x0b800000);         /* Blue ? */
 374        set_par(gspca_dev, 0x0d030000);         /* Gamma ? */
 375        setlightfreq(gspca_dev);
 376
 377        /* start the video flow */
 378        set_par(gspca_dev, 0x01000000);
 379        set_par(gspca_dev, 0x01000000);
 380        if (gspca_dev->usb_err >= 0)
 381                PDEBUG(D_STREAM, "camera started alt: 0x%02x",
 382                                gspca_dev->alt);
 383out:
 384        return gspca_dev->usb_err;
 385}
 386
 387static void sd_stopN(struct gspca_dev *gspca_dev)
 388{
 389        struct usb_device *dev = gspca_dev->dev;
 390
 391        set_par(gspca_dev, 0x02000000);
 392        set_par(gspca_dev, 0x02000000);
 393        usb_set_interface(dev, gspca_dev->iface, 1);
 394        reg_r(gspca_dev, 0x0630);
 395        rcv_val(gspca_dev, 0x000020);   /* << (value ff ff ff ff) */
 396        reg_r(gspca_dev, 0x0650);
 397        snd_val(gspca_dev, 0x000020, 0xffffffff);
 398        reg_w(gspca_dev, 0x0620, 0);
 399        reg_w(gspca_dev, 0x0630, 0);
 400        reg_w(gspca_dev, 0x0640, 0);
 401        reg_w(gspca_dev, 0x0650, 0);
 402        reg_w(gspca_dev, 0x0660, 0);
 403        PDEBUG(D_STREAM, "camera stopped");
 404}
 405
 406static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 407                        u8 *data,                       /* isoc packet */
 408                        int len)                        /* iso packet length */
 409{
 410        struct sd *sd = (struct sd *) gspca_dev;
 411        static unsigned char ffd9[] = {0xff, 0xd9};
 412
 413        /* a frame starts with:
 414         *      - 0xff 0xfe
 415         *      - 0x08 0x00     - length (little endian ?!)
 416         *      - 4 bytes = size of whole frame (BE - including header)
 417         *      - 0x00 0x0c
 418         *      - 0xff 0xd8
 419         *      - ..    JPEG image with escape sequences (ff 00)
 420         *              (without ending - ff d9)
 421         */
 422        if (data[0] == 0xff && data[1] == 0xfe) {
 423                gspca_frame_add(gspca_dev, LAST_PACKET,
 424                                ffd9, 2);
 425
 426                /* put the JPEG 411 header */
 427                gspca_frame_add(gspca_dev, FIRST_PACKET,
 428                        sd->jpeg_hdr, JPEG_HDR_SZ);
 429
 430                /* beginning of the frame */
 431#define STKHDRSZ 12
 432                data += STKHDRSZ;
 433                len -= STKHDRSZ;
 434        }
 435        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 436}
 437
 438static int sd_querymenu(struct gspca_dev *gspca_dev,
 439                        struct v4l2_querymenu *menu)
 440{
 441        static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
 442
 443        switch (menu->id) {
 444        case V4L2_CID_POWER_LINE_FREQUENCY:
 445                if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
 446                        break;
 447                strcpy((char *) menu->name, freq_nm[menu->index]);
 448                return 0;
 449        }
 450        return -EINVAL;
 451}
 452
 453static int sd_set_jcomp(struct gspca_dev *gspca_dev,
 454                        struct v4l2_jpegcompression *jcomp)
 455{
 456        struct sd *sd = (struct sd *) gspca_dev;
 457
 458        if (jcomp->quality < QUALITY_MIN)
 459                sd->quality = QUALITY_MIN;
 460        else if (jcomp->quality > QUALITY_MAX)
 461                sd->quality = QUALITY_MAX;
 462        else
 463                sd->quality = jcomp->quality;
 464        if (gspca_dev->streaming)
 465                jpeg_set_qual(sd->jpeg_hdr, sd->quality);
 466        return gspca_dev->usb_err;
 467}
 468
 469static int sd_get_jcomp(struct gspca_dev *gspca_dev,
 470                        struct v4l2_jpegcompression *jcomp)
 471{
 472        struct sd *sd = (struct sd *) gspca_dev;
 473
 474        memset(jcomp, 0, sizeof *jcomp);
 475        jcomp->quality = sd->quality;
 476        jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
 477                        | V4L2_JPEG_MARKER_DQT;
 478        return 0;
 479}
 480
 481/* sub-driver description */
 482static const struct sd_desc sd_desc = {
 483        .name = MODULE_NAME,
 484        .ctrls = sd_ctrls,
 485        .nctrls = NCTRLS,
 486        .config = sd_config,
 487        .init = sd_init,
 488        .start = sd_start,
 489        .stopN = sd_stopN,
 490        .pkt_scan = sd_pkt_scan,
 491        .querymenu = sd_querymenu,
 492        .get_jcomp = sd_get_jcomp,
 493        .set_jcomp = sd_set_jcomp,
 494};
 495
 496/* -- module initialisation -- */
 497static const struct usb_device_id device_table[] = {
 498        {USB_DEVICE(0x05e1, 0x0893)},
 499        {}
 500};
 501MODULE_DEVICE_TABLE(usb, device_table);
 502
 503/* -- device connect -- */
 504static int sd_probe(struct usb_interface *intf,
 505                        const struct usb_device_id *id)
 506{
 507        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 508                                THIS_MODULE);
 509}
 510
 511static struct usb_driver sd_driver = {
 512        .name = MODULE_NAME,
 513        .id_table = device_table,
 514        .probe = sd_probe,
 515        .disconnect = gspca_disconnect,
 516#ifdef CONFIG_PM
 517        .suspend = gspca_suspend,
 518        .resume = gspca_resume,
 519#endif
 520};
 521
 522/* -- module insert / remove -- */
 523static int __init sd_mod_init(void)
 524{
 525        return usb_register(&sd_driver);
 526}
 527static void __exit sd_mod_exit(void)
 528{
 529        usb_deregister(&sd_driver);
 530}
 531
 532module_init(sd_mod_init);
 533module_exit(sd_mod_exit);
 534