1/* 2 * T613 subdriver 3 * 4 * Copyright (C) 2010 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 *Notes: * t613 + tas5130A 21 * * Focus to light do not balance well as in win. 22 * Quality in win is not good, but its kinda better. 23 * * Fix some "extraneous bytes", most of apps will show the image anyway 24 * * Gamma table, is there, but its really doing something? 25 * * 7~8 Fps, its ok, max on win its 10. 26 * Costantino Leandro 27 */ 28 29#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 30 31#define MODULE_NAME "t613" 32 33#include <linux/input.h> 34#include <linux/slab.h> 35#include "gspca.h" 36 37#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0) 38 39MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>"); 40MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); 41MODULE_LICENSE("GPL"); 42 43struct sd { 44 struct gspca_dev gspca_dev; /* !! must be the first item */ 45 46 u8 brightness; 47 u8 contrast; 48 u8 colors; 49 u8 autogain; 50 u8 gamma; 51 u8 sharpness; 52 u8 freq; 53 u8 red_gain; 54 u8 blue_gain; 55 u8 green_gain; 56 u8 awb; /* set default r/g/b and activate */ 57 u8 mirror; 58 u8 effect; 59 60 u8 sensor; 61 u8 button_pressed; 62}; 63enum sensors { 64 SENSOR_OM6802, 65 SENSOR_OTHER, 66 SENSOR_TAS5130A, 67 SENSOR_LT168G, /* must verify if this is the actual model */ 68}; 69 70/* V4L2 controls supported by the driver */ 71static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 72static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 73static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); 74static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); 75static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); 76static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); 77static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val); 78static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val); 79static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); 80static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); 81static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 82static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 83static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); 84static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); 85 86static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); 87static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); 88static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val); 89static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val); 90static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val); 91static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val); 92static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 93static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 94 95static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val); 96static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val); 97static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); 98static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); 99 100static const struct ctrl sd_ctrls[] = { 101 { 102 { 103 .id = V4L2_CID_BRIGHTNESS, 104 .type = V4L2_CTRL_TYPE_INTEGER, 105 .name = "Brightness", 106 .minimum = 0, 107 .maximum = 14, 108 .step = 1, 109#define BRIGHTNESS_DEF 8 110 .default_value = BRIGHTNESS_DEF, 111 }, 112 .set = sd_setbrightness, 113 .get = sd_getbrightness, 114 }, 115 { 116 { 117 .id = V4L2_CID_CONTRAST, 118 .type = V4L2_CTRL_TYPE_INTEGER, 119 .name = "Contrast", 120 .minimum = 0, 121 .maximum = 0x0d, 122 .step = 1, 123#define CONTRAST_DEF 0x07 124 .default_value = CONTRAST_DEF, 125 }, 126 .set = sd_setcontrast, 127 .get = sd_getcontrast, 128 }, 129 { 130 { 131 .id = V4L2_CID_SATURATION, 132 .type = V4L2_CTRL_TYPE_INTEGER, 133 .name = "Color", 134 .minimum = 0, 135 .maximum = 0x0f, 136 .step = 1, 137#define COLORS_DEF 0x05 138 .default_value = COLORS_DEF, 139 }, 140 .set = sd_setcolors, 141 .get = sd_getcolors, 142 }, 143#define GAMMA_MAX 16 144#define GAMMA_DEF 10 145 { 146 { 147 .id = V4L2_CID_GAMMA, /* (gamma on win) */ 148 .type = V4L2_CTRL_TYPE_INTEGER, 149 .name = "Gamma", 150 .minimum = 0, 151 .maximum = GAMMA_MAX - 1, 152 .step = 1, 153 .default_value = GAMMA_DEF, 154 }, 155 .set = sd_setgamma, 156 .get = sd_getgamma, 157 }, 158 { 159 { 160 .id = V4L2_CID_BACKLIGHT_COMPENSATION, /* Activa lowlight, 161 * some apps dont bring up the 162 * backligth_compensation control) */ 163 .type = V4L2_CTRL_TYPE_INTEGER, 164 .name = "Low Light", 165 .minimum = 0, 166 .maximum = 1, 167 .step = 1, 168#define AUTOGAIN_DEF 0x01 169 .default_value = AUTOGAIN_DEF, 170 }, 171 .set = sd_setlowlight, 172 .get = sd_getlowlight, 173 }, 174 { 175 { 176 .id = V4L2_CID_HFLIP, 177 .type = V4L2_CTRL_TYPE_BOOLEAN, 178 .name = "Mirror Image", 179 .minimum = 0, 180 .maximum = 1, 181 .step = 1, 182#define MIRROR_DEF 0 183 .default_value = MIRROR_DEF, 184 }, 185 .set = sd_setmirror, 186 .get = sd_getmirror 187 }, 188 { 189 { 190 .id = V4L2_CID_POWER_LINE_FREQUENCY, 191 .type = V4L2_CTRL_TYPE_MENU, 192 .name = "Light Frequency Filter", 193 .minimum = 1, /* 1 -> 0x50, 2->0x60 */ 194 .maximum = 2, 195 .step = 1, 196#define FREQ_DEF 1 197 .default_value = FREQ_DEF, 198 }, 199 .set = sd_setfreq, 200 .get = sd_getfreq}, 201 202 { 203 { 204 .id = V4L2_CID_AUTO_WHITE_BALANCE, 205 .type = V4L2_CTRL_TYPE_INTEGER, 206 .name = "Auto White Balance", 207 .minimum = 0, 208 .maximum = 1, 209 .step = 1, 210#define AWB_DEF 0 211 .default_value = AWB_DEF, 212 }, 213 .set = sd_setawb, 214 .get = sd_getawb 215 }, 216 { 217 { 218 .id = V4L2_CID_SHARPNESS, 219 .type = V4L2_CTRL_TYPE_INTEGER, 220 .name = "Sharpness", 221 .minimum = 0, 222 .maximum = 15, 223 .step = 1, 224#define SHARPNESS_DEF 0x06 225 .default_value = SHARPNESS_DEF, 226 }, 227 .set = sd_setsharpness, 228 .get = sd_getsharpness, 229 }, 230 { 231 { 232 .id = V4L2_CID_EFFECTS, 233 .type = V4L2_CTRL_TYPE_MENU, 234 .name = "Webcam Effects", 235 .minimum = 0, 236 .maximum = 4, 237 .step = 1, 238#define EFFECTS_DEF 0 239 .default_value = EFFECTS_DEF, 240 }, 241 .set = sd_seteffect, 242 .get = sd_geteffect 243 }, 244 { 245 { 246 .id = V4L2_CID_BLUE_BALANCE, 247 .type = V4L2_CTRL_TYPE_INTEGER, 248 .name = "Blue Balance", 249 .minimum = 0x10, 250 .maximum = 0x40, 251 .step = 1, 252#define BLUE_GAIN_DEF 0x20 253 .default_value = BLUE_GAIN_DEF, 254 }, 255 .set = sd_setblue_gain, 256 .get = sd_getblue_gain, 257 }, 258 { 259 { 260 .id = V4L2_CID_RED_BALANCE, 261 .type = V4L2_CTRL_TYPE_INTEGER, 262 .name = "Red Balance", 263 .minimum = 0x10, 264 .maximum = 0x40, 265 .step = 1, 266#define RED_GAIN_DEF 0x20 267 .default_value = RED_GAIN_DEF, 268 }, 269 .set = sd_setred_gain, 270 .get = sd_getred_gain, 271 }, 272 { 273 { 274 .id = V4L2_CID_GAIN, 275 .type = V4L2_CTRL_TYPE_INTEGER, 276 .name = "Gain", 277 .minimum = 0x10, 278 .maximum = 0x40, 279 .step = 1, 280#define GAIN_DEF 0x20 281 .default_value = GAIN_DEF, 282 }, 283 .set = sd_setgain, 284 .get = sd_getgain, 285 }, 286}; 287 288static const struct v4l2_pix_format vga_mode_t16[] = { 289 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 290 .bytesperline = 160, 291 .sizeimage = 160 * 120 * 4 / 8 + 590, 292 .colorspace = V4L2_COLORSPACE_JPEG, 293 .priv = 4}, 294 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 295 .bytesperline = 176, 296 .sizeimage = 176 * 144 * 3 / 8 + 590, 297 .colorspace = V4L2_COLORSPACE_JPEG, 298 .priv = 3}, 299 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 300 .bytesperline = 320, 301 .sizeimage = 320 * 240 * 3 / 8 + 590, 302 .colorspace = V4L2_COLORSPACE_JPEG, 303 .priv = 2}, 304 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 305 .bytesperline = 352, 306 .sizeimage = 352 * 288 * 3 / 8 + 590, 307 .colorspace = V4L2_COLORSPACE_JPEG, 308 .priv = 1}, 309 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 310 .bytesperline = 640, 311 .sizeimage = 640 * 480 * 3 / 8 + 590, 312 .colorspace = V4L2_COLORSPACE_JPEG, 313 .priv = 0}, 314}; 315 316/* sensor specific data */ 317struct additional_sensor_data { 318 const u8 n3[6]; 319 const u8 *n4, n4sz; 320 const u8 reg80, reg8e; 321 const u8 nset8[6]; 322 const u8 data1[10]; 323 const u8 data2[9]; 324 const u8 data3[9]; 325 const u8 data5[6]; 326 const u8 stream[4]; 327}; 328 329static const u8 n4_om6802[] = { 330 0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, 331 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, 332 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, 333 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8, 334 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48, 335 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0, 336 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 337 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 338 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46 339}; 340static const u8 n4_other[] = { 341 0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69, 342 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68, 343 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8, 344 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8, 345 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56, 346 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5, 347 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0, 348 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00 349}; 350static const u8 n4_tas5130a[] = { 351 0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20, 352 0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4, 353 0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10, 354 0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08, 355 0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a, 356 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8, 357 0xc6, 0xda 358}; 359static const u8 n4_lt168g[] = { 360 0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28, 361 0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70, 362 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3, 363 0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20, 364 0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68, 365 0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40, 366 0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0, 367 0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c, 368 0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80 369}; 370 371static const struct additional_sensor_data sensor_data[] = { 372[SENSOR_OM6802] = { 373 .n3 = 374 {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}, 375 .n4 = n4_om6802, 376 .n4sz = sizeof n4_om6802, 377 .reg80 = 0x3c, 378 .reg8e = 0x33, 379 .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00}, 380 .data1 = 381 {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, 382 0xb3, 0xfc}, 383 .data2 = 384 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, 385 0xff}, 386 .data3 = 387 {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff, 388 0xff}, 389 .data5 = /* this could be removed later */ 390 {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23}, 391 .stream = 392 {0x0b, 0x04, 0x0a, 0x78}, 393 }, 394[SENSOR_OTHER] = { 395 .n3 = 396 {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00}, 397 .n4 = n4_other, 398 .n4sz = sizeof n4_other, 399 .reg80 = 0xac, 400 .reg8e = 0xb8, 401 .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00}, 402 .data1 = 403 {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a, 404 0xe8, 0xfc}, 405 .data2 = 406 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, 407 0xd9}, 408 .data3 = 409 {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96, 410 0xd9}, 411 .data5 = 412 {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69}, 413 .stream = 414 {0x0b, 0x04, 0x0a, 0x00}, 415 }, 416[SENSOR_TAS5130A] = { 417 .n3 = 418 {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08}, 419 .n4 = n4_tas5130a, 420 .n4sz = sizeof n4_tas5130a, 421 .reg80 = 0x3c, 422 .reg8e = 0xb4, 423 .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00}, 424 .data1 = 425 {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27, 426 0xc8, 0xfc}, 427 .data2 = 428 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, 429 0xe0}, 430 .data3 = 431 {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8, 432 0xe0}, 433 .data5 = 434 {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20}, 435 .stream = 436 {0x0b, 0x04, 0x0a, 0x40}, 437 }, 438[SENSOR_LT168G] = { 439 .n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00}, 440 .n4 = n4_lt168g, 441 .n4sz = sizeof n4_lt168g, 442 .reg80 = 0x7c, 443 .reg8e = 0xb3, 444 .nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00}, 445 .data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40, 446 0xb0, 0xf4}, 447 .data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6, 448 0xff}, 449 .data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6, 450 0xff}, 451 .data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b}, 452 .stream = {0x0b, 0x04, 0x0a, 0x28}, 453 }, 454}; 455 456#define MAX_EFFECTS 7 457/* easily done by soft, this table could be removed, 458 * i keep it here just in case */ 459static char *effects_control[MAX_EFFECTS] = { 460 "Normal", 461 "Emboss", /* disabled */ 462 "Monochrome", 463 "Sepia", 464 "Sketch", 465 "Sun Effect", /* disabled */ 466 "Negative", 467}; 468static const u8 effects_table[MAX_EFFECTS][6] = { 469 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ 470 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ 471 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */ 472 {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */ 473 {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */ 474 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */ 475 {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ 476}; 477 478static const u8 gamma_table[GAMMA_MAX][17] = { 479/* gamma table from cam1690.ini */ 480 {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21, /* 0 */ 481 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb, 482 0xff}, 483 {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d, /* 1 */ 484 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1, 485 0xff}, 486 {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35, /* 2 */ 487 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3, 488 0xff}, 489 {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */ 490 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6, 491 0xff}, 492 {0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */ 493 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9, 494 0xff}, 495 {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */ 496 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec, 497 0xff}, 498 {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67, /* 6 */ 499 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 500 0xff}, 501 {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, /* 7 */ 502 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 503 0xff}, 504 {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79, /* 8 */ 505 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0, 506 0xff}, 507 {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84, /* 9 */ 508 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2, 509 0xff}, 510 {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e, /* 10 */ 511 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3, 512 0xff}, 513 {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b, /* 11 */ 514 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5, 515 0xff}, 516 {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */ 517 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6, 518 0xff}, 519 {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */ 520 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9, 521 0xff}, 522 {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */ 523 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa, 524 0xff}, 525 {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */ 526 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc, 527 0xff} 528}; 529 530static const u8 tas5130a_sensor_init[][8] = { 531 {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, 532 {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, 533 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, 534}; 535 536static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07}; 537 538/* read 1 byte */ 539static u8 reg_r(struct gspca_dev *gspca_dev, 540 u16 index) 541{ 542 usb_control_msg(gspca_dev->dev, 543 usb_rcvctrlpipe(gspca_dev->dev, 0), 544 0, /* request */ 545 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 546 0, /* value */ 547 index, 548 gspca_dev->usb_buf, 1, 500); 549 return gspca_dev->usb_buf[0]; 550} 551 552static void reg_w(struct gspca_dev *gspca_dev, 553 u16 index) 554{ 555 usb_control_msg(gspca_dev->dev, 556 usb_sndctrlpipe(gspca_dev->dev, 0), 557 0, 558 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 559 0, index, 560 NULL, 0, 500); 561} 562 563static void reg_w_buf(struct gspca_dev *gspca_dev, 564 const u8 *buffer, u16 len) 565{ 566 if (len <= USB_BUF_SZ) { 567 memcpy(gspca_dev->usb_buf, buffer, len); 568 usb_control_msg(gspca_dev->dev, 569 usb_sndctrlpipe(gspca_dev->dev, 0), 570 0, 571 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 572 0x01, 0, 573 gspca_dev->usb_buf, len, 500); 574 } else { 575 u8 *tmpbuf; 576 577 tmpbuf = kmemdup(buffer, len, GFP_KERNEL); 578 if (!tmpbuf) { 579 pr_err("Out of memory\n"); 580 return; 581 } 582 usb_control_msg(gspca_dev->dev, 583 usb_sndctrlpipe(gspca_dev->dev, 0), 584 0, 585 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 586 0x01, 0, 587 tmpbuf, len, 500); 588 kfree(tmpbuf); 589 } 590} 591 592/* write values to consecutive registers */ 593static void reg_w_ixbuf(struct gspca_dev *gspca_dev, 594 u8 reg, 595 const u8 *buffer, u16 len) 596{ 597 int i; 598 u8 *p, *tmpbuf; 599 600 if (len * 2 <= USB_BUF_SZ) { 601 p = tmpbuf = gspca_dev->usb_buf; 602 } else { 603 p = tmpbuf = kmalloc(len * 2, GFP_KERNEL); 604 if (!tmpbuf) { 605 pr_err("Out of memory\n"); 606 return; 607 } 608 } 609 i = len; 610 while (--i >= 0) { 611 *p++ = reg++; 612 *p++ = *buffer++; 613 } 614 usb_control_msg(gspca_dev->dev, 615 usb_sndctrlpipe(gspca_dev->dev, 0), 616 0, 617 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 618 0x01, 0, 619 tmpbuf, len * 2, 500); 620 if (len * 2 > USB_BUF_SZ) 621 kfree(tmpbuf); 622} 623 624static void om6802_sensor_init(struct gspca_dev *gspca_dev) 625{ 626 int i; 627 const u8 *p; 628 u8 byte; 629 u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05}; 630 static const u8 sensor_init[] = { 631 0xdf, 0x6d, 632 0xdd, 0x18, 633 0x5a, 0xe0, 634 0x5c, 0x07, 635 0x5d, 0xb0, 636 0x5e, 0x1e, 637 0x60, 0x71, 638 0xef, 0x00, 639 0xe9, 0x00, 640 0xea, 0x00, 641 0x90, 0x24, 642 0x91, 0xb2, 643 0x82, 0x32, 644 0xfd, 0x41, 645 0x00 /* table end */ 646 }; 647 648 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); 649 msleep(100); 650 i = 4; 651 while (--i > 0) { 652 byte = reg_r(gspca_dev, 0x0060); 653 if (!(byte & 0x01)) 654 break; 655 msleep(100); 656 } 657 byte = reg_r(gspca_dev, 0x0063); 658 if (byte != 0x17) { 659 pr_err("Bad sensor reset %02x\n", byte); 660 /* continue? */ 661 } 662 663 p = sensor_init; 664 while (*p != 0) { 665 val[1] = *p++; 666 val[3] = *p++; 667 if (*p == 0) 668 reg_w(gspca_dev, 0x3c80); 669 reg_w_buf(gspca_dev, val, sizeof val); 670 i = 4; 671 while (--i >= 0) { 672 msleep(15); 673 byte = reg_r(gspca_dev, 0x60); 674 if (!(byte & 0x01)) 675 break; 676 } 677 } 678 msleep(15); 679 reg_w(gspca_dev, 0x3c80); 680} 681 682/* this function is called at probe time */ 683static int sd_config(struct gspca_dev *gspca_dev, 684 const struct usb_device_id *id) 685{ 686 struct sd *sd = (struct sd *) gspca_dev; 687 struct cam *cam; 688 689 cam = &gspca_dev->cam; 690 691 cam->cam_mode = vga_mode_t16; 692 cam->nmodes = ARRAY_SIZE(vga_mode_t16); 693 694 sd->brightness = BRIGHTNESS_DEF; 695 sd->contrast = CONTRAST_DEF; 696 sd->colors = COLORS_DEF; 697 sd->gamma = GAMMA_DEF; 698 sd->autogain = AUTOGAIN_DEF; 699 sd->mirror = MIRROR_DEF; 700 sd->freq = FREQ_DEF; 701 sd->awb = AWB_DEF; 702 sd->sharpness = SHARPNESS_DEF; 703 sd->effect = EFFECTS_DEF; 704 sd->red_gain = RED_GAIN_DEF; 705 sd->blue_gain = BLUE_GAIN_DEF; 706 sd->green_gain = GAIN_DEF * 3 - RED_GAIN_DEF - BLUE_GAIN_DEF; 707 708 return 0; 709} 710 711static void setbrightness(struct gspca_dev *gspca_dev) 712{ 713 struct sd *sd = (struct sd *) gspca_dev; 714 unsigned int brightness; 715 u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 }; 716 717 brightness = sd->brightness; 718 if (brightness < 7) { 719 set6[1] = 0x26; 720 set6[3] = 0x70 - brightness * 0x10; 721 } else { 722 set6[3] = 0x00 + ((brightness - 7) * 0x10); 723 } 724 725 reg_w_buf(gspca_dev, set6, sizeof set6); 726} 727 728static void setcontrast(struct gspca_dev *gspca_dev) 729{ 730 struct sd *sd = (struct sd *) gspca_dev; 731 unsigned int contrast = sd->contrast; 732 u16 reg_to_write; 733 734 if (contrast < 7) 735 reg_to_write = 0x8ea9 - contrast * 0x200; 736 else 737 reg_to_write = 0x00a9 + (contrast - 7) * 0x200; 738 739 reg_w(gspca_dev, reg_to_write); 740} 741 742static void setcolors(struct gspca_dev *gspca_dev) 743{ 744 struct sd *sd = (struct sd *) gspca_dev; 745 u16 reg_to_write; 746 747 reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */ 748 reg_w(gspca_dev, reg_to_write); 749} 750 751static void setgamma(struct gspca_dev *gspca_dev) 752{ 753 struct sd *sd = (struct sd *) gspca_dev; 754 755 PDEBUG(D_CONF, "Gamma: %d", sd->gamma); 756 reg_w_ixbuf(gspca_dev, 0x90, 757 gamma_table[sd->gamma], sizeof gamma_table[0]); 758} 759 760static void setRGB(struct gspca_dev *gspca_dev) 761{ 762 struct sd *sd = (struct sd *) gspca_dev; 763 u8 all_gain_reg[6] = 764 {0x87, 0x00, 0x88, 0x00, 0x89, 0x00}; 765 766 all_gain_reg[1] = sd->red_gain; 767 all_gain_reg[3] = sd->blue_gain; 768 all_gain_reg[5] = sd->green_gain; 769 reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg); 770} 771 772/* Generic fnc for r/b balance, exposure and awb */ 773static void setawb(struct gspca_dev *gspca_dev) 774{ 775 struct sd *sd = (struct sd *) gspca_dev; 776 u16 reg80; 777 778 reg80 = (sensor_data[sd->sensor].reg80 << 8) | 0x80; 779 780 /* on awb leave defaults values */ 781 if (!sd->awb) { 782 /* shoud we wait here.. */ 783 /* update and reset RGB gains with webcam values */ 784 sd->red_gain = reg_r(gspca_dev, 0x0087); 785 sd->blue_gain = reg_r(gspca_dev, 0x0088); 786 sd->green_gain = reg_r(gspca_dev, 0x0089); 787 reg80 &= ~0x0400; /* AWB off */ 788 } 789 reg_w(gspca_dev, reg80); 790 reg_w(gspca_dev, reg80); 791} 792 793static void init_gains(struct gspca_dev *gspca_dev) 794{ 795 struct sd *sd = (struct sd *) gspca_dev; 796 u16 reg80; 797 u8 all_gain_reg[8] = 798 {0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00}; 799 800 all_gain_reg[1] = sd->red_gain; 801 all_gain_reg[3] = sd->blue_gain; 802 all_gain_reg[5] = sd->green_gain; 803 reg80 = sensor_data[sd->sensor].reg80; 804 if (!sd->awb) 805 reg80 &= ~0x04; 806 all_gain_reg[7] = reg80; 807 reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg); 808 809 reg_w(gspca_dev, (sd->red_gain << 8) + 0x87); 810 reg_w(gspca_dev, (sd->blue_gain << 8) + 0x88); 811 reg_w(gspca_dev, (sd->green_gain << 8) + 0x89); 812} 813 814static void setsharpness(struct gspca_dev *gspca_dev) 815{ 816 struct sd *sd = (struct sd *) gspca_dev; 817 u16 reg_to_write; 818 819 reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; 820 821 reg_w(gspca_dev, reg_to_write); 822} 823 824static void setfreq(struct gspca_dev *gspca_dev) 825{ 826 struct sd *sd = (struct sd *) gspca_dev; 827 u8 reg66; 828 u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 }; 829 830 switch (sd->sensor) { 831 case SENSOR_LT168G: 832 if (sd->freq != 0) 833 freq[3] = 0xa8; 834 reg66 = 0x41; 835 break; 836 case SENSOR_OM6802: 837 reg66 = 0xca; 838 break; 839 default: 840 reg66 = 0x40; 841 break; 842 } 843 switch (sd->freq) { 844 case 0: /* no flicker */ 845 freq[3] = 0xf0; 846 break; 847 case 2: /* 60Hz */ 848 reg66 &= ~0x40; 849 break; 850 } 851 freq[1] = reg66; 852 853 reg_w_buf(gspca_dev, freq, sizeof freq); 854} 855 856/* this function is called at probe and resume time */ 857static int sd_init(struct gspca_dev *gspca_dev) 858{ 859 /* some of this registers are not really neded, because 860 * they are overriden by setbrigthness, setcontrast, etc, 861 * but wont hurt anyway, and can help someone with similar webcam 862 * to see the initial parameters.*/ 863 struct sd *sd = (struct sd *) gspca_dev; 864 const struct additional_sensor_data *sensor; 865 int i; 866 u16 sensor_id; 867 u8 test_byte = 0; 868 869 static const u8 read_indexs[] = 870 { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, 871 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 }; 872 static const u8 n1[] = 873 {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; 874 static const u8 n2[] = 875 {0x08, 0x00}; 876 877 sensor_id = (reg_r(gspca_dev, 0x06) << 8) 878 | reg_r(gspca_dev, 0x07); 879 switch (sensor_id & 0xff0f) { 880 case 0x0801: 881 PDEBUG(D_PROBE, "sensor tas5130a"); 882 sd->sensor = SENSOR_TAS5130A; 883 break; 884 case 0x0802: 885 PDEBUG(D_PROBE, "sensor lt168g"); 886 sd->sensor = SENSOR_LT168G; 887 break; 888 case 0x0803: 889 PDEBUG(D_PROBE, "sensor 'other'"); 890 sd->sensor = SENSOR_OTHER; 891 break; 892 case 0x0807: 893 PDEBUG(D_PROBE, "sensor om6802"); 894 sd->sensor = SENSOR_OM6802; 895 break; 896 default: 897 pr_err("unknown sensor %04x\n", sensor_id); 898 return -EINVAL; 899 } 900 901 if (sd->sensor == SENSOR_OM6802) { 902 reg_w_buf(gspca_dev, n1, sizeof n1); 903 i = 5; 904 while (--i >= 0) { 905 reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset); 906 test_byte = reg_r(gspca_dev, 0x0063); 907 msleep(100); 908 if (test_byte == 0x17) 909 break; /* OK */ 910 } 911 if (i < 0) { 912 pr_err("Bad sensor reset %02x\n", test_byte); 913 return -EIO; 914 } 915 reg_w_buf(gspca_dev, n2, sizeof n2); 916 } 917 918 i = 0; 919 while (read_indexs[i] != 0x00) { 920 test_byte = reg_r(gspca_dev, read_indexs[i]); 921 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i], 922 test_byte); 923 i++; 924 } 925 926 sensor = &sensor_data[sd->sensor]; 927 reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3); 928 reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz); 929 930 if (sd->sensor == SENSOR_LT168G) { 931 test_byte = reg_r(gspca_dev, 0x80); 932 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80, 933 test_byte); 934 reg_w(gspca_dev, 0x6c80); 935 } 936 937 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1); 938 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2); 939 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3); 940 941 reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80); 942 reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80); 943 reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e); 944 945 setbrightness(gspca_dev); 946 setcontrast(gspca_dev); 947 setgamma(gspca_dev); 948 setcolors(gspca_dev); 949 setsharpness(gspca_dev); 950 init_gains(gspca_dev); 951 setfreq(gspca_dev); 952 953 reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5); 954 reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8); 955 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); 956 957 if (sd->sensor == SENSOR_LT168G) { 958 test_byte = reg_r(gspca_dev, 0x80); 959 PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80, 960 test_byte); 961 reg_w(gspca_dev, 0x6c80); 962 } 963 964 reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1); 965 reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2); 966 reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3); 967 968 return 0; 969} 970 971static void setmirror(struct gspca_dev *gspca_dev) 972{ 973 struct sd *sd = (struct sd *) gspca_dev; 974 u8 hflipcmd[8] = 975 {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}; 976 977 if (sd->mirror) 978 hflipcmd[3] = 0x01; 979 980 reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd); 981} 982 983static void seteffect(struct gspca_dev *gspca_dev) 984{ 985 struct sd *sd = (struct sd *) gspca_dev; 986 987 reg_w_buf(gspca_dev, effects_table[sd->effect], 988 sizeof effects_table[0]); 989 if (sd->effect == 1 || sd->effect == 5) { 990 PDEBUG(D_CONF, 991 "This effect have been disabled for webcam \"safety\""); 992 return; 993 } 994 995 if (sd->effect == 1 || sd->effect == 4) 996 reg_w(gspca_dev, 0x4aa6); 997 else 998 reg_w(gspca_dev, 0xfaa6); 999} 1000 1001/* Is this really needed? 1002 * i added some module parameters for test with some users */ 1003static void poll_sensor(struct gspca_dev *gspca_dev) 1004{ 1005 static const u8 poll1[] = 1006 {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82, 1007 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34, 1008 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01, 1009 0x60, 0x14}; 1010 static const u8 poll2[] = 1011 {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9, 1012 0x73, 0x02, 0x73, 0x02, 0x60, 0x14}; 1013 static const u8 noise03[] = /* (some differences / ms-drv) */ 1014 {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f, 1015 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c, 1016 0xc2, 0x80, 0xc3, 0x10}; 1017 1018 PDEBUG(D_STREAM, "[Sensor requires polling]"); 1019 reg_w_buf(gspca_dev, poll1, sizeof poll1); 1020 reg_w_buf(gspca_dev, poll2, sizeof poll2); 1021 reg_w_buf(gspca_dev, noise03, sizeof noise03); 1022} 1023 1024static int sd_start(struct gspca_dev *gspca_dev) 1025{ 1026 struct sd *sd = (struct sd *) gspca_dev; 1027 const struct additional_sensor_data *sensor; 1028 int i, mode; 1029 u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; 1030 static const u8 t3[] = 1031 { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 }; 1032 1033 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; 1034 switch (mode) { 1035 case 0: /* 640x480 (0x00) */ 1036 break; 1037 case 1: /* 352x288 */ 1038 t2[1] = 0x40; 1039 break; 1040 case 2: /* 320x240 */ 1041 t2[1] = 0x10; 1042 break; 1043 case 3: /* 176x144 */ 1044 t2[1] = 0x50; 1045 break; 1046 default: 1047/* case 4: * 160x120 */ 1048 t2[1] = 0x20; 1049 break; 1050 } 1051 1052 switch (sd->sensor) { 1053 case SENSOR_OM6802: 1054 om6802_sensor_init(gspca_dev); 1055 break; 1056 case SENSOR_TAS5130A: 1057 i = 0; 1058 for (;;) { 1059 reg_w_buf(gspca_dev, tas5130a_sensor_init[i], 1060 sizeof tas5130a_sensor_init[0]); 1061 if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1) 1062 break; 1063 i++; 1064 } 1065 reg_w(gspca_dev, 0x3c80); 1066 /* just in case and to keep sync with logs (for mine) */ 1067 reg_w_buf(gspca_dev, tas5130a_sensor_init[i], 1068 sizeof tas5130a_sensor_init[0]); 1069 reg_w(gspca_dev, 0x3c80); 1070 break; 1071 } 1072 sensor = &sensor_data[sd->sensor]; 1073 setfreq(gspca_dev); 1074 reg_r(gspca_dev, 0x0012); 1075 reg_w_buf(gspca_dev, t2, sizeof t2); 1076 reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3); 1077 reg_w(gspca_dev, 0x0013); 1078 msleep(15); 1079 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); 1080 reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream); 1081 1082 if (sd->sensor == SENSOR_OM6802) 1083 poll_sensor(gspca_dev); 1084 1085 return 0; 1086} 1087 1088static void sd_stopN(struct gspca_dev *gspca_dev) 1089{ 1090 struct sd *sd = (struct sd *) gspca_dev; 1091 1092 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, 1093 sizeof sensor_data[sd->sensor].stream); 1094 reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream, 1095 sizeof sensor_data[sd->sensor].stream); 1096 if (sd->sensor == SENSOR_OM6802) { 1097 msleep(20); 1098 reg_w(gspca_dev, 0x0309); 1099 } 1100#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 1101 /* If the last button state is pressed, release it now! */ 1102 if (sd->button_pressed) { 1103 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); 1104 input_sync(gspca_dev->input_dev); 1105 sd->button_pressed = 0; 1106 } 1107#endif 1108} 1109 1110static void sd_pkt_scan(struct gspca_dev *gspca_dev, 1111 u8 *data, /* isoc packet */ 1112 int len) /* iso packet length */ 1113{ 1114 struct sd *sd = (struct sd *) gspca_dev; 1115 int pkt_type; 1116 1117 if (data[0] == 0x5a) { 1118#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 1119 if (len > 20) { 1120 u8 state = (data[20] & 0x80) ? 1 : 0; 1121 if (sd->button_pressed != state) { 1122 input_report_key(gspca_dev->input_dev, 1123 KEY_CAMERA, state); 1124 input_sync(gspca_dev->input_dev); 1125 sd->button_pressed = state; 1126 } 1127 } 1128#endif 1129 /* Control Packet, after this came the header again, 1130 * but extra bytes came in the packet before this, 1131 * sometimes an EOF arrives, sometimes not... */ 1132 return; 1133 } 1134 data += 2; 1135 len -= 2; 1136 if (data[0] == 0xff && data[1] == 0xd8) 1137 pkt_type = FIRST_PACKET; 1138 else if (data[len - 2] == 0xff && data[len - 1] == 0xd9) 1139 pkt_type = LAST_PACKET; 1140 else 1141 pkt_type = INTER_PACKET; 1142 gspca_frame_add(gspca_dev, pkt_type, data, len); 1143} 1144 1145static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val) 1146{ 1147 struct sd *sd = (struct sd *) gspca_dev; 1148 1149 sd->blue_gain = val; 1150 if (gspca_dev->streaming) 1151 reg_w(gspca_dev, (val << 8) + 0x88); 1152 return 0; 1153} 1154 1155static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val) 1156{ 1157 struct sd *sd = (struct sd *) gspca_dev; 1158 1159 *val = sd->blue_gain; 1160 return 0; 1161} 1162 1163static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val) 1164{ 1165 struct sd *sd = (struct sd *) gspca_dev; 1166 1167 sd->red_gain = val; 1168 if (gspca_dev->streaming) 1169 reg_w(gspca_dev, (val << 8) + 0x87); 1170 1171 return 0; 1172} 1173 1174static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val) 1175{ 1176 struct sd *sd = (struct sd *) gspca_dev; 1177 1178 *val = sd->red_gain; 1179 return 0; 1180} 1181 1182static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) 1183{ 1184 struct sd *sd = (struct sd *) gspca_dev; 1185 u16 psg, nsg; 1186 1187 psg = sd->red_gain + sd->blue_gain + sd->green_gain; 1188 nsg = val * 3; 1189 sd->red_gain = sd->red_gain * nsg / psg; 1190 if (sd->red_gain > 0x40) 1191 sd->red_gain = 0x40; 1192 else if (sd->red_gain < 0x10) 1193 sd->red_gain = 0x10; 1194 sd->blue_gain = sd->blue_gain * nsg / psg; 1195 if (sd->blue_gain > 0x40) 1196 sd->blue_gain = 0x40; 1197 else if (sd->blue_gain < 0x10) 1198 sd->blue_gain = 0x10; 1199 sd->green_gain = sd->green_gain * nsg / psg; 1200 if (sd->green_gain > 0x40) 1201 sd->green_gain = 0x40; 1202 else if (sd->green_gain < 0x10) 1203 sd->green_gain = 0x10; 1204 1205 if (gspca_dev->streaming) 1206 setRGB(gspca_dev); 1207 return 0; 1208} 1209 1210static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) 1211{ 1212 struct sd *sd = (struct sd *) gspca_dev; 1213 1214 *val = (sd->red_gain + sd->blue_gain + sd->green_gain) / 3; 1215 return 0; 1216} 1217 1218static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1219{ 1220 struct sd *sd = (struct sd *) gspca_dev; 1221 1222 sd->brightness = val; 1223 if (gspca_dev->streaming) 1224 setbrightness(gspca_dev); 1225 return 0; 1226} 1227 1228static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) 1229{ 1230 struct sd *sd = (struct sd *) gspca_dev; 1231 1232 *val = sd->brightness; 1233 return *val; 1234} 1235 1236static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val) 1237{ 1238 struct sd *sd = (struct sd *) gspca_dev; 1239 1240 sd->awb = val; 1241 if (gspca_dev->streaming) 1242 setawb(gspca_dev); 1243 return 0; 1244} 1245 1246static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val) 1247{ 1248 struct sd *sd = (struct sd *) gspca_dev; 1249 1250 *val = sd->awb; 1251 return *val; 1252} 1253 1254static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val) 1255{ 1256 struct sd *sd = (struct sd *) gspca_dev; 1257 1258 sd->mirror = val; 1259 if (gspca_dev->streaming) 1260 setmirror(gspca_dev); 1261 return 0; 1262} 1263 1264static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val) 1265{ 1266 struct sd *sd = (struct sd *) gspca_dev; 1267 1268 *val = sd->mirror; 1269 return *val; 1270} 1271 1272static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val) 1273{ 1274 struct sd *sd = (struct sd *) gspca_dev; 1275 1276 sd->effect = val; 1277 if (gspca_dev->streaming) 1278 seteffect(gspca_dev); 1279 return 0; 1280} 1281 1282static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val) 1283{ 1284 struct sd *sd = (struct sd *) gspca_dev; 1285 1286 *val = sd->effect; 1287 return *val; 1288} 1289 1290static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) 1291{ 1292 struct sd *sd = (struct sd *) gspca_dev; 1293 1294 sd->contrast = val; 1295 if (gspca_dev->streaming) 1296 setcontrast(gspca_dev); 1297 return 0; 1298} 1299 1300static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) 1301{ 1302 struct sd *sd = (struct sd *) gspca_dev; 1303 1304 *val = sd->contrast; 1305 return *val; 1306} 1307 1308static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) 1309{ 1310 struct sd *sd = (struct sd *) gspca_dev; 1311 1312 sd->colors = val; 1313 if (gspca_dev->streaming) 1314 setcolors(gspca_dev); 1315 return 0; 1316} 1317 1318static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) 1319{ 1320 struct sd *sd = (struct sd *) gspca_dev; 1321 1322 *val = sd->colors; 1323 return 0; 1324} 1325 1326static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) 1327{ 1328 struct sd *sd = (struct sd *) gspca_dev; 1329 1330 sd->gamma = val; 1331 if (gspca_dev->streaming) 1332 setgamma(gspca_dev); 1333 return 0; 1334} 1335 1336static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) 1337{ 1338 struct sd *sd = (struct sd *) gspca_dev; 1339 1340 *val = sd->gamma; 1341 return 0; 1342} 1343 1344static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) 1345{ 1346 struct sd *sd = (struct sd *) gspca_dev; 1347 1348 sd->freq = val; 1349 if (gspca_dev->streaming) 1350 setfreq(gspca_dev); 1351 return 0; 1352} 1353 1354static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) 1355{ 1356 struct sd *sd = (struct sd *) gspca_dev; 1357 1358 *val = sd->freq; 1359 return 0; 1360} 1361 1362static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) 1363{ 1364 struct sd *sd = (struct sd *) gspca_dev; 1365 1366 sd->sharpness = val; 1367 if (gspca_dev->streaming) 1368 setsharpness(gspca_dev); 1369 return 0; 1370} 1371 1372static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) 1373{ 1374 struct sd *sd = (struct sd *) gspca_dev; 1375 1376 *val = sd->sharpness; 1377 return 0; 1378} 1379 1380/* Low Light set here......*/ 1381static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) 1382{ 1383 struct sd *sd = (struct sd *) gspca_dev; 1384 1385 sd->autogain = val; 1386 if (val != 0) 1387 reg_w(gspca_dev, 0xf48e); 1388 else 1389 reg_w(gspca_dev, 0xb48e); 1390 return 0; 1391} 1392 1393static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val) 1394{ 1395 struct sd *sd = (struct sd *) gspca_dev; 1396 1397 *val = sd->autogain; 1398 return 0; 1399} 1400 1401static int sd_querymenu(struct gspca_dev *gspca_dev, 1402 struct v4l2_querymenu *menu) 1403{ 1404 static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"}; 1405 1406 switch (menu->id) { 1407 case V4L2_CID_POWER_LINE_FREQUENCY: 1408 if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm)) 1409 break; 1410 strcpy((char *) menu->name, freq_nm[menu->index]); 1411 return 0; 1412 case V4L2_CID_EFFECTS: 1413 if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) { 1414 strlcpy((char *) menu->name, 1415 effects_control[menu->index], 1416 sizeof menu->name); 1417 return 0; 1418 } 1419 break; 1420 } 1421 return -EINVAL; 1422} 1423 1424/* sub-driver description */ 1425static const struct sd_desc sd_desc = { 1426 .name = MODULE_NAME, 1427 .ctrls = sd_ctrls, 1428 .nctrls = ARRAY_SIZE(sd_ctrls), 1429 .config = sd_config, 1430 .init = sd_init, 1431 .start = sd_start, 1432 .stopN = sd_stopN, 1433 .pkt_scan = sd_pkt_scan, 1434 .querymenu = sd_querymenu, 1435#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 1436 .other_input = 1, 1437#endif 1438}; 1439 1440/* -- module initialisation -- */ 1441static const struct usb_device_id device_table[] = { 1442 {USB_DEVICE(0x17a1, 0x0128)}, 1443 {} 1444}; 1445MODULE_DEVICE_TABLE(usb, device_table); 1446 1447/* -- device connect -- */ 1448static int sd_probe(struct usb_interface *intf, 1449 const struct usb_device_id *id) 1450{ 1451 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 1452 THIS_MODULE); 1453} 1454 1455static struct usb_driver sd_driver = { 1456 .name = MODULE_NAME, 1457 .id_table = device_table, 1458 .probe = sd_probe, 1459 .disconnect = gspca_disconnect, 1460#ifdef CONFIG_PM 1461 .suspend = gspca_suspend, 1462 .resume = gspca_resume, 1463#endif 1464}; 1465 1466module_usb_driver(sd_driver); 1467