1 // SPDX-License-Identifier: GPL-2.0-only 2 3 /* 4 * Driver for the ov9650 sensor 5 * 6 * Copyright (C) 2008 Erik Andrén 7 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project. 8 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br> 9 * 10 * Portions of code to USB interface and ALi driver software, 11 * Copyright (c) 2006 Willem Duinker 12 * v4l2 interface modeled after the V4L2 driver 13 * for SN9C10x PC Camera Controllers 14 */ 15 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 18 #include "m5602_ov9650.h" 19 20 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl); 21 static void ov9650_dump_registers(struct sd *sd); 22 23 static const unsigned char preinit_ov9650[][3] = { 24 /* [INITCAM] */ 25 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, 26 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, 27 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 28 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 29 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 30 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 31 32 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08}, 33 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 34 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 35 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 36 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 37 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, 38 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 39 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, 40 /* Reset chip */ 41 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 42 /* Enable double clock */ 43 {SENSOR, OV9650_CLKRC, 0x80}, 44 /* Do something out of spec with the power */ 45 {SENSOR, OV9650_OFON, 0x40} 46 }; 47 48 static const unsigned char init_ov9650[][3] = { 49 /* [INITCAM] */ 50 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, 51 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, 52 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 53 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 54 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 55 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 56 57 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x08}, 58 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 59 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 60 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 61 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 62 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, 63 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 64 {BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a}, 65 66 /* Reset chip */ 67 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 68 /* One extra reset is needed in order to make the sensor behave 69 properly when resuming from ram, could be a timing issue */ 70 {SENSOR, OV9650_COM7, OV9650_REGISTER_RESET}, 71 72 /* Enable double clock */ 73 {SENSOR, OV9650_CLKRC, 0x80}, 74 /* Do something out of spec with the power */ 75 {SENSOR, OV9650_OFON, 0x40}, 76 77 /* Set fast AGC/AEC algorithm with unlimited step size */ 78 {SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC | 79 OV9650_AEC_UNLIM_STEP_SIZE}, 80 81 {SENSOR, OV9650_CHLF, 0x10}, 82 {SENSOR, OV9650_ARBLM, 0xbf}, 83 {SENSOR, OV9650_ACOM38, 0x81}, 84 /* Turn off color matrix coefficient double option */ 85 {SENSOR, OV9650_COM16, 0x00}, 86 /* Enable color matrix for RGB/YUV, Delay Y channel, 87 set output Y/UV delay to 1 */ 88 {SENSOR, OV9650_COM13, 0x19}, 89 /* Enable digital BLC, Set output mode to U Y V Y */ 90 {SENSOR, OV9650_TSLB, 0x0c}, 91 /* Limit the AGC/AEC stable upper region */ 92 {SENSOR, OV9650_COM24, 0x00}, 93 /* Enable HREF and some out of spec things */ 94 {SENSOR, OV9650_COM12, 0x73}, 95 /* Set all DBLC offset signs to positive and 96 do some out of spec stuff */ 97 {SENSOR, OV9650_DBLC1, 0xdf}, 98 {SENSOR, OV9650_COM21, 0x06}, 99 {SENSOR, OV9650_RSVD35, 0x91}, 100 /* Necessary, no camera stream without it */ 101 {SENSOR, OV9650_RSVD16, 0x06}, 102 {SENSOR, OV9650_RSVD94, 0x99}, 103 {SENSOR, OV9650_RSVD95, 0x99}, 104 {SENSOR, OV9650_RSVD96, 0x04}, 105 /* Enable full range output */ 106 {SENSOR, OV9650_COM15, 0x0}, 107 /* Enable HREF at optical black, enable ADBLC bias, 108 enable ADBLC, reset timings at format change */ 109 {SENSOR, OV9650_COM6, 0x4b}, 110 /* Subtract 32 from the B channel bias */ 111 {SENSOR, OV9650_BBIAS, 0xa0}, 112 /* Subtract 32 from the Gb channel bias */ 113 {SENSOR, OV9650_GbBIAS, 0xa0}, 114 /* Do not bypass the analog BLC and to some out of spec stuff */ 115 {SENSOR, OV9650_Gr_COM, 0x00}, 116 /* Subtract 32 from the R channel bias */ 117 {SENSOR, OV9650_RBIAS, 0xa0}, 118 /* Subtract 32 from the R channel bias */ 119 {SENSOR, OV9650_RBIAS, 0x0}, 120 {SENSOR, OV9650_COM26, 0x80}, 121 {SENSOR, OV9650_ACOMA9, 0x98}, 122 /* Set the AGC/AEC stable region upper limit */ 123 {SENSOR, OV9650_AEW, 0x68}, 124 /* Set the AGC/AEC stable region lower limit */ 125 {SENSOR, OV9650_AEB, 0x5c}, 126 /* Set the high and low limit nibbles to 3 */ 127 {SENSOR, OV9650_VPT, 0xc3}, 128 /* Set the Automatic Gain Ceiling (AGC) to 128x, 129 drop VSYNC at frame drop, 130 limit exposure timing, 131 drop frame when the AEC step is larger than the exposure gap */ 132 {SENSOR, OV9650_COM9, 0x6e}, 133 /* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync) 134 and set PWDN to SLVS (slave mode vertical sync) */ 135 {SENSOR, OV9650_COM10, 0x42}, 136 /* Set horizontal column start high to default value */ 137 {SENSOR, OV9650_HSTART, 0x1a}, /* 210 */ 138 /* Set horizontal column end */ 139 {SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */ 140 /* Complementing register to the two writes above */ 141 {SENSOR, OV9650_HREF, 0xb2}, 142 /* Set vertical row start high bits */ 143 {SENSOR, OV9650_VSTRT, 0x02}, 144 /* Set vertical row end low bits */ 145 {SENSOR, OV9650_VSTOP, 0x7e}, 146 /* Set complementing vertical frame control */ 147 {SENSOR, OV9650_VREF, 0x10}, 148 {SENSOR, OV9650_ADC, 0x04}, 149 {SENSOR, OV9650_HV, 0x40}, 150 151 /* Enable denoise, and white-pixel erase */ 152 {SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE | 153 OV9650_WHITE_PIXEL_ENABLE | 154 OV9650_WHITE_PIXEL_OPTION}, 155 156 /* Enable VARIOPIXEL */ 157 {SENSOR, OV9650_COM3, OV9650_VARIOPIXEL}, 158 {SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL}, 159 160 /* Put the sensor in soft sleep mode */ 161 {SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X}, 162 }; 163 164 static const unsigned char res_init_ov9650[][3] = { 165 {SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X}, 166 167 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82}, 168 {BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00}, 169 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, 170 {BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00}, 171 {BRIDGE, M5602_XB_SIG_INI, 0x01} 172 }; 173 174 /* Vertically and horizontally flips the image if matched, needed for machines 175 where the sensor is mounted upside down */ 176 static 177 const 178 struct dmi_system_id ov9650_flip_dmi_table[] = { 179 { 180 .ident = "ASUS A6Ja", 181 .matches = { 182 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 183 DMI_MATCH(DMI_PRODUCT_NAME, "A6J") 184 } 185 }, 186 { 187 .ident = "ASUS A6JC", 188 .matches = { 189 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 190 DMI_MATCH(DMI_PRODUCT_NAME, "A6JC") 191 } 192 }, 193 { 194 .ident = "ASUS A6K", 195 .matches = { 196 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 197 DMI_MATCH(DMI_PRODUCT_NAME, "A6K") 198 } 199 }, 200 { 201 .ident = "ASUS A6Kt", 202 .matches = { 203 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 204 DMI_MATCH(DMI_PRODUCT_NAME, "A6Kt") 205 } 206 }, 207 { 208 .ident = "ASUS A6VA", 209 .matches = { 210 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 211 DMI_MATCH(DMI_PRODUCT_NAME, "A6VA") 212 } 213 }, 214 { 215 216 .ident = "ASUS A6VC", 217 .matches = { 218 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 219 DMI_MATCH(DMI_PRODUCT_NAME, "A6VC") 220 } 221 }, 222 { 223 .ident = "ASUS A6VM", 224 .matches = { 225 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 226 DMI_MATCH(DMI_PRODUCT_NAME, "A6VM") 227 } 228 }, 229 { 230 .ident = "ASUS A7V", 231 .matches = { 232 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 233 DMI_MATCH(DMI_PRODUCT_NAME, "A7V") 234 } 235 }, 236 { 237 .ident = "Alienware Aurora m9700", 238 .matches = { 239 DMI_MATCH(DMI_SYS_VENDOR, "alienware"), 240 DMI_MATCH(DMI_PRODUCT_NAME, "Aurora m9700") 241 } 242 }, 243 {} 244 }; 245 246 static struct v4l2_pix_format ov9650_modes[] = { 247 { 248 176, 249 144, 250 V4L2_PIX_FMT_SBGGR8, 251 V4L2_FIELD_NONE, 252 .sizeimage = 253 176 * 144, 254 .bytesperline = 176, 255 .colorspace = V4L2_COLORSPACE_SRGB, 256 .priv = 9 257 }, { 258 320, 259 240, 260 V4L2_PIX_FMT_SBGGR8, 261 V4L2_FIELD_NONE, 262 .sizeimage = 263 320 * 240, 264 .bytesperline = 320, 265 .colorspace = V4L2_COLORSPACE_SRGB, 266 .priv = 8 267 }, { 268 352, 269 288, 270 V4L2_PIX_FMT_SBGGR8, 271 V4L2_FIELD_NONE, 272 .sizeimage = 273 352 * 288, 274 .bytesperline = 352, 275 .colorspace = V4L2_COLORSPACE_SRGB, 276 .priv = 9 277 }, { 278 640, 279 480, 280 V4L2_PIX_FMT_SBGGR8, 281 V4L2_FIELD_NONE, 282 .sizeimage = 283 640 * 480, 284 .bytesperline = 640, 285 .colorspace = V4L2_COLORSPACE_SRGB, 286 .priv = 9 287 } 288 }; 289 290 static const struct v4l2_ctrl_ops ov9650_ctrl_ops = { 291 .s_ctrl = ov9650_s_ctrl, 292 }; 293 294 int ov9650_probe(struct sd *sd) 295 { 296 int err = 0; 297 u8 prod_id = 0, ver_id = 0, i; 298 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; 299 300 if (force_sensor) { 301 if (force_sensor == OV9650_SENSOR) { 302 pr_info("Forcing an %s sensor\n", 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 gspca_dbg(gspca_dev, D_PROBE, "Probing for an ov9650 sensor\n"); 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 pr_info("Detected an ov9650 sensor\n"); 334 goto sensor_found; 335 } 336 return -ENODEV; 337 338 sensor_found: 339 sd->gspca_dev.cam.cam_mode = ov9650_modes; 340 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov9650_modes); 341 342 return 0; 343 } 344 345 int ov9650_init(struct sd *sd) 346 { 347 int i, err = 0; 348 u8 data; 349 350 if (dump_sensor) 351 ov9650_dump_registers(sd); 352 353 for (i = 0; i < ARRAY_SIZE(init_ov9650) && !err; i++) { 354 data = init_ov9650[i][2]; 355 if (init_ov9650[i][0] == SENSOR) 356 err = m5602_write_sensor(sd, init_ov9650[i][1], 357 &data, 1); 358 else 359 err = m5602_write_bridge(sd, init_ov9650[i][1], data); 360 } 361 362 return 0; 363 } 364 365 int ov9650_init_controls(struct sd *sd) 366 { 367 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; 368 369 sd->gspca_dev.vdev.ctrl_handler = hdl; 370 v4l2_ctrl_handler_init(hdl, 9); 371 372 sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, 373 V4L2_CID_AUTO_WHITE_BALANCE, 374 0, 1, 1, 1); 375 sd->red_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, 376 V4L2_CID_RED_BALANCE, 0, 255, 1, 377 RED_GAIN_DEFAULT); 378 sd->blue_bal = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, 379 V4L2_CID_BLUE_BALANCE, 0, 255, 1, 380 BLUE_GAIN_DEFAULT); 381 382 sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &ov9650_ctrl_ops, 383 V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO); 384 sd->expo = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_EXPOSURE, 385 0, 0x1ff, 4, EXPOSURE_DEFAULT); 386 387 sd->autogain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, 388 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 389 sd->gain = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_GAIN, 0, 390 0x3ff, 1, GAIN_DEFAULT); 391 392 sd->hflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_HFLIP, 393 0, 1, 1, 0); 394 sd->vflip = v4l2_ctrl_new_std(hdl, &ov9650_ctrl_ops, V4L2_CID_VFLIP, 395 0, 1, 1, 0); 396 397 if (hdl->error) { 398 pr_err("Could not initialize controls\n"); 399 return hdl->error; 400 } 401 402 v4l2_ctrl_auto_cluster(3, &sd->auto_white_bal, 0, false); 403 v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false); 404 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); 405 v4l2_ctrl_cluster(2, &sd->hflip); 406 407 return 0; 408 } 409 410 int ov9650_start(struct sd *sd) 411 { 412 u8 data; 413 int i, err = 0; 414 struct cam *cam = &sd->gspca_dev.cam; 415 416 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width; 417 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height; 418 int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv; 419 int hor_offs = OV9650_LEFT_OFFSET; 420 struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; 421 422 if ((!dmi_check_system(ov9650_flip_dmi_table) && 423 sd->vflip->val) || 424 (dmi_check_system(ov9650_flip_dmi_table) && 425 !sd->vflip->val)) 426 ver_offs--; 427 428 if (width <= 320) 429 hor_offs /= 2; 430 431 /* Synthesize the vsync/hsync setup */ 432 for (i = 0; i < ARRAY_SIZE(res_init_ov9650) && !err; i++) { 433 if (res_init_ov9650[i][0] == BRIDGE) 434 err = m5602_write_bridge(sd, res_init_ov9650[i][1], 435 res_init_ov9650[i][2]); 436 else if (res_init_ov9650[i][0] == SENSOR) { 437 data = res_init_ov9650[i][2]; 438 err = m5602_write_sensor(sd, 439 res_init_ov9650[i][1], &data, 1); 440 } 441 } 442 if (err < 0) 443 return err; 444 445 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 446 ((ver_offs >> 8) & 0xff)); 447 if (err < 0) 448 return err; 449 450 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff)); 451 if (err < 0) 452 return err; 453 454 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); 455 if (err < 0) 456 return err; 457 458 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff); 459 if (err < 0) 460 return err; 461 462 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff)); 463 if (err < 0) 464 return err; 465 466 for (i = 0; i < 2 && !err; i++) 467 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0); 468 if (err < 0) 469 return err; 470 471 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); 472 if (err < 0) 473 return err; 474 475 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2); 476 if (err < 0) 477 return err; 478 479 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 480 (hor_offs >> 8) & 0xff); 481 if (err < 0) 482 return err; 483 484 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, hor_offs & 0xff); 485 if (err < 0) 486 return err; 487 488 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 489 ((width + hor_offs) >> 8) & 0xff); 490 if (err < 0) 491 return err; 492 493 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 494 ((width + hor_offs) & 0xff)); 495 if (err < 0) 496 return err; 497 498 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0); 499 if (err < 0) 500 return err; 501 502 switch (width) { 503 case 640: 504 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n"); 505 506 data = OV9650_VGA_SELECT | OV9650_RGB_SELECT | 507 OV9650_RAW_RGB_SELECT; 508 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 509 break; 510 511 case 352: 512 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for CIF mode\n"); 513 514 data = OV9650_CIF_SELECT | OV9650_RGB_SELECT | 515 OV9650_RAW_RGB_SELECT; 516 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 517 break; 518 519 case 320: 520 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QVGA mode\n"); 521 522 data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT | 523 OV9650_RAW_RGB_SELECT; 524 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 525 break; 526 527 case 176: 528 gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QCIF mode\n"); 529 530 data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT | 531 OV9650_RAW_RGB_SELECT; 532 err = m5602_write_sensor(sd, OV9650_COM7, &data, 1); 533 break; 534 } 535 return err; 536 } 537 538 int ov9650_stop(struct sd *sd) 539 { 540 u8 data = OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X; 541 return m5602_write_sensor(sd, OV9650_COM2, &data, 1); 542 } 543 544 void ov9650_disconnect(struct sd *sd) 545 { 546 ov9650_stop(sd); 547 548 sd->sensor = NULL; 549 } 550 551 static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val) 552 { 553 struct sd *sd = (struct sd *) gspca_dev; 554 u8 i2c_data; 555 int err; 556 557 gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val); 558 559 /* The 6 MSBs */ 560 i2c_data = (val >> 10) & 0x3f; 561 err = m5602_write_sensor(sd, OV9650_AECHM, 562 &i2c_data, 1); 563 if (err < 0) 564 return err; 565 566 /* The 8 middle bits */ 567 i2c_data = (val >> 2) & 0xff; 568 err = m5602_write_sensor(sd, OV9650_AECH, 569 &i2c_data, 1); 570 if (err < 0) 571 return err; 572 573 /* The 2 LSBs */ 574 i2c_data = val & 0x03; 575 err = m5602_write_sensor(sd, OV9650_COM1, &i2c_data, 1); 576 return err; 577 } 578 579 static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val) 580 { 581 int err; 582 u8 i2c_data; 583 struct sd *sd = (struct sd *) gspca_dev; 584 585 gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val); 586 587 /* The 2 MSB */ 588 /* Read the OV9650_VREF register first to avoid 589 corrupting the VREF high and low bits */ 590 err = m5602_read_sensor(sd, OV9650_VREF, &i2c_data, 1); 591 if (err < 0) 592 return err; 593 594 /* Mask away all uninteresting bits */ 595 i2c_data = ((val & 0x0300) >> 2) | 596 (i2c_data & 0x3f); 597 err = m5602_write_sensor(sd, OV9650_VREF, &i2c_data, 1); 598 if (err < 0) 599 return err; 600 601 /* The 8 LSBs */ 602 i2c_data = val & 0xff; 603 err = m5602_write_sensor(sd, OV9650_GAIN, &i2c_data, 1); 604 return err; 605 } 606 607 static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val) 608 { 609 int err; 610 u8 i2c_data; 611 struct sd *sd = (struct sd *) gspca_dev; 612 613 gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d\n", val); 614 615 i2c_data = val & 0xff; 616 err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1); 617 return err; 618 } 619 620 static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val) 621 { 622 int err; 623 u8 i2c_data; 624 struct sd *sd = (struct sd *) gspca_dev; 625 626 gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d\n", val); 627 628 i2c_data = val & 0xff; 629 err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1); 630 return err; 631 } 632 633 static int ov9650_set_hvflip(struct gspca_dev *gspca_dev) 634 { 635 int err; 636 u8 i2c_data; 637 struct sd *sd = (struct sd *) gspca_dev; 638 int hflip = sd->hflip->val; 639 int vflip = sd->vflip->val; 640 641 gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d %d\n", hflip, vflip); 642 643 if (dmi_check_system(ov9650_flip_dmi_table)) 644 vflip = !vflip; 645 646 i2c_data = (hflip << 5) | (vflip << 4); 647 err = m5602_write_sensor(sd, OV9650_MVFP, &i2c_data, 1); 648 if (err < 0) 649 return err; 650 651 /* When vflip is toggled we need to readjust the bridge hsync/vsync */ 652 if (gspca_dev->streaming) 653 err = ov9650_start(sd); 654 655 return err; 656 } 657 658 static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev, 659 __s32 val) 660 { 661 int err; 662 u8 i2c_data; 663 struct sd *sd = (struct sd *) gspca_dev; 664 665 gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val); 666 667 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 668 if (err < 0) 669 return err; 670 671 val = (val == V4L2_EXPOSURE_AUTO); 672 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); 673 674 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 675 } 676 677 static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, 678 __s32 val) 679 { 680 int err; 681 u8 i2c_data; 682 struct sd *sd = (struct sd *) gspca_dev; 683 684 gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val); 685 686 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 687 if (err < 0) 688 return err; 689 690 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); 691 err = m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 692 693 return err; 694 } 695 696 static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 697 { 698 int err; 699 u8 i2c_data; 700 struct sd *sd = (struct sd *) gspca_dev; 701 702 gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val); 703 704 err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1); 705 if (err < 0) 706 return err; 707 708 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 709 710 return m5602_write_sensor(sd, OV9650_COM8, &i2c_data, 1); 711 } 712 713 static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl) 714 { 715 struct gspca_dev *gspca_dev = 716 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 717 struct sd *sd = (struct sd *) gspca_dev; 718 int err; 719 720 if (!gspca_dev->streaming) 721 return 0; 722 723 switch (ctrl->id) { 724 case V4L2_CID_AUTO_WHITE_BALANCE: 725 err = ov9650_set_auto_white_balance(gspca_dev, ctrl->val); 726 if (err || ctrl->val) 727 return err; 728 err = ov9650_set_red_balance(gspca_dev, sd->red_bal->val); 729 if (err) 730 return err; 731 err = ov9650_set_blue_balance(gspca_dev, sd->blue_bal->val); 732 break; 733 case V4L2_CID_EXPOSURE_AUTO: 734 err = ov9650_set_auto_exposure(gspca_dev, ctrl->val); 735 if (err || ctrl->val == V4L2_EXPOSURE_AUTO) 736 return err; 737 err = ov9650_set_exposure(gspca_dev, sd->expo->val); 738 break; 739 case V4L2_CID_AUTOGAIN: 740 err = ov9650_set_auto_gain(gspca_dev, ctrl->val); 741 if (err || ctrl->val) 742 return err; 743 err = ov9650_set_gain(gspca_dev, sd->gain->val); 744 break; 745 case V4L2_CID_HFLIP: 746 err = ov9650_set_hvflip(gspca_dev); 747 break; 748 default: 749 return -EINVAL; 750 } 751 752 return err; 753 } 754 755 static void ov9650_dump_registers(struct sd *sd) 756 { 757 int address; 758 pr_info("Dumping the ov9650 register state\n"); 759 for (address = 0; address < 0xa9; address++) { 760 u8 value; 761 m5602_read_sensor(sd, address, &value, 1); 762 pr_info("register 0x%x contains 0x%x\n", address, value); 763 } 764 765 pr_info("ov9650 register state dump complete\n"); 766 767 pr_info("Probing for which registers that are read/write\n"); 768 for (address = 0; address < 0xff; address++) { 769 u8 old_value, ctrl_value; 770 u8 test_value[2] = {0xff, 0xff}; 771 772 m5602_read_sensor(sd, address, &old_value, 1); 773 m5602_write_sensor(sd, address, test_value, 1); 774 m5602_read_sensor(sd, address, &ctrl_value, 1); 775 776 if (ctrl_value == test_value[0]) 777 pr_info("register 0x%x is writeable\n", address); 778 else 779 pr_info("register 0x%x is read only\n", address); 780 781 /* Restore original value */ 782 m5602_write_sensor(sd, address, &old_value, 1); 783 } 784 } 785