1 /* 2 * Driver for the ov9650 sensor 3 * 4 * Copyright (C) 2008 Erik Andrén 5 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. 6 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> 7 * 8 * Portions of code to USB interface and ALi driver software, 9 * Copyright (c) 2006 Willem Duinker 10 * v4l2 interface modeled after the V4L2 driver 11 * for SN9C10x PC Camera Controllers 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License as 15 * published by the Free Software Foundation, version 2. 16 * 17 */ 18 19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 20 21 #include "m5602_ov9650.h" 22 23 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val); 24 static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val); 25 static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 26 static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val); 27 static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val); 28 static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val); 29 static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val); 30 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val); 31 static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 32 static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val); 33 static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 34 static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 35 static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, 36 __s32 *val); 37 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, 38 __s32 val); 39 static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); 40 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); 41 static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); 42 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); 43 44 /* Vertically and horizontally flips the image if matched, needed for machines 45 where the sensor is mounted upside down */ 46 static 47 const 48 struct dmi_system_id ov9650_flip_dmi_table[] = { 49 { 50 .ident = "ASUS A6Ja", 51 .matches = { 52 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 53 DMI_MATCH(DMI_PRODUCT_NAME, "A6J") 54 } 55 }, 56 { 57 .ident = "ASUS A6JC", 58 .matches = { 59 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 60 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") 61 } 62 }, 63 { 64 .ident = "ASUS A6K", 65 .matches = { 66 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 67 DMI_MATCH(DMI_PRODUCT_NAME, "A6K") 68 } 69 }, 70 { 71 .ident = "ASUS A6Kt", 72 .matches = { 73 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 74 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") 75 } 76 }, 77 { 78 .ident = "ASUS A6VA", 79 .matches = { 80 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 81 DMI_MATCH(DMI_PRODUCT_NAME, "A6VA") 82 } 83 }, 84 { 85 86 .ident = "ASUS A6VC", 87 .matches = { 88 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 89 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") 90 } 91 }, 92 { 93 .ident = "ASUS A6VM", 94 .matches = { 95 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 96 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") 97 } 98 }, 99 { 100 .ident = "ASUS A7V", 101 .matches = { 102 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 103 DMI_MATCH(DMI_PRODUCT_NAME, "A7V") 104 } 105 }, 106 { 107 .ident = "Alienware Aurora m9700", 108 .matches = { 109 DMI_MATCH(DMI_SYS_VENDOR, "alienware"), 110 DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700") 111 } 112 }, 113 {} 114 }; 115 116 static const struct ctrl ov9650_ctrls[] = { 117 #define EXPOSURE_IDX 0 118 { 119 { 120 .id = V4L2_CID_EXPOSURE, 121 .type = V4L2_CTRL_TYPE_INTEGER, 122 .name = "exposure", 123 .minimum = 0x00, 124 .maximum = 0x1ff, 125 .step = 0x4, 126 .default_value = EXPOSURE_DEFAULT, 127 .flags = V4L2_CTRL_FLAG_SLIDER 128 }, 129 .set = ov9650_set_exposure, 130 .get = ov9650_get_exposure 131 }, 132 #define GAIN_IDX 1 133 { 134 { 135 .id = V4L2_CID_GAIN, 136 .type = V4L2_CTRL_TYPE_INTEGER, 137 .name = "gain", 138 .minimum = 0x00, 139 .maximum = 0x3ff, 140 .step = 0x1, 141 .default_value = GAIN_DEFAULT, 142 .flags = V4L2_CTRL_FLAG_SLIDER 143 }, 144 .set = ov9650_set_gain, 145 .get = ov9650_get_gain 146 }, 147 #define RED_BALANCE_IDX 2 148 { 149 { 150 .id = V4L2_CID_RED_BALANCE, 151 .type = V4L2_CTRL_TYPE_INTEGER, 152 .name = "red balance", 153 .minimum = 0x00, 154 .maximum = 0xff, 155 .step = 0x1, 156 .default_value = RED_GAIN_DEFAULT, 157 .flags = V4L2_CTRL_FLAG_SLIDER 158 }, 159 .set = ov9650_set_red_balance, 160 .get = ov9650_get_red_balance 161 }, 162 #define BLUE_BALANCE_IDX 3 163 { 164 { 165 .id = V4L2_CID_BLUE_BALANCE, 166 .type = V4L2_CTRL_TYPE_INTEGER, 167 .name = "blue balance", 168 .minimum = 0x00, 169 .maximum = 0xff, 170 .step = 0x1, 171 .default_value = BLUE_GAIN_DEFAULT, 172 .flags = V4L2_CTRL_FLAG_SLIDER 173 }, 174 .set = ov9650_set_blue_balance, 175 .get = ov9650_get_blue_balance 176 }, 177 #define HFLIP_IDX 4 178 { 179 { 180 .id = V4L2_CID_HFLIP, 181 .type = V4L2_CTRL_TYPE_BOOLEAN, 182 .name = "horizontal flip", 183 .minimum = 0, 184 .maximum = 1, 185 .step = 1, 186 .default_value = 0 187 }, 188 .set = ov9650_set_hflip, 189 .get = ov9650_get_hflip 190 }, 191 #define VFLIP_IDX 5 192 { 193 { 194 .id = V4L2_CID_VFLIP, 195 .type = V4L2_CTRL_TYPE_BOOLEAN, 196 .name = "vertical flip", 197 .minimum = 0, 198 .maximum = 1, 199 .step = 1, 200 .default_value = 0 201 }, 202 .set = ov9650_set_vflip, 203 .get = ov9650_get_vflip 204 }, 205 #define AUTO_WHITE_BALANCE_IDX 6 206 { 207 { 208 .id = V4L2_CID_AUTO_WHITE_BALANCE, 209 .type = V4L2_CTRL_TYPE_BOOLEAN, 210 .name = "auto white balance", 211 .minimum = 0, 212 .maximum = 1, 213 .step = 1, 214 .default_value = 1 215 }, 216 .set = ov9650_set_auto_white_balance, 217 .get = ov9650_get_auto_white_balance 218 }, 219 #define AUTO_GAIN_CTRL_IDX 7 220 { 221 { 222 .id = V4L2_CID_AUTOGAIN, 223 .type = V4L2_CTRL_TYPE_BOOLEAN, 224 .name = "auto gain control", 225 .minimum = 0, 226 .maximum = 1, 227 .step = 1, 228 .default_value = 1 229 }, 230 .set = ov9650_set_auto_gain, 231 .get = ov9650_get_auto_gain 232 }, 233 #define AUTO_EXPOSURE_IDX 8 234 { 235 { 236 .id = V4L2_CID_EXPOSURE_AUTO, 237 .type = V4L2_CTRL_TYPE_BOOLEAN, 238 .name = "auto exposure", 239 .minimum = 0, 240 .maximum = 1, 241 .step = 1, 242 .default_value = 1 243 }, 244 .set = ov9650_set_auto_exposure, 245 .get = ov9650_get_auto_exposure 246 } 247 248 }; 249 250 static struct v4l2_pix_format ov9650_modes[] = { 251 { 252 176, 253 144, 254 V4L2_PIX_FMT_SBGGR8, 255 V4L2_FIELD_NONE, 256 .sizeimage = 257 176 * 144, 258 .bytesperline = 176, 259 .colorspace = V4L2_COLORSPACE_SRGB, 260 .priv = 9 261 }, { 262 320, 263 240, 264 V4L2_PIX_FMT_SBGGR8, 265 V4L2_FIELD_NONE, 266 .sizeimage = 267 320 * 240, 268 .bytesperline = 320, 269 .colorspace = V4L2_COLORSPACE_SRGB, 270 .priv = 8 271 }, { 272 352, 273 288, 274 V4L2_PIX_FMT_SBGGR8, 275 V4L2_FIELD_NONE, 276 .sizeimage = 277 352 * 288, 278 .bytesperline = 352, 279 .colorspace = V4L2_COLORSPACE_SRGB, 280 .priv = 9 281 }, { 282 640, 283 480, 284 V4L2_PIX_FMT_SBGGR8, 285 V4L2_FIELD_NONE, 286 .sizeimage = 287 640 * 480, 288 .bytesperline = 640, 289 .colorspace = V4L2_COLORSPACE_SRGB, 290 .priv = 9 291 } 292 }; 293 294 static void ov9650_dump_registers(struct sd *sd); 295 296 int ov9650_probe(struct sd *sd) 297 { 298 int err = 0; 299 u8 prod_id = 0, ver_id = 0, i; 300 s32 *sensor_settings; 301 302 if (force_sensor) { 303 if (force_sensor == OV9650_SENSOR) { 304 pr_info("Forcing an %s sensor\n", ov9650.name); 305 goto sensor_found; 306 } 307 /* If we want to force another sensor, 308 don't try to probe this one */ 309 return -ENODEV; 310 } 311 312 PDEBUG(D_PROBE, "Probing for an ov9650 sensor"); 313 314 /* Run the pre-init before probing the sensor */ 315 for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) { 316 u8 data = preinit_ov9650[i][2]; 317 if (preinit_ov9650[i][0] == SENSOR) 318 err = m5602_write_sensor(sd, 319 preinit_ov9650[i][1], &data, 1); 320 else 321 err = m5602_write_bridge(sd, 322 preinit_ov9650[i][1], data); 323 } 324 325 if (err < 0) 326 return err; 327 328 if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1)) 329 return -ENODEV; 330 331 if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1)) 332 return -ENODEV; 333 334 if ((prod_id == 0x96) && (ver_id == 0x52)) { 335 pr_info("Detected an ov9650 sensor\n"); 336 goto sensor_found; 337 } 338 return -ENODEV; 339 340 sensor_found: 341 sensor_settings = kmalloc( 342 ARRAY_SIZE(ov9650_ctrls) * sizeof(s32), GFP_KERNEL); 343 if (!sensor_settings) 344 return -ENOMEM; 345 346 sd->gspca_dev.cam.cam_mode = ov9650_modes; 347 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes); 348 sd->desc->ctrls = ov9650_ctrls; 349 sd->desc->nctrls = ARRAY_SIZE(ov9650_ctrls); 350 351 for (i = 0; i < ARRAY_SIZE(ov9650_ctrls); i++) 352 sensor_settings[i] = ov9650_ctrls[i].qctrl.default_value; 353 sd->sensor_priv = sensor_settings; 354 return 0; 355 } 356 357 int ov9650_init(struct sd *sd) 358 { 359 int i, err = 0; 360 u8 data; 361 s32 *sensor_settings = sd->sensor_priv; 362 363 if (dump_sensor) 364 ov9650_dump_registers(sd); 365 366 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) { 367 data = init_ov9650[i][2]; 368 if (init_ov9650[i][0] == SENSOR) 369 err = m5602_write_sensor(sd, init_ov9650[i][1], 370 &data, 1); 371 else 372 err = m5602_write_bridge(sd, init_ov9650[i][1], data); 373 } 374 375 err = ov9650_set_exposure(&sd->gspca_dev, 376 sensor_settings[EXPOSURE_IDX]); 377 if (err < 0) 378 return err; 379 380 err = ov9650_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); 381 if (err < 0) 382 return err; 383 384 err = ov9650_set_red_balance(&sd->gspca_dev, 385 sensor_settings[RED_BALANCE_IDX]); 386 if (err < 0) 387 return err; 388 389 err = ov9650_set_blue_balance(&sd->gspca_dev, 390 sensor_settings[BLUE_BALANCE_IDX]); 391 if (err < 0) 392 return err; 393 394 err = ov9650_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]); 395 if (err < 0) 396 return err; 397 398 err = ov9650_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]); 399 if (err < 0) 400 return err; 401 402 err = ov9650_set_auto_exposure(&sd->gspca_dev, 403 sensor_settings[AUTO_EXPOSURE_IDX]); 404 if (err < 0) 405 return err; 406 407 err = ov9650_set_auto_white_balance(&sd->gspca_dev, 408 sensor_settings[AUTO_WHITE_BALANCE_IDX]); 409 if (err < 0) 410 return err; 411 412 err = ov9650_set_auto_gain(&sd->gspca_dev, 413 sensor_settings[AUTO_GAIN_CTRL_IDX]); 414 return err; 415 } 416 417 int ov9650_start(struct sd *sd) 418 { 419 u8 data; 420 int i, err = 0; 421 struct cam *cam = &sd->gspca_dev.cam; 422 s32 *sensor_settings = sd->sensor_priv; 423 424 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; 425 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; 426 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; 427 int hor_offs = OV9650_LEFT_OFFSET; 428 429 if ((!dmi_check_system(ov9650_flip_dmi_table) && 430 sensor_settings[VFLIP_IDX]) || 431 (dmi_check_system(ov9650_flip_dmi_table) && 432 !sensor_settings[VFLIP_IDX])) 433 ver_offs--; 434 435 if (width <= 320) 436 hor_offs /= 2; 437 438 /* Synthesize the vsync/hsync setup */ 439 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { 440 if (res_init_ov9650[i][0] == BRIDGE) 441 err = m5602_write_bridge(sd, res_init_ov9650[i][1], 442 res_init_ov9650[i][2]); 443 else if (res_init_ov9650[i][0] == SENSOR) { 444 data = res_init_ov9650[i][2]; 445 err = m5602_write_sensor(sd, 446 res_init_ov9650[i][1], &data, 1); 447 } 448 } 449 if (err < 0) 450 return err; 451 452 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 453 ((ver_offs >> 8) & 0xff)); 454 if (err < 0) 455 return err; 456 457 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff)); 458 if (err < 0) 459 return err; 460 461 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); 462 if (err < 0) 463 return err; 464 465 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); 466 if (err < 0) 467 return err; 468 469 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); 470 if (err < 0) 471 return err; 472 473 for (i = 0; i < 2 && !err; i++) 474 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); 475 if (err < 0) 476 return err; 477 478 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); 479 if (err < 0) 480 return err; 481 482 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); 483 if (err < 0) 484 return err; 485 486 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 487 (hor_offs >> 8) & 0xff); 488 if (err < 0) 489 return err; 490 491 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff); 492 if (err < 0) 493 return err; 494 495 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 496 ((width + hor_offs) >> 8) & 0xff); 497 if (err < 0) 498 return err; 499 500 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 501 ((width + hor_offs) & 0xff)); 502 if (err < 0) 503 return err; 504 505 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); 506 if (err < 0) 507 return err; 508 509 switch (width) { 510 case 640: 511 PDEBUG(D_V4L2, "Configuring camera for VGA mode"); 512 513 data = OV9650_VGA_SELECT | OV9650_RGB_SELECT | 514 OV9650_RAW_RGB_SELECT; 515 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 516 break; 517 518 case 352: 519 PDEBUG(D_V4L2, "Configuring camera for CIF mode"); 520 521 data = OV9650_CIF_SELECT | OV9650_RGB_SELECT | 522 OV9650_RAW_RGB_SELECT; 523 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 524 break; 525 526 case 320: 527 PDEBUG(D_V4L2, "Configuring camera for QVGA mode"); 528 529 data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT | 530 OV9650_RAW_RGB_SELECT; 531 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 532 break; 533 534 case 176: 535 PDEBUG(D_V4L2, "Configuring camera for QCIF mode"); 536 537 data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT | 538 OV9650_RAW_RGB_SELECT; 539 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 540 break; 541 } 542 return err; 543 } 544 545 int ov9650_stop(struct sd *sd) 546 { 547 u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X; 548 return m5602_write_sensor(sd, OV9650_COM2, &data, 1); 549 } 550 551 void ov9650_disconnect(struct sd *sd) 552 { 553 ov9650_stop(sd); 554 555 sd->sensor = NULL; 556 kfree(sd->sensor_priv); 557 } 558 559 static int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) 560 { 561 struct sd *sd = (struct sd *) gspca_dev; 562 s32 *sensor_settings = sd->sensor_priv; 563 564 *val = sensor_settings[EXPOSURE_IDX]; 565 PDEBUG(D_V4L2, "Read exposure %d", *val); 566 return 0; 567 } 568 569 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 570 { 571 struct sd *sd = (struct sd *) gspca_dev; 572 s32 *sensor_settings = sd->sensor_priv; 573 u8 i2c_data; 574 int err; 575 576 PDEBUG(D_V4L2, "Set exposure to %d", val); 577 578 sensor_settings[EXPOSURE_IDX] = val; 579 /* The 6 MSBs */ 580 i2c_data = (val >> 10) & 0x3f; 581 err = m5602_write_sensor(sd, OV9650_AECHM, 582 &i2c_data, 1); 583 if (err < 0) 584 return err; 585 586 /* The 8 middle bits */ 587 i2c_data = (val >> 2) & 0xff; 588 err = m5602_write_sensor(sd, OV9650_AECH, 589 &i2c_data, 1); 590 if (err < 0) 591 return err; 592 593 /* The 2 LSBs */ 594 i2c_data = val & 0x03; 595 err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1); 596 return err; 597 } 598 599 static int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 600 { 601 struct sd *sd = (struct sd *) gspca_dev; 602 s32 *sensor_settings = sd->sensor_priv; 603 604 *val = sensor_settings[GAIN_IDX]; 605 PDEBUG(D_V4L2, "Read gain %d", *val); 606 return 0; 607 } 608 609 static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 610 { 611 int err; 612 u8 i2c_data; 613 struct sd *sd = (struct sd *) gspca_dev; 614 s32 *sensor_settings = sd->sensor_priv; 615 616 PDEBUG(D_V4L2, "Setting gain to %d", val); 617 618 sensor_settings[GAIN_IDX] = val; 619 620 /* The 2 MSB */ 621 /* Read the OV9650_VREF register first to avoid 622 corrupting the VREF high and low bits */ 623 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 624 if (err < 0) 625 return err; 626 627 /* Mask away all uninteresting bits */ 628 i2c_data = ((val & 0x0300) >> 2) | 629 (i2c_data & 0x3f); 630 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 631 if (err < 0) 632 return err; 633 634 /* The 8 LSBs */ 635 i2c_data = val & 0xff; 636 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 637 return err; 638 } 639 640 static int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val) 641 { 642 struct sd *sd = (struct sd *) gspca_dev; 643 s32 *sensor_settings = sd->sensor_priv; 644 645 *val = sensor_settings[RED_BALANCE_IDX]; 646 PDEBUG(D_V4L2, "Read red gain %d", *val); 647 return 0; 648 } 649 650 static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 651 { 652 int err; 653 u8 i2c_data; 654 struct sd *sd = (struct sd *) gspca_dev; 655 s32 *sensor_settings = sd->sensor_priv; 656 657 PDEBUG(D_V4L2, "Set red gain to %d", val); 658 659 sensor_settings[RED_BALANCE_IDX] = val; 660 661 i2c_data = val & 0xff; 662 err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1); 663 return err; 664 } 665 666 static int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val) 667 { 668 struct sd *sd = (struct sd *) gspca_dev; 669 s32 *sensor_settings = sd->sensor_priv; 670 671 *val = sensor_settings[BLUE_BALANCE_IDX]; 672 PDEBUG(D_V4L2, "Read blue gain %d", *val); 673 674 return 0; 675 } 676 677 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 678 { 679 int err; 680 u8 i2c_data; 681 struct sd *sd = (struct sd *) gspca_dev; 682 s32 *sensor_settings = sd->sensor_priv; 683 684 PDEBUG(D_V4L2, "Set blue gain to %d", val); 685 686 sensor_settings[BLUE_BALANCE_IDX] = val; 687 688 i2c_data = val & 0xff; 689 err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); 690 return err; 691 } 692 693 static int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 694 { 695 struct sd *sd = (struct sd *) gspca_dev; 696 s32 *sensor_settings = sd->sensor_priv; 697 698 *val = sensor_settings[HFLIP_IDX]; 699 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 700 return 0; 701 } 702 703 static int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 704 { 705 int err; 706 u8 i2c_data; 707 struct sd *sd = (struct sd *) gspca_dev; 708 s32 *sensor_settings = sd->sensor_priv; 709 710 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 711 712 sensor_settings[HFLIP_IDX] = val; 713 714 if (!dmi_check_system(ov9650_flip_dmi_table)) 715 i2c_data = ((val & 0x01) << 5) | 716 (sensor_settings[VFLIP_IDX] << 4); 717 else 718 i2c_data = ((val & 0x01) << 5) | 719 (!sensor_settings[VFLIP_IDX] << 4); 720 721 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 722 723 return err; 724 } 725 726 static int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 727 { 728 struct sd *sd = (struct sd *) gspca_dev; 729 s32 *sensor_settings = sd->sensor_priv; 730 731 *val = sensor_settings[VFLIP_IDX]; 732 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 733 734 return 0; 735 } 736 737 static int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 738 { 739 int err; 740 u8 i2c_data; 741 struct sd *sd = (struct sd *) gspca_dev; 742 s32 *sensor_settings = sd->sensor_priv; 743 744 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 745 sensor_settings[VFLIP_IDX] = val; 746 747 if (dmi_check_system(ov9650_flip_dmi_table)) 748 val = !val; 749 750 i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); 751 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 752 if (err < 0) 753 return err; 754 755 /* When vflip is toggled we need to readjust the bridge hsync/vsync */ 756 if (gspca_dev->streaming) 757 err = ov9650_start(sd); 758 759 return err; 760 } 761 762 static int ov9650_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) 763 { 764 struct sd *sd = (struct sd *) gspca_dev; 765 s32 *sensor_settings = sd->sensor_priv; 766 767 *val = sensor_settings[AUTO_EXPOSURE_IDX]; 768 PDEBUG(D_V4L2, "Read auto exposure control %d", *val); 769 return 0; 770 } 771 772 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, 773 __s32 val) 774 { 775 int err; 776 u8 i2c_data; 777 struct sd *sd = (struct sd *) gspca_dev; 778 s32 *sensor_settings = sd->sensor_priv; 779 780 PDEBUG(D_V4L2, "Set auto exposure control to %d", val); 781 782 sensor_settings[AUTO_EXPOSURE_IDX] = val; 783 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 784 if (err < 0) 785 return err; 786 787 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); 788 789 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 790 } 791 792 static int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, 793 __s32 *val) 794 { 795 struct sd *sd = (struct sd *) gspca_dev; 796 s32 *sensor_settings = sd->sensor_priv; 797 798 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; 799 return 0; 800 } 801 802 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, 803 __s32 val) 804 { 805 int err; 806 u8 i2c_data; 807 struct sd *sd = (struct sd *) gspca_dev; 808 s32 *sensor_settings = sd->sensor_priv; 809 810 PDEBUG(D_V4L2, "Set auto white balance to %d", val); 811 812 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; 813 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 814 if (err < 0) 815 return err; 816 817 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); 818 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 819 820 return err; 821 } 822 823 static int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) 824 { 825 struct sd *sd = (struct sd *) gspca_dev; 826 s32 *sensor_settings = sd->sensor_priv; 827 828 *val = sensor_settings[AUTO_GAIN_CTRL_IDX]; 829 PDEBUG(D_V4L2, "Read auto gain control %d", *val); 830 return 0; 831 } 832 833 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 834 { 835 int err; 836 u8 i2c_data; 837 struct sd *sd = (struct sd *) gspca_dev; 838 s32 *sensor_settings = sd->sensor_priv; 839 840 PDEBUG(D_V4L2, "Set auto gain control to %d", val); 841 842 sensor_settings[AUTO_GAIN_CTRL_IDX] = val; 843 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 844 if (err < 0) 845 return err; 846 847 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 848 849 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 850 } 851 852 static void ov9650_dump_registers(struct sd *sd) 853 { 854 int address; 855 pr_info("Dumping the ov9650 register state\n"); 856 for (address = 0; address < 0xa9; address++) { 857 u8 value; 858 m5602_read_sensor(sd, address, &value, 1); 859 pr_info("register 0x%x contains 0x%x\n", address, value); 860 } 861 862 pr_info("ov9650 register state dump complete\n"); 863 864 pr_info("Probing for which registers that are read/write\n"); 865 for (address = 0; address < 0xff; address++) { 866 u8 old_value, ctrl_value; 867 u8 test_value[2] = {0xff, 0xff}; 868 869 m5602_read_sensor(sd, address, &old_value, 1); 870 m5602_write_sensor(sd, address, test_value, 1); 871 m5602_read_sensor(sd, address, &ctrl_value, 1); 872 873 if (ctrl_value == test_value[0]) 874 pr_info("register 0x%x is writeable\n", address); 875 else 876 pr_info("register 0x%x is read only\n", address); 877 878 /* Restore original value */ 879 m5602_write_sensor(sd, address, &old_value, 1); 880 } 881 } 882