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