linux/drivers/media/usb/gspca/spca500.c
<<
>>
Prefs
   1/*
   2 * SPCA500 chip based cameras initialization data
   3 *
   4 * V4L2 by 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
  22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  23
  24#define MODULE_NAME "spca500"
  25
  26#include "gspca.h"
  27#include "jpeg.h"
  28
  29MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  30MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
  31MODULE_LICENSE("GPL");
  32
  33#define QUALITY 85
  34
  35/* specific webcam descriptor */
  36struct sd {
  37        struct gspca_dev gspca_dev;             /* !! must be the first item */
  38
  39        char subtype;
  40#define AgfaCl20 0
  41#define AiptekPocketDV 1
  42#define BenqDC1016 2
  43#define CreativePCCam300 3
  44#define DLinkDSC350 4
  45#define Gsmartmini 5
  46#define IntelPocketPCCamera 6
  47#define KodakEZ200 7
  48#define LogitechClickSmart310 8
  49#define LogitechClickSmart510 9
  50#define LogitechTraveler 10
  51#define MustekGsmart300 11
  52#define Optimedia 12
  53#define PalmPixDC85 13
  54#define ToptroIndus 14
  55
  56        u8 jpeg_hdr[JPEG_HDR_SZ];
  57};
  58
  59static const struct v4l2_pix_format vga_mode[] = {
  60        {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  61                .bytesperline = 320,
  62                .sizeimage = 320 * 240 * 3 / 8 + 590,
  63                .colorspace = V4L2_COLORSPACE_JPEG,
  64                .priv = 1},
  65        {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  66                .bytesperline = 640,
  67                .sizeimage = 640 * 480 * 3 / 8 + 590,
  68                .colorspace = V4L2_COLORSPACE_JPEG,
  69                .priv = 0},
  70};
  71
  72static const struct v4l2_pix_format sif_mode[] = {
  73        {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  74                .bytesperline = 176,
  75                .sizeimage = 176 * 144 * 3 / 8 + 590,
  76                .colorspace = V4L2_COLORSPACE_JPEG,
  77                .priv = 1},
  78        {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
  79                .bytesperline = 352,
  80                .sizeimage = 352 * 288 * 3 / 8 + 590,
  81                .colorspace = V4L2_COLORSPACE_JPEG,
  82                .priv = 0},
  83};
  84
  85/* Frame packet header offsets for the spca500 */
  86#define SPCA500_OFFSET_PADDINGLB 2
  87#define SPCA500_OFFSET_PADDINGHB 3
  88#define SPCA500_OFFSET_MODE      4
  89#define SPCA500_OFFSET_IMGWIDTH  5
  90#define SPCA500_OFFSET_IMGHEIGHT 6
  91#define SPCA500_OFFSET_IMGMODE   7
  92#define SPCA500_OFFSET_QTBLINDEX 8
  93#define SPCA500_OFFSET_FRAMSEQ   9
  94#define SPCA500_OFFSET_CDSPINFO  10
  95#define SPCA500_OFFSET_GPIO      11
  96#define SPCA500_OFFSET_AUGPIO    12
  97#define SPCA500_OFFSET_DATA      16
  98
  99
 100static const __u16 spca500_visual_defaults[][3] = {
 101        {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
 102                                 * hue (H byte) = 0,
 103                                 * saturation/hue enable,
 104                                 * brightness/contrast enable.
 105                                 */
 106        {0x00, 0x0000, 0x8167}, /* brightness = 0 */
 107        {0x00, 0x0020, 0x8168}, /* contrast = 0 */
 108        {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
 109                                 * hue (H byte) = 0, saturation/hue enable,
 110                                 * brightness/contrast enable.
 111                                 * was 0x0003, now 0x0000.
 112                                 */
 113        {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
 114        {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
 115        {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
 116        {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
 117        {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
 118        {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
 119        {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
 120        {0x0c, 0x0004, 0x0000},
 121        /* set interface */
 122        {}
 123};
 124static const __u16 Clicksmart510_defaults[][3] = {
 125        {0x00, 0x00, 0x8211},
 126        {0x00, 0x01, 0x82c0},
 127        {0x00, 0x10, 0x82cb},
 128        {0x00, 0x0f, 0x800d},
 129        {0x00, 0x82, 0x8225},
 130        {0x00, 0x21, 0x8228},
 131        {0x00, 0x00, 0x8203},
 132        {0x00, 0x00, 0x8204},
 133        {0x00, 0x08, 0x8205},
 134        {0x00, 0xf8, 0x8206},
 135        {0x00, 0x28, 0x8207},
 136        {0x00, 0xa0, 0x8208},
 137        {0x00, 0x08, 0x824a},
 138        {0x00, 0x08, 0x8214},
 139        {0x00, 0x80, 0x82c1},
 140        {0x00, 0x00, 0x82c2},
 141        {0x00, 0x00, 0x82ca},
 142        {0x00, 0x80, 0x82c1},
 143        {0x00, 0x04, 0x82c2},
 144        {0x00, 0x00, 0x82ca},
 145        {0x00, 0xfc, 0x8100},
 146        {0x00, 0xfc, 0x8105},
 147        {0x00, 0x30, 0x8101},
 148        {0x00, 0x00, 0x8102},
 149        {0x00, 0x00, 0x8103},
 150        {0x00, 0x66, 0x8107},
 151        {0x00, 0x00, 0x816b},
 152        {0x00, 0x00, 0x8155},
 153        {0x00, 0x01, 0x8156},
 154        {0x00, 0x60, 0x8157},
 155        {0x00, 0x40, 0x8158},
 156        {0x00, 0x0a, 0x8159},
 157        {0x00, 0x06, 0x815a},
 158        {0x00, 0x00, 0x813f},
 159        {0x00, 0x00, 0x8200},
 160        {0x00, 0x19, 0x8201},
 161        {0x00, 0x00, 0x82c1},
 162        {0x00, 0xa0, 0x82c2},
 163        {0x00, 0x00, 0x82ca},
 164        {0x00, 0x00, 0x8117},
 165        {0x00, 0x00, 0x8118},
 166        {0x00, 0x65, 0x8119},
 167        {0x00, 0x00, 0x811a},
 168        {0x00, 0x00, 0x811b},
 169        {0x00, 0x55, 0x811c},
 170        {0x00, 0x65, 0x811d},
 171        {0x00, 0x55, 0x811e},
 172        {0x00, 0x16, 0x811f},
 173        {0x00, 0x19, 0x8120},
 174        {0x00, 0x80, 0x8103},
 175        {0x00, 0x83, 0x816b},
 176        {0x00, 0x25, 0x8168},
 177        {0x00, 0x01, 0x820f},
 178        {0x00, 0xff, 0x8115},
 179        {0x00, 0x48, 0x8116},
 180        {0x00, 0x50, 0x8151},
 181        {0x00, 0x40, 0x8152},
 182        {0x00, 0x78, 0x8153},
 183        {0x00, 0x40, 0x8154},
 184        {0x00, 0x00, 0x8167},
 185        {0x00, 0x20, 0x8168},
 186        {0x00, 0x00, 0x816a},
 187        {0x00, 0x03, 0x816b},
 188        {0x00, 0x20, 0x8169},
 189        {0x00, 0x60, 0x8157},
 190        {0x00, 0x00, 0x8190},
 191        {0x00, 0x00, 0x81a1},
 192        {0x00, 0x00, 0x81b2},
 193        {0x00, 0x27, 0x8191},
 194        {0x00, 0x27, 0x81a2},
 195        {0x00, 0x27, 0x81b3},
 196        {0x00, 0x4b, 0x8192},
 197        {0x00, 0x4b, 0x81a3},
 198        {0x00, 0x4b, 0x81b4},
 199        {0x00, 0x66, 0x8193},
 200        {0x00, 0x66, 0x81a4},
 201        {0x00, 0x66, 0x81b5},
 202        {0x00, 0x79, 0x8194},
 203        {0x00, 0x79, 0x81a5},
 204        {0x00, 0x79, 0x81b6},
 205        {0x00, 0x8a, 0x8195},
 206        {0x00, 0x8a, 0x81a6},
 207        {0x00, 0x8a, 0x81b7},
 208        {0x00, 0x9b, 0x8196},
 209        {0x00, 0x9b, 0x81a7},
 210        {0x00, 0x9b, 0x81b8},
 211        {0x00, 0xa6, 0x8197},
 212        {0x00, 0xa6, 0x81a8},
 213        {0x00, 0xa6, 0x81b9},
 214        {0x00, 0xb2, 0x8198},
 215        {0x00, 0xb2, 0x81a9},
 216        {0x00, 0xb2, 0x81ba},
 217        {0x00, 0xbe, 0x8199},
 218        {0x00, 0xbe, 0x81aa},
 219        {0x00, 0xbe, 0x81bb},
 220        {0x00, 0xc8, 0x819a},
 221        {0x00, 0xc8, 0x81ab},
 222        {0x00, 0xc8, 0x81bc},
 223        {0x00, 0xd2, 0x819b},
 224        {0x00, 0xd2, 0x81ac},
 225        {0x00, 0xd2, 0x81bd},
 226        {0x00, 0xdb, 0x819c},
 227        {0x00, 0xdb, 0x81ad},
 228        {0x00, 0xdb, 0x81be},
 229        {0x00, 0xe4, 0x819d},
 230        {0x00, 0xe4, 0x81ae},
 231        {0x00, 0xe4, 0x81bf},
 232        {0x00, 0xed, 0x819e},
 233        {0x00, 0xed, 0x81af},
 234        {0x00, 0xed, 0x81c0},
 235        {0x00, 0xf7, 0x819f},
 236        {0x00, 0xf7, 0x81b0},
 237        {0x00, 0xf7, 0x81c1},
 238        {0x00, 0xff, 0x81a0},
 239        {0x00, 0xff, 0x81b1},
 240        {0x00, 0xff, 0x81c2},
 241        {0x00, 0x03, 0x8156},
 242        {0x00, 0x00, 0x8211},
 243        {0x00, 0x20, 0x8168},
 244        {0x00, 0x01, 0x8202},
 245        {0x00, 0x30, 0x8101},
 246        {0x00, 0x00, 0x8111},
 247        {0x00, 0x00, 0x8112},
 248        {0x00, 0x00, 0x8113},
 249        {0x00, 0x00, 0x8114},
 250        {}
 251};
 252
 253static const __u8 qtable_creative_pccam[2][64] = {
 254        {                               /* Q-table Y-components */
 255         0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
 256         0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
 257         0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
 258         0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
 259         0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
 260         0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
 261         0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
 262         0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
 263        {                               /* Q-table C-components */
 264         0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
 265         0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
 266         0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 267         0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 268         0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 269         0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 270         0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
 271         0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
 272};
 273
 274static const __u8 qtable_kodak_ez200[2][64] = {
 275        {                               /* Q-table Y-components */
 276         0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
 277         0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
 278         0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
 279         0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
 280         0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
 281         0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
 282         0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
 283         0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
 284        {                               /* Q-table C-components */
 285         0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
 286         0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
 287         0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 288         0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 289         0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 290         0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 291         0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 292         0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
 293};
 294
 295static const __u8 qtable_pocketdv[2][64] = {
 296        {               /* Q-table Y-components start registers 0x8800 */
 297         0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
 298         0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
 299         0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
 300         0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
 301         0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
 302         0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
 303         0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
 304         0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
 305         },
 306        {               /* Q-table C-components start registers 0x8840 */
 307         0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
 308         0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
 309         0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
 310         0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 311         0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 312         0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 313         0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
 314         0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
 315};
 316
 317/* read 'len' bytes to gspca_dev->usb_buf */
 318static void reg_r(struct gspca_dev *gspca_dev,
 319                  __u16 index,
 320                  __u16 length)
 321{
 322        usb_control_msg(gspca_dev->dev,
 323                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 324                        0,
 325                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 326                        0,              /* value */
 327                        index, gspca_dev->usb_buf, length, 500);
 328}
 329
 330static int reg_w(struct gspca_dev *gspca_dev,
 331                     __u16 req, __u16 index, __u16 value)
 332{
 333        int ret;
 334
 335        PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
 336        ret = usb_control_msg(gspca_dev->dev,
 337                        usb_sndctrlpipe(gspca_dev->dev, 0),
 338                        req,
 339                        USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 340                        value, index, NULL, 0, 500);
 341        if (ret < 0)
 342                pr_err("reg write: error %d\n", ret);
 343        return ret;
 344}
 345
 346/* returns: negative is error, pos or zero is data */
 347static int reg_r_12(struct gspca_dev *gspca_dev,
 348                        __u16 req,      /* bRequest */
 349                        __u16 index,    /* wIndex */
 350                        __u16 length)   /* wLength (1 or 2 only) */
 351{
 352        int ret;
 353
 354        gspca_dev->usb_buf[1] = 0;
 355        ret = usb_control_msg(gspca_dev->dev,
 356                        usb_rcvctrlpipe(gspca_dev->dev, 0),
 357                        req,
 358                        USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 359                        0,              /* value */
 360                        index,
 361                        gspca_dev->usb_buf, length,
 362                        500);           /* timeout */
 363        if (ret < 0) {
 364                pr_err("reg_r_12 err %d\n", ret);
 365                return ret;
 366        }
 367        return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
 368}
 369
 370/*
 371 * Simple function to wait for a given 8-bit value to be returned from
 372 * a reg_read call.
 373 * Returns: negative is error or timeout, zero is success.
 374 */
 375static int reg_r_wait(struct gspca_dev *gspca_dev,
 376                        __u16 reg, __u16 index, __u16 value)
 377{
 378        int ret, cnt = 20;
 379
 380        while (--cnt > 0) {
 381                ret = reg_r_12(gspca_dev, reg, index, 1);
 382                if (ret == value)
 383                        return 0;
 384                msleep(50);
 385        }
 386        return -EIO;
 387}
 388
 389static int write_vector(struct gspca_dev *gspca_dev,
 390                        const __u16 data[][3])
 391{
 392        int ret, i = 0;
 393
 394        while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
 395                ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
 396                if (ret < 0)
 397                        return ret;
 398                i++;
 399        }
 400        return 0;
 401}
 402
 403static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
 404                                unsigned int request,
 405                                unsigned int ybase,
 406                                unsigned int cbase,
 407                                const __u8 qtable[2][64])
 408{
 409        int i, err;
 410
 411        /* loop over y components */
 412        for (i = 0; i < 64; i++) {
 413                err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
 414                if (err < 0)
 415                        return err;
 416        }
 417
 418        /* loop over c components */
 419        for (i = 0; i < 64; i++) {
 420                err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
 421                if (err < 0)
 422                        return err;
 423        }
 424        return 0;
 425}
 426
 427static void spca500_ping310(struct gspca_dev *gspca_dev)
 428{
 429        reg_r(gspca_dev, 0x0d04, 2);
 430        PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
 431                gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
 432}
 433
 434static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
 435{
 436        reg_r(gspca_dev, 0x0d05, 2);
 437        PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
 438                gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
 439        reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
 440        spca500_ping310(gspca_dev);
 441
 442        reg_w(gspca_dev, 0x00, 0x8168, 0x22);
 443        reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
 444        reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
 445        reg_w(gspca_dev, 0x00, 0x8169, 0x25);
 446        reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
 447        reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
 448        reg_w(gspca_dev, 0x00, 0x813f, 0x03);
 449        reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
 450        reg_w(gspca_dev, 0x00, 0x8153, 0x78);
 451        reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
 452                                                /* 00 for adjust shutter */
 453        reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
 454        reg_w(gspca_dev, 0x00, 0x8169, 0x25);
 455        reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
 456}
 457
 458static void spca500_setmode(struct gspca_dev *gspca_dev,
 459                        __u8 xmult, __u8 ymult)
 460{
 461        int mode;
 462
 463        /* set x multiplier */
 464        reg_w(gspca_dev, 0, 0x8001, xmult);
 465
 466        /* set y multiplier */
 467        reg_w(gspca_dev, 0, 0x8002, ymult);
 468
 469        /* use compressed mode, VGA, with mode specific subsample */
 470        mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 471        reg_w(gspca_dev, 0, 0x8003, mode << 4);
 472}
 473
 474static int spca500_full_reset(struct gspca_dev *gspca_dev)
 475{
 476        int err;
 477
 478        /* send the reset command */
 479        err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
 480        if (err < 0)
 481                return err;
 482
 483        /* wait for the reset to complete */
 484        err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
 485        if (err < 0)
 486                return err;
 487        err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
 488        if (err < 0)
 489                return err;
 490        err = reg_r_wait(gspca_dev, 0x06, 0, 0);
 491        if (err < 0) {
 492                PDEBUG(D_ERR, "reg_r_wait() failed");
 493                return err;
 494        }
 495        /* all ok */
 496        return 0;
 497}
 498
 499/* Synchro the Bridge with sensor */
 500/* Maybe that will work on all spca500 chip */
 501/* because i only own a clicksmart310 try for that chip */
 502/* using spca50x_set_packet_size() cause an Ooops here */
 503/* usb_set_interface from kernel 2.6.x clear all the urb stuff */
 504/* up-port the same feature as in 2.4.x kernel */
 505static int spca500_synch310(struct gspca_dev *gspca_dev)
 506{
 507        if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
 508                PDEBUG(D_ERR, "Set packet size: set interface error");
 509                goto error;
 510        }
 511        spca500_ping310(gspca_dev);
 512
 513        reg_r(gspca_dev, 0x0d00, 1);
 514
 515        /* need alt setting here */
 516        PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
 517
 518        /* Windoze use pipe with altsetting 6 why 7 here */
 519        if (usb_set_interface(gspca_dev->dev,
 520                                gspca_dev->iface,
 521                                gspca_dev->alt) < 0) {
 522                PDEBUG(D_ERR, "Set packet size: set interface error");
 523                goto error;
 524        }
 525        return 0;
 526error:
 527        return -EBUSY;
 528}
 529
 530static void spca500_reinit(struct gspca_dev *gspca_dev)
 531{
 532        int err;
 533        __u8 Data;
 534
 535        /* some unknown command from Aiptek pocket dv and family300 */
 536
 537        reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
 538        reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
 539        reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
 540
 541        /* enable drop packet */
 542        reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 543
 544        err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
 545                                 qtable_pocketdv);
 546        if (err < 0)
 547                PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
 548
 549        /* set qtable index */
 550        reg_w(gspca_dev, 0x00, 0x8880, 2);
 551        /* family cam Quicksmart stuff */
 552        reg_w(gspca_dev, 0x00, 0x800a, 0x00);
 553        /* Set agc transfer: synced between frames */
 554        reg_w(gspca_dev, 0x00, 0x820f, 0x01);
 555        /* Init SDRAM - needed for SDRAM access */
 556        reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 557        /*Start init sequence or stream */
 558        reg_w(gspca_dev, 0, 0x8003, 0x00);
 559        /* switch to video camera mode */
 560        reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 561        msleep(2000);
 562        if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
 563                reg_r(gspca_dev, 0x816b, 1);
 564                Data = gspca_dev->usb_buf[0];
 565                reg_w(gspca_dev, 0x00, 0x816b, Data);
 566        }
 567}
 568
 569/* this function is called at probe time */
 570static int sd_config(struct gspca_dev *gspca_dev,
 571                        const struct usb_device_id *id)
 572{
 573        struct sd *sd = (struct sd *) gspca_dev;
 574        struct cam *cam;
 575
 576        cam = &gspca_dev->cam;
 577        sd->subtype = id->driver_info;
 578        if (sd->subtype != LogitechClickSmart310) {
 579                cam->cam_mode = vga_mode;
 580                cam->nmodes = ARRAY_SIZE(vga_mode);
 581        } else {
 582                cam->cam_mode = sif_mode;
 583                cam->nmodes = ARRAY_SIZE(sif_mode);
 584        }
 585        return 0;
 586}
 587
 588/* this function is called at probe and resume time */
 589static int sd_init(struct gspca_dev *gspca_dev)
 590{
 591        struct sd *sd = (struct sd *) gspca_dev;
 592
 593        /* initialisation of spca500 based cameras is deferred */
 594        PDEBUG(D_STREAM, "SPCA500 init");
 595        if (sd->subtype == LogitechClickSmart310)
 596                spca500_clksmart310_init(gspca_dev);
 597/*      else
 598                spca500_initialise(gspca_dev); */
 599        PDEBUG(D_STREAM, "SPCA500 init done");
 600        return 0;
 601}
 602
 603static int sd_start(struct gspca_dev *gspca_dev)
 604{
 605        struct sd *sd = (struct sd *) gspca_dev;
 606        int err;
 607        __u8 Data;
 608        __u8 xmult, ymult;
 609
 610        /* create the JPEG header */
 611        jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
 612                        0x22);          /* JPEG 411 */
 613        jpeg_set_qual(sd->jpeg_hdr, QUALITY);
 614
 615        if (sd->subtype == LogitechClickSmart310) {
 616                xmult = 0x16;
 617                ymult = 0x12;
 618        } else {
 619                xmult = 0x28;
 620                ymult = 0x1e;
 621        }
 622
 623        /* is there a sensor here ? */
 624        reg_r(gspca_dev, 0x8a04, 1);
 625        PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
 626                gspca_dev->usb_buf[0]);
 627        PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
 628                gspca_dev->curr_mode, xmult, ymult);
 629
 630        /* setup qtable */
 631        switch (sd->subtype) {
 632        case LogitechClickSmart310:
 633                 spca500_setmode(gspca_dev, xmult, ymult);
 634
 635                /* enable drop packet */
 636                reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 637                reg_w(gspca_dev, 0x00, 0x8880, 3);
 638                err = spca50x_setup_qtable(gspca_dev,
 639                                           0x00, 0x8800, 0x8840,
 640                                           qtable_creative_pccam);
 641                if (err < 0)
 642                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 643                /* Init SDRAM - needed for SDRAM access */
 644                reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 645
 646                /* switch to video camera mode */
 647                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 648                msleep(500);
 649                if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
 650                        PDEBUG(D_ERR, "reg_r_wait() failed");
 651
 652                reg_r(gspca_dev, 0x816b, 1);
 653                Data = gspca_dev->usb_buf[0];
 654                reg_w(gspca_dev, 0x00, 0x816b, Data);
 655
 656                spca500_synch310(gspca_dev);
 657
 658                write_vector(gspca_dev, spca500_visual_defaults);
 659                spca500_setmode(gspca_dev, xmult, ymult);
 660                /* enable drop packet */
 661                err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 662                if (err < 0)
 663                        PDEBUG(D_ERR, "failed to enable drop packet");
 664                reg_w(gspca_dev, 0x00, 0x8880, 3);
 665                err = spca50x_setup_qtable(gspca_dev,
 666                                           0x00, 0x8800, 0x8840,
 667                                           qtable_creative_pccam);
 668                if (err < 0)
 669                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 670
 671                /* Init SDRAM - needed for SDRAM access */
 672                reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 673
 674                /* switch to video camera mode */
 675                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 676
 677                if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
 678                        PDEBUG(D_ERR, "reg_r_wait() failed");
 679
 680                reg_r(gspca_dev, 0x816b, 1);
 681                Data = gspca_dev->usb_buf[0];
 682                reg_w(gspca_dev, 0x00, 0x816b, Data);
 683                break;
 684        case CreativePCCam300:          /* Creative PC-CAM 300 640x480 CCD */
 685        case IntelPocketPCCamera:       /* FIXME: Temporary fix for
 686                                         *      Intel Pocket PC Camera
 687                                         *      - NWG (Sat 29th March 2003) */
 688
 689                /* do a full reset */
 690                err = spca500_full_reset(gspca_dev);
 691                if (err < 0)
 692                        PDEBUG(D_ERR, "spca500_full_reset failed");
 693
 694                /* enable drop packet */
 695                err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 696                if (err < 0)
 697                        PDEBUG(D_ERR, "failed to enable drop packet");
 698                reg_w(gspca_dev, 0x00, 0x8880, 3);
 699                err = spca50x_setup_qtable(gspca_dev,
 700                                           0x00, 0x8800, 0x8840,
 701                                           qtable_creative_pccam);
 702                if (err < 0)
 703                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 704
 705                spca500_setmode(gspca_dev, xmult, ymult);
 706                reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
 707
 708                /* switch to video camera mode */
 709                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 710
 711                if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
 712                        PDEBUG(D_ERR, "reg_r_wait() failed");
 713
 714                reg_r(gspca_dev, 0x816b, 1);
 715                Data = gspca_dev->usb_buf[0];
 716                reg_w(gspca_dev, 0x00, 0x816b, Data);
 717
 718/*              write_vector(gspca_dev, spca500_visual_defaults); */
 719                break;
 720        case KodakEZ200:                /* Kodak EZ200 */
 721
 722                /* do a full reset */
 723                err = spca500_full_reset(gspca_dev);
 724                if (err < 0)
 725                        PDEBUG(D_ERR, "spca500_full_reset failed");
 726                /* enable drop packet */
 727                reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 728                reg_w(gspca_dev, 0x00, 0x8880, 0);
 729                err = spca50x_setup_qtable(gspca_dev,
 730                                           0x00, 0x8800, 0x8840,
 731                                           qtable_kodak_ez200);
 732                if (err < 0)
 733                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 734                spca500_setmode(gspca_dev, xmult, ymult);
 735
 736                reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
 737
 738                /* switch to video camera mode */
 739                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 740
 741                if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
 742                        PDEBUG(D_ERR, "reg_r_wait() failed");
 743
 744                reg_r(gspca_dev, 0x816b, 1);
 745                Data = gspca_dev->usb_buf[0];
 746                reg_w(gspca_dev, 0x00, 0x816b, Data);
 747
 748/*              write_vector(gspca_dev, spca500_visual_defaults); */
 749                break;
 750
 751        case BenqDC1016:
 752        case DLinkDSC350:               /* FamilyCam 300 */
 753        case AiptekPocketDV:            /* Aiptek PocketDV */
 754        case Gsmartmini:                /*Mustek Gsmart Mini */
 755        case MustekGsmart300:           /* Mustek Gsmart 300 */
 756        case PalmPixDC85:
 757        case Optimedia:
 758        case ToptroIndus:
 759        case AgfaCl20:
 760                spca500_reinit(gspca_dev);
 761                reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
 762                /* enable drop packet */
 763                reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 764
 765                err = spca50x_setup_qtable(gspca_dev,
 766                                   0x00, 0x8800, 0x8840, qtable_pocketdv);
 767                if (err < 0)
 768                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 769                reg_w(gspca_dev, 0x00, 0x8880, 2);
 770
 771                /* familycam Quicksmart pocketDV stuff */
 772                reg_w(gspca_dev, 0x00, 0x800a, 0x00);
 773                /* Set agc transfer: synced between frames */
 774                reg_w(gspca_dev, 0x00, 0x820f, 0x01);
 775                /* Init SDRAM - needed for SDRAM access */
 776                reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 777
 778                spca500_setmode(gspca_dev, xmult, ymult);
 779                /* switch to video camera mode */
 780                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 781
 782                reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
 783
 784                reg_r(gspca_dev, 0x816b, 1);
 785                Data = gspca_dev->usb_buf[0];
 786                reg_w(gspca_dev, 0x00, 0x816b, Data);
 787                break;
 788        case LogitechTraveler:
 789        case LogitechClickSmart510:
 790                reg_w(gspca_dev, 0x02, 0x00, 0x00);
 791                /* enable drop packet */
 792                reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 793
 794                err = spca50x_setup_qtable(gspca_dev,
 795                                        0x00, 0x8800,
 796                                        0x8840, qtable_creative_pccam);
 797                if (err < 0)
 798                        PDEBUG(D_ERR, "spca50x_setup_qtable failed");
 799                reg_w(gspca_dev, 0x00, 0x8880, 3);
 800                reg_w(gspca_dev, 0x00, 0x800a, 0x00);
 801                /* Init SDRAM - needed for SDRAM access */
 802                reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 803
 804                spca500_setmode(gspca_dev, xmult, ymult);
 805
 806                /* switch to video camera mode */
 807                reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 808                reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
 809
 810                reg_r(gspca_dev, 0x816b, 1);
 811                Data = gspca_dev->usb_buf[0];
 812                reg_w(gspca_dev, 0x00, 0x816b, Data);
 813                write_vector(gspca_dev, Clicksmart510_defaults);
 814                break;
 815        }
 816        return 0;
 817}
 818
 819static void sd_stopN(struct gspca_dev *gspca_dev)
 820{
 821        reg_w(gspca_dev, 0, 0x8003, 0x00);
 822
 823        /* switch to video camera mode */
 824        reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 825        reg_r(gspca_dev, 0x8000, 1);
 826        PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
 827                gspca_dev->usb_buf[0]);
 828}
 829
 830static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 831                        u8 *data,                       /* isoc packet */
 832                        int len)                        /* iso packet length */
 833{
 834        struct sd *sd = (struct sd *) gspca_dev;
 835        int i;
 836        static __u8 ffd9[] = {0xff, 0xd9};
 837
 838/* frames are jpeg 4.1.1 without 0xff escape */
 839        if (data[0] == 0xff) {
 840                if (data[1] != 0x01) {  /* drop packet */
 841/*                      gspca_dev->last_packet_type = DISCARD_PACKET; */
 842                        return;
 843                }
 844                gspca_frame_add(gspca_dev, LAST_PACKET,
 845                                        ffd9, 2);
 846
 847                /* put the JPEG header in the new frame */
 848                gspca_frame_add(gspca_dev, FIRST_PACKET,
 849                        sd->jpeg_hdr, JPEG_HDR_SZ);
 850
 851                data += SPCA500_OFFSET_DATA;
 852                len -= SPCA500_OFFSET_DATA;
 853        } else {
 854                data += 1;
 855                len -= 1;
 856        }
 857
 858        /* add 0x00 after 0xff */
 859        i = 0;
 860        do {
 861                if (data[i] == 0xff) {
 862                        gspca_frame_add(gspca_dev, INTER_PACKET,
 863                                        data, i + 1);
 864                        len -= i;
 865                        data += i;
 866                        *data = 0x00;
 867                        i = 0;
 868                }
 869                i++;
 870        } while (i < len);
 871        gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 872}
 873
 874static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
 875{
 876        reg_w(gspca_dev, 0x00, 0x8167,
 877                        (__u8) (val - 128));
 878}
 879
 880static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
 881{
 882        reg_w(gspca_dev, 0x00, 0x8168, val);
 883}
 884
 885static void setcolors(struct gspca_dev *gspca_dev, s32 val)
 886{
 887        reg_w(gspca_dev, 0x00, 0x8169, val);
 888}
 889
 890static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
 891{
 892        struct gspca_dev *gspca_dev =
 893                container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
 894
 895        gspca_dev->usb_err = 0;
 896
 897        if (!gspca_dev->streaming)
 898                return 0;
 899
 900        switch (ctrl->id) {
 901        case V4L2_CID_BRIGHTNESS:
 902                setbrightness(gspca_dev, ctrl->val);
 903                break;
 904        case V4L2_CID_CONTRAST:
 905                setcontrast(gspca_dev, ctrl->val);
 906                break;
 907        case V4L2_CID_SATURATION:
 908                setcolors(gspca_dev, ctrl->val);
 909                break;
 910        }
 911        return gspca_dev->usb_err;
 912}
 913
 914static const struct v4l2_ctrl_ops sd_ctrl_ops = {
 915        .s_ctrl = sd_s_ctrl,
 916};
 917
 918static int sd_init_controls(struct gspca_dev *gspca_dev)
 919{
 920        struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
 921
 922        gspca_dev->vdev.ctrl_handler = hdl;
 923        v4l2_ctrl_handler_init(hdl, 3);
 924        v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 925                        V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
 926        v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 927                        V4L2_CID_CONTRAST, 0, 63, 1, 31);
 928        v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
 929                        V4L2_CID_SATURATION, 0, 63, 1, 31);
 930
 931        if (hdl->error) {
 932                pr_err("Could not initialize controls\n");
 933                return hdl->error;
 934        }
 935        return 0;
 936}
 937
 938/* sub-driver description */
 939static const struct sd_desc sd_desc = {
 940        .name = MODULE_NAME,
 941        .config = sd_config,
 942        .init = sd_init,
 943        .init_controls = sd_init_controls,
 944        .start = sd_start,
 945        .stopN = sd_stopN,
 946        .pkt_scan = sd_pkt_scan,
 947};
 948
 949/* -- module initialisation -- */
 950static const struct usb_device_id device_table[] = {
 951        {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
 952        {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
 953        {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
 954        {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
 955        {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
 956        {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
 957        {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
 958        {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
 959        {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
 960        {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
 961        {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
 962        {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
 963        {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
 964        {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
 965        {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
 966        {}
 967};
 968MODULE_DEVICE_TABLE(usb, device_table);
 969
 970/* -- device connect -- */
 971static int sd_probe(struct usb_interface *intf,
 972                        const struct usb_device_id *id)
 973{
 974        return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
 975                                THIS_MODULE);
 976}
 977
 978static struct usb_driver sd_driver = {
 979        .name = MODULE_NAME,
 980        .id_table = device_table,
 981        .probe = sd_probe,
 982        .disconnect = gspca_disconnect,
 983#ifdef CONFIG_PM
 984        .suspend = gspca_suspend,
 985        .resume = gspca_resume,
 986        .reset_resume = gspca_resume,
 987#endif
 988};
 989
 990module_usb_driver(sd_driver);
 991