0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #define MODULE_NAME "spca505"
0011
0012 #include "gspca.h"
0013
0014 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
0015 MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver");
0016 MODULE_LICENSE("GPL");
0017
0018
0019 struct sd {
0020 struct gspca_dev gspca_dev;
0021
0022 u8 subtype;
0023 #define IntelPCCameraPro 0
0024 #define Nxultra 1
0025 };
0026
0027 static const struct v4l2_pix_format vga_mode[] = {
0028 {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
0029 .bytesperline = 160,
0030 .sizeimage = 160 * 120 * 3 / 2,
0031 .colorspace = V4L2_COLORSPACE_SRGB,
0032 .priv = 4},
0033 {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
0034 .bytesperline = 176,
0035 .sizeimage = 176 * 144 * 3 / 2,
0036 .colorspace = V4L2_COLORSPACE_SRGB,
0037 .priv = 3},
0038 {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
0039 .bytesperline = 320,
0040 .sizeimage = 320 * 240 * 3 / 2,
0041 .colorspace = V4L2_COLORSPACE_SRGB,
0042 .priv = 2},
0043 {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
0044 .bytesperline = 352,
0045 .sizeimage = 352 * 288 * 3 / 2,
0046 .colorspace = V4L2_COLORSPACE_SRGB,
0047 .priv = 1},
0048 {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
0049 .bytesperline = 640,
0050 .sizeimage = 640 * 480 * 3 / 2,
0051 .colorspace = V4L2_COLORSPACE_SRGB,
0052 .priv = 0},
0053 };
0054
0055 #define SPCA50X_OFFSET_DATA 10
0056
0057 #define SPCA50X_REG_USB 0x02
0058
0059 #define SPCA50X_USB_CTRL 0x00
0060 #define SPCA50X_CUSB_ENABLE 0x01
0061
0062 #define SPCA50X_REG_GLOBAL 0x03
0063 #define SPCA50X_GMISC0_IDSEL 0x01
0064 #define SPCA50X_GLOBAL_MISC0 0x00
0065
0066 #define SPCA50X_GLOBAL_MISC1 0x01
0067 #define SPCA50X_GLOBAL_MISC3 0x03
0068 #define SPCA50X_GMISC3_SAA7113RST 0x20
0069
0070
0071 #define SPCA50X_REG_COMPRESS 0x04
0072
0073
0074
0075
0076 static const u8 spca505_init_data[][3] = {
0077
0078 {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
0079
0080 {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
0081 {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
0082
0083 {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0},
0084
0085 {0x05, 0x01, 0x10},
0086
0087 {0x05, 0x0f, 0x11},
0088
0089
0090 {0x06, 0x10, 0x08},
0091 {0x06, 0x00, 0x09},
0092 {0x06, 0x00, 0x0a},
0093 {0x06, 0x00, 0x0b},
0094 {0x06, 0x10, 0x0c},
0095 {0x06, 0x00, 0x0d},
0096 {0x06, 0x00, 0x0e},
0097 {0x06, 0x00, 0x0f},
0098 {0x06, 0x10, 0x10},
0099 {0x06, 0x02, 0x11},
0100 {0x06, 0x00, 0x12},
0101 {0x06, 0x04, 0x13},
0102 {0x06, 0x02, 0x14},
0103 {0x06, 0x8a, 0x51},
0104 {0x06, 0x40, 0x52},
0105 {0x06, 0xb6, 0x53},
0106 {0x06, 0x3d, 0x54},
0107 {}
0108 };
0109
0110
0111
0112
0113 static const u8 spca505_open_data_ccd[][3] = {
0114
0115
0116 {0x03, 0x04, 0x01},
0117
0118 {0x03, 0x00, 0x01},
0119
0120
0121
0122 {0x04, 0x10, 0x01},
0123
0124 {0x04, 0x00, 0x04},
0125 {0x04, 0x00, 0x05},
0126 {0x04, 0x20, 0x06},
0127 {0x04, 0x20, 0x07},
0128
0129 {0x08, 0x0a, 0x00},
0130
0131
0132 {0x05, 0x00, 0x10},
0133 {0x05, 0x00, 0x11},
0134 {0x05, 0x00, 0x00},
0135
0136 {0x05, 0x00, 0x01},
0137
0138 {0x05, 0x00, 0x02},
0139
0140 {0x05, 0x00, 0x03},
0141
0142 {0x05, 0x00, 0x04},
0143
0144 {0x05, 0x80, 0x05},
0145
0146 {0x05, 0xe0, 0x06},
0147
0148 {0x05, 0x20, 0x07},
0149
0150 {0x05, 0xa0, 0x08},
0151
0152 {0x05, 0x0, 0x12},
0153
0154 {0x05, 0x02, 0x0f},
0155
0156 {0x05, 0x10, 0x46},
0157
0158 {0x05, 0x8, 0x4a},
0159
0160
0161 {0x03, 0x08, 0x03},
0162
0163 {0x03, 0x08, 0x01},
0164 {0x03, 0x0c, 0x03},
0165
0166 {0x03, 0x21, 0x00},
0167
0168
0169
0170 {0x06, 0x10, 0x08},
0171 {0x06, 0x00, 0x09},
0172 {0x06, 0x00, 0x0a},
0173 {0x06, 0x00, 0x0b},
0174 {0x06, 0x10, 0x0c},
0175 {0x06, 0x00, 0x0d},
0176 {0x06, 0x00, 0x0e},
0177 {0x06, 0x00, 0x0f},
0178 {0x06, 0x10, 0x10},
0179 {0x06, 0x02, 0x11},
0180 {0x06, 0x00, 0x12},
0181 {0x06, 0x04, 0x13},
0182 {0x06, 0x02, 0x14},
0183 {0x06, 0x8a, 0x51},
0184 {0x06, 0x40, 0x52},
0185 {0x06, 0xb6, 0x53},
0186 {0x06, 0x3d, 0x54},
0187
0188
0189 {0x06, 0x3f, 0x1},
0190
0191 {0x06, 0x10, 0x02},
0192 {0x06, 0x64, 0x07},
0193 {0x06, 0x10, 0x08},
0194 {0x06, 0x00, 0x09},
0195 {0x06, 0x00, 0x0a},
0196 {0x06, 0x00, 0x0b},
0197 {0x06, 0x10, 0x0c},
0198 {0x06, 0x00, 0x0d},
0199 {0x06, 0x00, 0x0e},
0200 {0x06, 0x00, 0x0f},
0201 {0x06, 0x10, 0x10},
0202 {0x06, 0x02, 0x11},
0203 {0x06, 0x00, 0x12},
0204 {0x06, 0x04, 0x13},
0205 {0x06, 0x02, 0x14},
0206 {0x06, 0x8a, 0x51},
0207 {0x06, 0x40, 0x52},
0208 {0x06, 0xb6, 0x53},
0209 {0x06, 0x3d, 0x54},
0210 {0x06, 0x60, 0x57},
0211 {0x06, 0x20, 0x58},
0212 {0x06, 0x15, 0x59},
0213 {0x06, 0x05, 0x5a},
0214
0215 {0x05, 0x01, 0xc0},
0216 {0x05, 0x10, 0xcb},
0217 {0x05, 0x80, 0xc1},
0218
0219 {0x05, 0x0, 0xc2},
0220
0221 {0x05, 0x00, 0xca},
0222 {0x05, 0x80, 0xc1},
0223
0224 {0x05, 0x04, 0xc2},
0225 {0x05, 0x00, 0xca},
0226 {0x05, 0x0, 0xc1},
0227
0228 {0x05, 0x00, 0xc2},
0229 {0x05, 0x00, 0xca},
0230 {0x05, 0x40, 0xc1},
0231
0232 {0x05, 0x17, 0xc2},
0233 {0x05, 0x00, 0xca},
0234 {0x05, 0x80, 0xc1},
0235
0236 {0x05, 0x06, 0xc2},
0237 {0x05, 0x00, 0xca},
0238 {0x05, 0x80, 0xc1},
0239
0240 {0x05, 0x04, 0xc2},
0241 {0x05, 0x00, 0xca},
0242
0243 {0x03, 0x4c, 0x3},
0244 {0x03, 0x18, 0x1},
0245
0246 {0x06, 0x70, 0x51},
0247 {0x06, 0xbe, 0x53},
0248 {0x06, 0x71, 0x57},
0249 {0x06, 0x20, 0x58},
0250 {0x06, 0x05, 0x59},
0251 {0x06, 0x15, 0x5a},
0252
0253 {0x04, 0x00, 0x08},
0254
0255 {0x04, 0x12, 0x09},
0256 {0x04, 0x21, 0x0a},
0257 {0x04, 0x10, 0x0b},
0258 {0x04, 0x21, 0x0c},
0259 {0x04, 0x05, 0x00},
0260
0261 {0x04, 0x00, 0x01},
0262
0263 {0x06, 0x3f, 0x01},
0264
0265 {0x04, 0x00, 0x04},
0266 {0x04, 0x00, 0x05},
0267 {0x04, 0x40, 0x06},
0268 {0x04, 0x40, 0x07},
0269
0270 {0x06, 0x1c, 0x17},
0271 {0x06, 0xe2, 0x19},
0272 {0x06, 0x1c, 0x1b},
0273 {0x06, 0xe2, 0x1d},
0274 {0x06, 0xaa, 0x1f},
0275 {0x06, 0x70, 0x20},
0276
0277 {0x05, 0x01, 0x10},
0278 {0x05, 0x00, 0x11},
0279 {0x05, 0x01, 0x00},
0280 {0x05, 0x05, 0x01},
0281 {0x05, 0x00, 0xc1},
0282
0283 {0x05, 0x00, 0xc2},
0284 {0x05, 0x00, 0xca},
0285
0286 {0x06, 0x70, 0x51},
0287 {0x06, 0xbe, 0x53},
0288 {}
0289 };
0290
0291
0292
0293
0294
0295
0296 #define initial_brightness 0x7f
0297
0298
0299
0300
0301 static const u8 spca505b_init_data[][3] = {
0302
0303 {0x02, 0x00, 0x00},
0304 {0x02, 0x00, 0x01},
0305 {0x02, 0x00, 0x02},
0306 {0x02, 0x00, 0x03},
0307 {0x02, 0x00, 0x04},
0308 {0x02, 0x00, 0x05},
0309 {0x02, 0x00, 0x06},
0310 {0x02, 0x00, 0x07},
0311 {0x02, 0x00, 0x08},
0312 {0x02, 0x00, 0x09},
0313 {0x03, 0x00, 0x00},
0314 {0x03, 0x00, 0x01},
0315 {0x03, 0x00, 0x02},
0316 {0x03, 0x00, 0x03},
0317 {0x03, 0x00, 0x04},
0318 {0x03, 0x00, 0x05},
0319 {0x03, 0x00, 0x06},
0320 {0x04, 0x00, 0x00},
0321 {0x04, 0x00, 0x02},
0322 {0x04, 0x00, 0x04},
0323 {0x04, 0x00, 0x05},
0324 {0x04, 0x00, 0x06},
0325 {0x04, 0x00, 0x07},
0326 {0x04, 0x00, 0x08},
0327 {0x04, 0x00, 0x09},
0328 {0x04, 0x00, 0x0a},
0329 {0x04, 0x00, 0x0b},
0330 {0x04, 0x00, 0x0c},
0331 {0x07, 0x00, 0x00},
0332 {0x07, 0x00, 0x03},
0333 {0x08, 0x00, 0x00},
0334 {0x08, 0x00, 0x01},
0335 {0x08, 0x00, 0x02},
0336 {0x06, 0x18, 0x08},
0337 {0x06, 0xfc, 0x09},
0338 {0x06, 0xfc, 0x0a},
0339 {0x06, 0xfc, 0x0b},
0340 {0x06, 0x18, 0x0c},
0341 {0x06, 0xfc, 0x0d},
0342 {0x06, 0xfc, 0x0e},
0343 {0x06, 0xfc, 0x0f},
0344 {0x06, 0x18, 0x10},
0345 {0x06, 0xfe, 0x12},
0346 {0x06, 0x00, 0x11},
0347 {0x06, 0x00, 0x14},
0348 {0x06, 0x00, 0x13},
0349 {0x06, 0x28, 0x51},
0350 {0x06, 0xff, 0x53},
0351 {0x02, 0x00, 0x08},
0352
0353 {0x03, 0x00, 0x03},
0354 {0x03, 0x10, 0x03},
0355 {}
0356 };
0357
0358
0359
0360
0361 static const u8 spca505b_open_data_ccd[][3] = {
0362
0363
0364 {0x03, 0x04, 0x01},
0365 {0x03, 0x00, 0x01},
0366 {0x03, 0x00, 0x00},
0367 {0x03, 0x21, 0x00},
0368 {0x03, 0x00, 0x04},
0369 {0x03, 0x00, 0x03},
0370 {0x03, 0x18, 0x03},
0371 {0x03, 0x08, 0x01},
0372 {0x03, 0x1c, 0x03},
0373 {0x03, 0x5c, 0x03},
0374 {0x03, 0x5c, 0x03},
0375 {0x03, 0x18, 0x01},
0376
0377
0378 {0x04, 0x10, 0x01},
0379 {0x04, 0x00, 0x04},
0380 {0x04, 0x00, 0x05},
0381 {0x04, 0x20, 0x06},
0382 {0x04, 0x20, 0x07},
0383
0384 {0x08, 0x0a, 0x00},
0385
0386 {0x05, 0x00, 0x10},
0387 {0x05, 0x00, 0x11},
0388 {0x05, 0x00, 0x12},
0389 {0x05, 0x6f, 0x00},
0390 {0x05, initial_brightness >> 6, 0x00},
0391 {0x05, (initial_brightness << 2) & 0xff, 0x01},
0392 {0x05, 0x00, 0x02},
0393 {0x05, 0x01, 0x03},
0394 {0x05, 0x00, 0x04},
0395 {0x05, 0x03, 0x05},
0396 {0x05, 0xe0, 0x06},
0397 {0x05, 0x20, 0x07},
0398 {0x05, 0xa0, 0x08},
0399 {0x05, 0x00, 0x12},
0400 {0x05, 0x02, 0x0f},
0401 {0x05, 0x80, 0x14},
0402 {0x05, 0x01, 0xb0},
0403 {0x05, 0x01, 0xbf},
0404 {0x03, 0x02, 0x06},
0405 {0x05, 0x10, 0x46},
0406 {0x05, 0x08, 0x4a},
0407
0408 {0x06, 0x00, 0x01},
0409 {0x06, 0x10, 0x02},
0410 {0x06, 0x64, 0x07},
0411 {0x06, 0x18, 0x08},
0412 {0x06, 0xfc, 0x09},
0413 {0x06, 0xfc, 0x0a},
0414 {0x06, 0xfc, 0x0b},
0415 {0x04, 0x00, 0x01},
0416 {0x06, 0x18, 0x0c},
0417 {0x06, 0xfc, 0x0d},
0418 {0x06, 0xfc, 0x0e},
0419 {0x06, 0xfc, 0x0f},
0420 {0x06, 0x11, 0x10},
0421 {0x06, 0x00, 0x11},
0422 {0x06, 0xfe, 0x12},
0423 {0x06, 0x00, 0x13},
0424 {0x06, 0x00, 0x14},
0425 {0x06, 0x9d, 0x51},
0426 {0x06, 0x40, 0x52},
0427 {0x06, 0x7c, 0x53},
0428 {0x06, 0x40, 0x54},
0429 {0x06, 0x02, 0x57},
0430 {0x06, 0x03, 0x58},
0431 {0x06, 0x15, 0x59},
0432 {0x06, 0x05, 0x5a},
0433 {0x06, 0x03, 0x56},
0434 {0x06, 0x02, 0x3f},
0435 {0x06, 0x00, 0x40},
0436 {0x06, 0x39, 0x41},
0437 {0x06, 0x69, 0x42},
0438 {0x06, 0x87, 0x43},
0439 {0x06, 0x9e, 0x44},
0440 {0x06, 0xb1, 0x45},
0441 {0x06, 0xbf, 0x46},
0442 {0x06, 0xcc, 0x47},
0443 {0x06, 0xd5, 0x48},
0444 {0x06, 0xdd, 0x49},
0445 {0x06, 0xe3, 0x4a},
0446 {0x06, 0xe8, 0x4b},
0447 {0x06, 0xed, 0x4c},
0448 {0x06, 0xf2, 0x4d},
0449 {0x06, 0xf7, 0x4e},
0450 {0x06, 0xfc, 0x4f},
0451 {0x06, 0xff, 0x50},
0452
0453 {0x05, 0x01, 0xc0},
0454 {0x05, 0x10, 0xcb},
0455 {0x05, 0x40, 0xc1},
0456 {0x05, 0x04, 0xc2},
0457 {0x05, 0x00, 0xca},
0458 {0x05, 0x40, 0xc1},
0459 {0x05, 0x09, 0xc2},
0460 {0x05, 0x00, 0xca},
0461 {0x05, 0xc0, 0xc1},
0462 {0x05, 0x09, 0xc2},
0463 {0x05, 0x00, 0xca},
0464 {0x05, 0x40, 0xc1},
0465 {0x05, 0x59, 0xc2},
0466 {0x05, 0x00, 0xca},
0467 {0x04, 0x00, 0x01},
0468 {0x05, 0x80, 0xc1},
0469 {0x05, 0xec, 0xc2},
0470 {0x05, 0x0, 0xca},
0471
0472 {0x06, 0x02, 0x57},
0473 {0x06, 0x01, 0x58},
0474 {0x06, 0x15, 0x59},
0475 {0x06, 0x0a, 0x5a},
0476 {0x06, 0x01, 0x57},
0477 {0x06, 0x8a, 0x03},
0478 {0x06, 0x0a, 0x6c},
0479 {0x06, 0x30, 0x01},
0480 {0x06, 0x20, 0x02},
0481 {0x06, 0x00, 0x03},
0482
0483 {0x05, 0x8c, 0x25},
0484
0485 {0x06, 0x4d, 0x51},
0486 {0x06, 0x84, 0x53},
0487 {0x06, 0x00, 0x57},
0488 {0x06, 0x18, 0x08},
0489 {0x06, 0xfc, 0x09},
0490 {0x06, 0xfc, 0x0a},
0491 {0x06, 0xfc, 0x0b},
0492 {0x06, 0x18, 0x0c},
0493 {0x06, 0xfc, 0x0d},
0494 {0x06, 0xfc, 0x0e},
0495 {0x06, 0xfc, 0x0f},
0496 {0x06, 0x18, 0x10},
0497
0498 {0x05, 0x01, 0x02},
0499
0500 {0x04, 0x00, 0x08},
0501 {0x04, 0x12, 0x09},
0502 {0x04, 0x21, 0x0a},
0503 {0x04, 0x10, 0x0b},
0504 {0x04, 0x21, 0x0c},
0505 {0x04, 0x1d, 0x00},
0506 {0x04, 0x41, 0x01},
0507
0508 {0x04, 0x00, 0x04},
0509 {0x04, 0x00, 0x05},
0510 {0x04, 0x10, 0x06},
0511 {0x04, 0x10, 0x07},
0512 {0x04, 0x40, 0x06},
0513 {0x04, 0x40, 0x07},
0514 {0x04, 0x00, 0x04},
0515 {0x04, 0x00, 0x05},
0516
0517 {0x06, 0x1c, 0x17},
0518 {0x06, 0xe2, 0x19},
0519 {0x06, 0x1c, 0x1b},
0520 {0x06, 0xe2, 0x1d},
0521 {0x06, 0x5f, 0x1f},
0522 {0x06, 0x32, 0x20},
0523
0524 {0x05, initial_brightness >> 6, 0x00},
0525 {0x05, (initial_brightness << 2) & 0xff, 0x01},
0526 {0x05, 0x06, 0xc1},
0527 {0x05, 0x58, 0xc2},
0528 {0x05, 0x00, 0xca},
0529 {0x05, 0x00, 0x11},
0530 {}
0531 };
0532
0533 static int reg_write(struct gspca_dev *gspca_dev,
0534 u16 req, u16 index, u16 value)
0535 {
0536 int ret;
0537 struct usb_device *dev = gspca_dev->dev;
0538
0539 ret = usb_control_msg(dev,
0540 usb_sndctrlpipe(dev, 0),
0541 req,
0542 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0543 value, index, NULL, 0, 500);
0544 gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d\n",
0545 req, index, value, ret);
0546 if (ret < 0)
0547 pr_err("reg write: error %d\n", ret);
0548 return ret;
0549 }
0550
0551
0552 static int reg_read(struct gspca_dev *gspca_dev,
0553 u16 req,
0554 u16 index)
0555 {
0556 int ret;
0557
0558 ret = usb_control_msg(gspca_dev->dev,
0559 usb_rcvctrlpipe(gspca_dev->dev, 0),
0560 req,
0561 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0562 0,
0563 index,
0564 gspca_dev->usb_buf, 2,
0565 500);
0566 if (ret < 0)
0567 return ret;
0568 return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
0569 }
0570
0571 static int write_vector(struct gspca_dev *gspca_dev,
0572 const u8 data[][3])
0573 {
0574 int ret, i = 0;
0575
0576 while (data[i][0] != 0) {
0577 ret = reg_write(gspca_dev, data[i][0], data[i][2],
0578 data[i][1]);
0579 if (ret < 0)
0580 return ret;
0581 i++;
0582 }
0583 return 0;
0584 }
0585
0586
0587 static int sd_config(struct gspca_dev *gspca_dev,
0588 const struct usb_device_id *id)
0589 {
0590 struct sd *sd = (struct sd *) gspca_dev;
0591 struct cam *cam;
0592
0593 cam = &gspca_dev->cam;
0594 cam->cam_mode = vga_mode;
0595 sd->subtype = id->driver_info;
0596 if (sd->subtype != IntelPCCameraPro)
0597 cam->nmodes = ARRAY_SIZE(vga_mode);
0598 else
0599 cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
0600
0601 return 0;
0602 }
0603
0604
0605 static int sd_init(struct gspca_dev *gspca_dev)
0606 {
0607 struct sd *sd = (struct sd *) gspca_dev;
0608
0609 if (write_vector(gspca_dev,
0610 sd->subtype == Nxultra
0611 ? spca505b_init_data
0612 : spca505_init_data))
0613 return -EIO;
0614 return 0;
0615 }
0616
0617 static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
0618 {
0619 reg_write(gspca_dev, 0x05, 0x00, (255 - brightness) >> 6);
0620 reg_write(gspca_dev, 0x05, 0x01, (255 - brightness) << 2);
0621 }
0622
0623 static int sd_start(struct gspca_dev *gspca_dev)
0624 {
0625 struct sd *sd = (struct sd *) gspca_dev;
0626 int ret, mode;
0627 static u8 mode_tb[][3] = {
0628
0629 {0x00, 0x10, 0x10},
0630 {0x01, 0x1a, 0x1a},
0631 {0x02, 0x1c, 0x1d},
0632 {0x04, 0x34, 0x34},
0633 {0x05, 0x40, 0x40}
0634 };
0635
0636 if (sd->subtype == Nxultra)
0637 write_vector(gspca_dev, spca505b_open_data_ccd);
0638 else
0639 write_vector(gspca_dev, spca505_open_data_ccd);
0640 ret = reg_read(gspca_dev, 0x06, 0x16);
0641
0642 if (ret < 0) {
0643 gspca_err(gspca_dev, "register read failed err: %d\n", ret);
0644 return ret;
0645 }
0646 if (ret != 0x0101) {
0647 pr_err("After vector read returns 0x%04x should be 0x0101\n",
0648 ret);
0649 }
0650
0651 ret = reg_write(gspca_dev, 0x06, 0x16, 0x0a);
0652 if (ret < 0)
0653 return ret;
0654 reg_write(gspca_dev, 0x05, 0xc2, 0x12);
0655
0656
0657
0658
0659 reg_write(gspca_dev, 0x02, 0x00, 0x00);
0660
0661 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
0662 reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]);
0663 reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]);
0664 reg_write(gspca_dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]);
0665
0666 return reg_write(gspca_dev, SPCA50X_REG_USB,
0667 SPCA50X_USB_CTRL,
0668 SPCA50X_CUSB_ENABLE);
0669 }
0670
0671 static void sd_stopN(struct gspca_dev *gspca_dev)
0672 {
0673
0674 reg_write(gspca_dev, 0x02, 0x00, 0x00);
0675 }
0676
0677
0678 static void sd_stop0(struct gspca_dev *gspca_dev)
0679 {
0680 if (!gspca_dev->present)
0681 return;
0682
0683
0684 reg_write(gspca_dev, 0x03, 0x03, 0x20);
0685 reg_write(gspca_dev, 0x03, 0x01, 0x00);
0686 reg_write(gspca_dev, 0x03, 0x00, 0x01);
0687 reg_write(gspca_dev, 0x05, 0x10, 0x01);
0688 reg_write(gspca_dev, 0x05, 0x11, 0x0f);
0689 }
0690
0691 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
0692 u8 *data,
0693 int len)
0694 {
0695 switch (data[0]) {
0696 case 0:
0697 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
0698 data += SPCA50X_OFFSET_DATA;
0699 len -= SPCA50X_OFFSET_DATA;
0700 gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
0701 break;
0702 case 0xff:
0703 break;
0704 default:
0705 data += 1;
0706 len -= 1;
0707 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
0708 break;
0709 }
0710 }
0711
0712 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
0713 {
0714 struct gspca_dev *gspca_dev =
0715 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
0716
0717 gspca_dev->usb_err = 0;
0718
0719 if (!gspca_dev->streaming)
0720 return 0;
0721
0722 switch (ctrl->id) {
0723 case V4L2_CID_BRIGHTNESS:
0724 setbrightness(gspca_dev, ctrl->val);
0725 break;
0726 }
0727 return gspca_dev->usb_err;
0728 }
0729
0730 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
0731 .s_ctrl = sd_s_ctrl,
0732 };
0733
0734 static int sd_init_controls(struct gspca_dev *gspca_dev)
0735 {
0736 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
0737
0738 gspca_dev->vdev.ctrl_handler = hdl;
0739 v4l2_ctrl_handler_init(hdl, 5);
0740 v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
0741 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
0742
0743 if (hdl->error) {
0744 pr_err("Could not initialize controls\n");
0745 return hdl->error;
0746 }
0747 return 0;
0748 }
0749
0750
0751 static const struct sd_desc sd_desc = {
0752 .name = MODULE_NAME,
0753 .config = sd_config,
0754 .init_controls = sd_init_controls,
0755 .init = sd_init,
0756 .start = sd_start,
0757 .stopN = sd_stopN,
0758 .stop0 = sd_stop0,
0759 .pkt_scan = sd_pkt_scan,
0760 };
0761
0762
0763 static const struct usb_device_id device_table[] = {
0764 {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra},
0765 {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro},
0766
0767 {}
0768 };
0769 MODULE_DEVICE_TABLE(usb, device_table);
0770
0771
0772 static int sd_probe(struct usb_interface *intf,
0773 const struct usb_device_id *id)
0774 {
0775 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
0776 THIS_MODULE);
0777 }
0778
0779 static struct usb_driver sd_driver = {
0780 .name = MODULE_NAME,
0781 .id_table = device_table,
0782 .probe = sd_probe,
0783 .disconnect = gspca_disconnect,
0784 #ifdef CONFIG_PM
0785 .suspend = gspca_suspend,
0786 .resume = gspca_resume,
0787 .reset_resume = gspca_resume,
0788 #endif
0789 };
0790
0791 module_usb_driver(sd_driver);