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_s_ctrl(struct v4l2_ctrl *ctrl); 24 static void ov9650_dump_registers(struct sd *sd); 25 26 /* Vertically and horizontally flips the image if matched, needed for machines 27 where the sensor is mounted upside down */ 28 static 29 const 30 struct dmi_system_id ov9650_flip_dmi_table[] = { 31 { 32 .ident = "ASUS A6Ja", 33 .matches = { 34 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 35 DMI_MATCH(DMI_PRODUCT_NAME, "A6J") 36 } 37 }, 38 { 39 .ident = "ASUS A6JC", 40 .matches = { 41 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 42 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") 43 } 44 }, 45 { 46 .ident = "ASUS A6K", 47 .matches = { 48 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 49 DMI_MATCH(DMI_PRODUCT_NAME, "A6K") 50 } 51 }, 52 { 53 .ident = "ASUS A6Kt", 54 .matches = { 55 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 56 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") 57 } 58 }, 59 { 60 .ident = "ASUS A6VA", 61 .matches = { 62 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 63 DMI_MATCH(DMI_PRODUCT_NAME, "A6VA") 64 } 65 }, 66 { 67 68 .ident = "ASUS A6VC", 69 .matches = { 70 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 71 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") 72 } 73 }, 74 { 75 .ident = "ASUS A6VM", 76 .matches = { 77 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 78 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") 79 } 80 }, 81 { 82 .ident = "ASUS A7V", 83 .matches = { 84 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 85 DMI_MATCH(DMI_PRODUCT_NAME, "A7V") 86 } 87 }, 88 { 89 .ident = "Alienware Aurora m9700", 90 .matches = { 91 DMI_MATCH(DMI_SYS_VENDOR, "alienware"), 92 DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700") 93 } 94 }, 95 {} 96 }; 97 98 static struct v4l2_pix_format ov9650_modes[] = { 99 { 100 176, 101 144, 102 V4L2_PIX_FMT_SBGGR8, 103 V4L2_FIELD_NONE, 104 .sizeimage = 105 176 * 144, 106 .bytesperline = 176, 107 .colorspace = V4L2_COLORSPACE_SRGB, 108 .priv = 9 109 }, { 110 320, 111 240, 112 V4L2_PIX_FMT_SBGGR8, 113 V4L2_FIELD_NONE, 114 .sizeimage = 115 320 * 240, 116 .bytesperline = 320, 117 .colorspace = V4L2_COLORSPACE_SRGB, 118 .priv = 8 119 }, { 120 352, 121 288, 122 V4L2_PIX_FMT_SBGGR8, 123 V4L2_FIELD_NONE, 124 .sizeimage = 125 352 * 288, 126 .bytesperline = 352, 127 .colorspace = V4L2_COLORSPACE_SRGB, 128 .priv = 9 129 }, { 130 640, 131 480, 132 V4L2_PIX_FMT_SBGGR8, 133 V4L2_FIELD_NONE, 134 .sizeimage = 135 640 * 480, 136 .bytesperline = 640, 137 .colorspace = V4L2_COLORSPACE_SRGB, 138 .priv = 9 139 } 140 }; 141 142 static const struct v4l2_ctrl_ops ov9650_ctrl_ops = { 143 .s_ctrl = ov9650_s_ctrl, 144 }; 145 146 int ov9650_probe(struct sd *sd) 147 { 148 int err = 0; 149 u8 prod_id = 0, ver_id = 0, i; 150 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; 151 152 if (force_sensor) { 153 if (force_sensor == OV9650_SENSOR) { 154 pr_info("Forcing an %s sensor\n", ov9650.name); 155 goto sensor_found; 156 } 157 /* If we want to force another sensor, 158 don't try to probe this one */ 159 return -ENODEV; 160 } 161 162 PDEBUG(D_PROBE, "Probing for an ov9650 sensor"); 163 164 /* Run the pre-init before probing the sensor */ 165 for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) { 166 u8 data = preinit_ov9650[i][2]; 167 if (preinit_ov9650[i][0] == SENSOR) 168 err = m5602_write_sensor(sd, 169 preinit_ov9650[i][1], &data, 1); 170 else 171 err = m5602_write_bridge(sd, 172 preinit_ov9650[i][1], data); 173 } 174 175 if (err < 0) 176 return err; 177 178 if (m5602_read_sensor(sd, OV9650_PID, &prod_id, 1)) 179 return -ENODEV; 180 181 if (m5602_read_sensor(sd, OV9650_VER, &ver_id, 1)) 182 return -ENODEV; 183 184 if ((prod_id == 0x96) && (ver_id == 0x52)) { 185 pr_info("Detected an ov9650 sensor\n"); 186 goto sensor_found; 187 } 188 return -ENODEV; 189 190 sensor_found: 191 sd->gspca_dev.cam.cam_mode = ov9650_modes; 192 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes); 193 194 return 0; 195 } 196 197 int ov9650_init(struct sd *sd) 198 { 199 int i, err = 0; 200 u8 data; 201 202 if (dump_sensor) 203 ov9650_dump_registers(sd); 204 205 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) { 206 data = init_ov9650[i][2]; 207 if (init_ov9650[i][0] == SENSOR) 208 err = m5602_write_sensor(sd, init_ov9650[i][1], 209 &data, 1); 210 else 211 err = m5602_write_bridge(sd, init_ov9650[i][1], data); 212 } 213 214 return 0; 215 } 216 217 int ov9650_init_controls(struct sd *sd) 218 { 219 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; 220 221 sd->gspca_dev.vdev.ctrl_handler = hdl; 222 v4l2_ctrl_handler_init(hdl, 9); 223 224 sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, 225 V4L2_CID_AUTO_WHITE_BALANCE, 226 0, 1, 1, 1); 227 sd->red_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, 228 V4L2_CID_RED_BALANCE, 0, 255, 1, 229 RED_GAIN_DEFAULT); 230 sd->blue_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, 231 V4L2_CID_BLUE_BALANCE, 0, 255, 1, 232 BLUE_GAIN_DEFAULT); 233 234 sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &ov9650_ctrl_ops, 235 V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO); 236 sd->expo = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_EXPOSURE, 237 0, 0x1ff, 4, EXPOSURE_DEFAULT); 238 239 sd->autogain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, 240 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 241 sd->gain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_GAIN, 0, 242 0x3ff, 1, GAIN_DEFAULT); 243 244 sd->hflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_HFLIP, 245 0, 1, 1, 0); 246 sd->vflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_VFLIP, 247 0, 1, 1, 0); 248 249 if (hdl->error) { 250 pr_err("Could not initialize controls\n"); 251 return hdl->error; 252 } 253 254 v4l2_ctrl_auto_cluster(3, &sd->auto_white_bal, 0, false); 255 v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false); 256 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); 257 v4l2_ctrl_cluster(2, &sd->hflip); 258 259 return 0; 260 } 261 262 int ov9650_start(struct sd *sd) 263 { 264 u8 data; 265 int i, err = 0; 266 struct cam *cam = &sd->gspca_dev.cam; 267 268 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; 269 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; 270 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; 271 int hor_offs = OV9650_LEFT_OFFSET; 272 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; 273 274 if ((!dmi_check_system(ov9650_flip_dmi_table) && 275 sd->vflip->val) || 276 (dmi_check_system(ov9650_flip_dmi_table) && 277 !sd->vflip->val)) 278 ver_offs--; 279 280 if (width <= 320) 281 hor_offs /= 2; 282 283 /* Synthesize the vsync/hsync setup */ 284 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { 285 if (res_init_ov9650[i][0] == BRIDGE) 286 err = m5602_write_bridge(sd, res_init_ov9650[i][1], 287 res_init_ov9650[i][2]); 288 else if (res_init_ov9650[i][0] == SENSOR) { 289 data = res_init_ov9650[i][2]; 290 err = m5602_write_sensor(sd, 291 res_init_ov9650[i][1], &data, 1); 292 } 293 } 294 if (err < 0) 295 return err; 296 297 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 298 ((ver_offs >> 8) & 0xff)); 299 if (err < 0) 300 return err; 301 302 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff)); 303 if (err < 0) 304 return err; 305 306 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); 307 if (err < 0) 308 return err; 309 310 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); 311 if (err < 0) 312 return err; 313 314 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); 315 if (err < 0) 316 return err; 317 318 for (i = 0; i < 2 && !err; i++) 319 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); 320 if (err < 0) 321 return err; 322 323 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); 324 if (err < 0) 325 return err; 326 327 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); 328 if (err < 0) 329 return err; 330 331 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 332 (hor_offs >> 8) & 0xff); 333 if (err < 0) 334 return err; 335 336 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff); 337 if (err < 0) 338 return err; 339 340 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 341 ((width + hor_offs) >> 8) & 0xff); 342 if (err < 0) 343 return err; 344 345 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 346 ((width + hor_offs) & 0xff)); 347 if (err < 0) 348 return err; 349 350 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); 351 if (err < 0) 352 return err; 353 354 switch (width) { 355 case 640: 356 PDEBUG(D_CONF, "Configuring camera for VGA mode"); 357 358 data = OV9650_VGA_SELECT | OV9650_RGB_SELECT | 359 OV9650_RAW_RGB_SELECT; 360 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 361 break; 362 363 case 352: 364 PDEBUG(D_CONF, "Configuring camera for CIF mode"); 365 366 data = OV9650_CIF_SELECT | OV9650_RGB_SELECT | 367 OV9650_RAW_RGB_SELECT; 368 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 369 break; 370 371 case 320: 372 PDEBUG(D_CONF, "Configuring camera for QVGA mode"); 373 374 data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT | 375 OV9650_RAW_RGB_SELECT; 376 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 377 break; 378 379 case 176: 380 PDEBUG(D_CONF, "Configuring camera for QCIF mode"); 381 382 data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT | 383 OV9650_RAW_RGB_SELECT; 384 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 385 break; 386 } 387 return err; 388 } 389 390 int ov9650_stop(struct sd *sd) 391 { 392 u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X; 393 return m5602_write_sensor(sd, OV9650_COM2, &data, 1); 394 } 395 396 void ov9650_disconnect(struct sd *sd) 397 { 398 ov9650_stop(sd); 399 400 sd->sensor = NULL; 401 } 402 403 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 404 { 405 struct sd *sd = (struct sd *) gspca_dev; 406 u8 i2c_data; 407 int err; 408 409 PDEBUG(D_CONF, "Set exposure to %d", val); 410 411 /* The 6 MSBs */ 412 i2c_data = (val >> 10) & 0x3f; 413 err = m5602_write_sensor(sd, OV9650_AECHM, 414 &i2c_data, 1); 415 if (err < 0) 416 return err; 417 418 /* The 8 middle bits */ 419 i2c_data = (val >> 2) & 0xff; 420 err = m5602_write_sensor(sd, OV9650_AECH, 421 &i2c_data, 1); 422 if (err < 0) 423 return err; 424 425 /* The 2 LSBs */ 426 i2c_data = val & 0x03; 427 err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1); 428 return err; 429 } 430 431 static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 432 { 433 int err; 434 u8 i2c_data; 435 struct sd *sd = (struct sd *) gspca_dev; 436 437 PDEBUG(D_CONF, "Setting gain to %d", val); 438 439 /* The 2 MSB */ 440 /* Read the OV9650_VREF register first to avoid 441 corrupting the VREF high and low bits */ 442 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 443 if (err < 0) 444 return err; 445 446 /* Mask away all uninteresting bits */ 447 i2c_data = ((val & 0x0300) >> 2) | 448 (i2c_data & 0x3f); 449 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 450 if (err < 0) 451 return err; 452 453 /* The 8 LSBs */ 454 i2c_data = val & 0xff; 455 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 456 return err; 457 } 458 459 static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 460 { 461 int err; 462 u8 i2c_data; 463 struct sd *sd = (struct sd *) gspca_dev; 464 465 PDEBUG(D_CONF, "Set red gain to %d", val); 466 467 i2c_data = val & 0xff; 468 err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1); 469 return err; 470 } 471 472 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 473 { 474 int err; 475 u8 i2c_data; 476 struct sd *sd = (struct sd *) gspca_dev; 477 478 PDEBUG(D_CONF, "Set blue gain to %d", val); 479 480 i2c_data = val & 0xff; 481 err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); 482 return err; 483 } 484 485 static int ov9650_set_hvflip(struct gspca_dev *gspca_dev) 486 { 487 int err; 488 u8 i2c_data; 489 struct sd *sd = (struct sd *) gspca_dev; 490 int hflip = sd->hflip->val; 491 int vflip = sd->vflip->val; 492 493 PDEBUG(D_CONF, "Set hvflip to %d %d", hflip, vflip); 494 495 if (dmi_check_system(ov9650_flip_dmi_table)) 496 vflip = !vflip; 497 498 i2c_data = (hflip << 5) | (vflip << 4); 499 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 500 if (err < 0) 501 return err; 502 503 /* When vflip is toggled we need to readjust the bridge hsync/vsync */ 504 if (gspca_dev->streaming) 505 err = ov9650_start(sd); 506 507 return err; 508 } 509 510 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, 511 __s32 val) 512 { 513 int err; 514 u8 i2c_data; 515 struct sd *sd = (struct sd *) gspca_dev; 516 517 PDEBUG(D_CONF, "Set auto exposure control to %d", val); 518 519 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 520 if (err < 0) 521 return err; 522 523 val = (val == V4L2_EXPOSURE_AUTO); 524 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); 525 526 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 527 } 528 529 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, 530 __s32 val) 531 { 532 int err; 533 u8 i2c_data; 534 struct sd *sd = (struct sd *) gspca_dev; 535 536 PDEBUG(D_CONF, "Set auto white balance to %d", val); 537 538 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 539 if (err < 0) 540 return err; 541 542 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); 543 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 544 545 return err; 546 } 547 548 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 549 { 550 int err; 551 u8 i2c_data; 552 struct sd *sd = (struct sd *) gspca_dev; 553 554 PDEBUG(D_CONF, "Set auto gain control to %d", val); 555 556 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 557 if (err < 0) 558 return err; 559 560 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 561 562 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 563 } 564 565 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl) 566 { 567 struct gspca_dev *gspca_dev = 568 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 569 struct sd *sd = (struct sd *) gspca_dev; 570 int err; 571 572 if (!gspca_dev->streaming) 573 return 0; 574 575 switch (ctrl->id) { 576 case V4L2_CID_AUTO_WHITE_BALANCE: 577 err = ov9650_set_auto_white_balance(gspca_dev, ctrl->val); 578 if (err || ctrl->val) 579 return err; 580 err = ov9650_set_red_balance(gspca_dev, sd->red_bal->val); 581 if (err) 582 return err; 583 err = ov9650_set_blue_balance(gspca_dev, sd->blue_bal->val); 584 break; 585 case V4L2_CID_EXPOSURE_AUTO: 586 err = ov9650_set_auto_exposure(gspca_dev, ctrl->val); 587 if (err || ctrl->val == V4L2_EXPOSURE_AUTO) 588 return err; 589 err = ov9650_set_exposure(gspca_dev, sd->expo->val); 590 break; 591 case V4L2_CID_AUTOGAIN: 592 err = ov9650_set_auto_gain(gspca_dev, ctrl->val); 593 if (err || ctrl->val) 594 return err; 595 err = ov9650_set_gain(gspca_dev, sd->gain->val); 596 break; 597 case V4L2_CID_HFLIP: 598 err = ov9650_set_hvflip(gspca_dev); 599 break; 600 default: 601 return -EINVAL; 602 } 603 604 return err; 605 } 606 607 static void ov9650_dump_registers(struct sd *sd) 608 { 609 int address; 610 pr_info("Dumping the ov9650 register state\n"); 611 for (address = 0; address < 0xa9; address++) { 612 u8 value; 613 m5602_read_sensor(sd, address, &value, 1); 614 pr_info("register 0x%x contains 0x%x\n", address, value); 615 } 616 617 pr_info("ov9650 register state dump complete\n"); 618 619 pr_info("Probing for which registers that are read/write\n"); 620 for (address = 0; address < 0xff; address++) { 621 u8 old_value, ctrl_value; 622 u8 test_value[2] = {0xff, 0xff}; 623 624 m5602_read_sensor(sd, address, &old_value, 1); 625 m5602_write_sensor(sd, address, test_value, 1); 626 m5602_read_sensor(sd, address, &ctrl_value, 1); 627 628 if (ctrl_value == test_value[0]) 629 pr_info("register 0x%x is writeable\n", address); 630 else 631 pr_info("register 0x%x is read only\n", address); 632 633 /* Restore original value */ 634 m5602_write_sensor(sd, address, &old_value, 1); 635 } 636 } 637