1 /* 2 * Driver for the ov7660 sensor 3 * 4 * Copyright (C) 2009 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_ov7660.h" 22 23 static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 24 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val); 25 static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev, 26 __s32 *val); 27 static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, 28 __s32 val); 29 static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val); 30 static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val); 31 static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val); 32 static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val); 33 static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val); 34 static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val); 35 static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val); 36 static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val); 37 38 static const struct ctrl ov7660_ctrls[] = { 39 #define GAIN_IDX 1 40 { 41 { 42 .id = V4L2_CID_GAIN, 43 .type = V4L2_CTRL_TYPE_INTEGER, 44 .name = "gain", 45 .minimum = 0x00, 46 .maximum = 0xff, 47 .step = 0x1, 48 .default_value = OV7660_DEFAULT_GAIN, 49 .flags = V4L2_CTRL_FLAG_SLIDER 50 }, 51 .set = ov7660_set_gain, 52 .get = ov7660_get_gain 53 }, 54 #define BLUE_BALANCE_IDX 2 55 #define RED_BALANCE_IDX 3 56 #define AUTO_WHITE_BALANCE_IDX 4 57 { 58 { 59 .id = V4L2_CID_AUTO_WHITE_BALANCE, 60 .type = V4L2_CTRL_TYPE_BOOLEAN, 61 .name = "auto white balance", 62 .minimum = 0, 63 .maximum = 1, 64 .step = 1, 65 .default_value = 1 66 }, 67 .set = ov7660_set_auto_white_balance, 68 .get = ov7660_get_auto_white_balance 69 }, 70 #define AUTO_GAIN_CTRL_IDX 5 71 { 72 { 73 .id = V4L2_CID_AUTOGAIN, 74 .type = V4L2_CTRL_TYPE_BOOLEAN, 75 .name = "auto gain control", 76 .minimum = 0, 77 .maximum = 1, 78 .step = 1, 79 .default_value = 1 80 }, 81 .set = ov7660_set_auto_gain, 82 .get = ov7660_get_auto_gain 83 }, 84 #define AUTO_EXPOSURE_IDX 6 85 { 86 { 87 .id = V4L2_CID_EXPOSURE_AUTO, 88 .type = V4L2_CTRL_TYPE_BOOLEAN, 89 .name = "auto exposure", 90 .minimum = 0, 91 .maximum = 1, 92 .step = 1, 93 .default_value = 1 94 }, 95 .set = ov7660_set_auto_exposure, 96 .get = ov7660_get_auto_exposure 97 }, 98 #define HFLIP_IDX 7 99 { 100 { 101 .id = V4L2_CID_HFLIP, 102 .type = V4L2_CTRL_TYPE_BOOLEAN, 103 .name = "horizontal flip", 104 .minimum = 0, 105 .maximum = 1, 106 .step = 1, 107 .default_value = 0 108 }, 109 .set = ov7660_set_hflip, 110 .get = ov7660_get_hflip 111 }, 112 #define VFLIP_IDX 8 113 { 114 { 115 .id = V4L2_CID_VFLIP, 116 .type = V4L2_CTRL_TYPE_BOOLEAN, 117 .name = "vertical flip", 118 .minimum = 0, 119 .maximum = 1, 120 .step = 1, 121 .default_value = 0 122 }, 123 .set = ov7660_set_vflip, 124 .get = ov7660_get_vflip 125 }, 126 127 }; 128 129 static struct v4l2_pix_format ov7660_modes[] = { 130 { 131 640, 132 480, 133 V4L2_PIX_FMT_SBGGR8, 134 V4L2_FIELD_NONE, 135 .sizeimage = 136 640 * 480, 137 .bytesperline = 640, 138 .colorspace = V4L2_COLORSPACE_SRGB, 139 .priv = 0 140 } 141 }; 142 143 static void ov7660_dump_registers(struct sd *sd); 144 145 int ov7660_probe(struct sd *sd) 146 { 147 int err = 0, i; 148 u8 prod_id = 0, ver_id = 0; 149 150 s32 *sensor_settings; 151 152 if (force_sensor) { 153 if (force_sensor == OV7660_SENSOR) { 154 pr_info("Forcing an %s sensor\n", ov7660.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 /* Do the preinit */ 163 for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) { 164 u8 data[2]; 165 166 if (preinit_ov7660[i][0] == BRIDGE) { 167 err = m5602_write_bridge(sd, 168 preinit_ov7660[i][1], 169 preinit_ov7660[i][2]); 170 } else { 171 data[0] = preinit_ov7660[i][2]; 172 err = m5602_write_sensor(sd, 173 preinit_ov7660[i][1], data, 1); 174 } 175 } 176 if (err < 0) 177 return err; 178 179 if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1)) 180 return -ENODEV; 181 182 if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1)) 183 return -ENODEV; 184 185 pr_info("Sensor reported 0x%x%x\n", prod_id, ver_id); 186 187 if ((prod_id == 0x76) && (ver_id == 0x60)) { 188 pr_info("Detected a ov7660 sensor\n"); 189 goto sensor_found; 190 } 191 return -ENODEV; 192 193 sensor_found: 194 sensor_settings = kmalloc( 195 ARRAY_SIZE(ov7660_ctrls) * sizeof(s32), GFP_KERNEL); 196 if (!sensor_settings) 197 return -ENOMEM; 198 199 sd->gspca_dev.cam.cam_mode = ov7660_modes; 200 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes); 201 sd->desc->ctrls = ov7660_ctrls; 202 sd->desc->nctrls = ARRAY_SIZE(ov7660_ctrls); 203 204 for (i = 0; i < ARRAY_SIZE(ov7660_ctrls); i++) 205 sensor_settings[i] = ov7660_ctrls[i].qctrl.default_value; 206 sd->sensor_priv = sensor_settings; 207 208 return 0; 209 } 210 211 int ov7660_init(struct sd *sd) 212 { 213 int i, err = 0; 214 s32 *sensor_settings = sd->sensor_priv; 215 216 /* Init the sensor */ 217 for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) { 218 u8 data[2]; 219 220 if (init_ov7660[i][0] == BRIDGE) { 221 err = m5602_write_bridge(sd, 222 init_ov7660[i][1], 223 init_ov7660[i][2]); 224 } else { 225 data[0] = init_ov7660[i][2]; 226 err = m5602_write_sensor(sd, 227 init_ov7660[i][1], data, 1); 228 } 229 } 230 231 if (dump_sensor) 232 ov7660_dump_registers(sd); 233 234 err = ov7660_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]); 235 if (err < 0) 236 return err; 237 238 err = ov7660_set_auto_white_balance(&sd->gspca_dev, 239 sensor_settings[AUTO_WHITE_BALANCE_IDX]); 240 if (err < 0) 241 return err; 242 243 err = ov7660_set_auto_gain(&sd->gspca_dev, 244 sensor_settings[AUTO_GAIN_CTRL_IDX]); 245 if (err < 0) 246 return err; 247 248 err = ov7660_set_auto_exposure(&sd->gspca_dev, 249 sensor_settings[AUTO_EXPOSURE_IDX]); 250 if (err < 0) 251 return err; 252 err = ov7660_set_hflip(&sd->gspca_dev, 253 sensor_settings[HFLIP_IDX]); 254 if (err < 0) 255 return err; 256 257 err = ov7660_set_vflip(&sd->gspca_dev, 258 sensor_settings[VFLIP_IDX]); 259 260 return err; 261 } 262 263 int ov7660_start(struct sd *sd) 264 { 265 return 0; 266 } 267 268 int ov7660_stop(struct sd *sd) 269 { 270 return 0; 271 } 272 273 void ov7660_disconnect(struct sd *sd) 274 { 275 ov7660_stop(sd); 276 277 sd->sensor = NULL; 278 kfree(sd->sensor_priv); 279 } 280 281 static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 282 { 283 struct sd *sd = (struct sd *) gspca_dev; 284 s32 *sensor_settings = sd->sensor_priv; 285 286 *val = sensor_settings[GAIN_IDX]; 287 PDEBUG(D_V4L2, "Read gain %d", *val); 288 return 0; 289 } 290 291 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val) 292 { 293 int err; 294 u8 i2c_data; 295 struct sd *sd = (struct sd *) gspca_dev; 296 s32 *sensor_settings = sd->sensor_priv; 297 298 PDEBUG(D_V4L2, "Setting gain to %d", val); 299 300 sensor_settings[GAIN_IDX] = val; 301 302 err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1); 303 return err; 304 } 305 306 307 static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev, 308 __s32 *val) 309 { 310 struct sd *sd = (struct sd *) gspca_dev; 311 s32 *sensor_settings = sd->sensor_priv; 312 313 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX]; 314 return 0; 315 } 316 317 static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, 318 __s32 val) 319 { 320 int err; 321 u8 i2c_data; 322 struct sd *sd = (struct sd *) gspca_dev; 323 s32 *sensor_settings = sd->sensor_priv; 324 325 PDEBUG(D_V4L2, "Set auto white balance to %d", val); 326 327 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val; 328 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); 329 if (err < 0) 330 return err; 331 332 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); 333 err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); 334 335 return err; 336 } 337 338 static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val) 339 { 340 struct sd *sd = (struct sd *) gspca_dev; 341 s32 *sensor_settings = sd->sensor_priv; 342 343 *val = sensor_settings[AUTO_GAIN_CTRL_IDX]; 344 PDEBUG(D_V4L2, "Read auto gain control %d", *val); 345 return 0; 346 } 347 348 static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 349 { 350 int err; 351 u8 i2c_data; 352 struct sd *sd = (struct sd *) gspca_dev; 353 s32 *sensor_settings = sd->sensor_priv; 354 355 PDEBUG(D_V4L2, "Set auto gain control to %d", val); 356 357 sensor_settings[AUTO_GAIN_CTRL_IDX] = val; 358 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); 359 if (err < 0) 360 return err; 361 362 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 363 364 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); 365 } 366 367 static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val) 368 { 369 struct sd *sd = (struct sd *) gspca_dev; 370 s32 *sensor_settings = sd->sensor_priv; 371 372 *val = sensor_settings[AUTO_EXPOSURE_IDX]; 373 PDEBUG(D_V4L2, "Read auto exposure control %d", *val); 374 return 0; 375 } 376 377 static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, 378 __s32 val) 379 { 380 int err; 381 u8 i2c_data; 382 struct sd *sd = (struct sd *) gspca_dev; 383 s32 *sensor_settings = sd->sensor_priv; 384 385 PDEBUG(D_V4L2, "Set auto exposure control to %d", val); 386 387 sensor_settings[AUTO_EXPOSURE_IDX] = val; 388 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); 389 if (err < 0) 390 return err; 391 392 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); 393 394 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); 395 } 396 397 static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 398 { 399 struct sd *sd = (struct sd *) gspca_dev; 400 s32 *sensor_settings = sd->sensor_priv; 401 402 *val = sensor_settings[HFLIP_IDX]; 403 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 404 return 0; 405 } 406 407 static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 408 { 409 int err; 410 u8 i2c_data; 411 struct sd *sd = (struct sd *) gspca_dev; 412 s32 *sensor_settings = sd->sensor_priv; 413 414 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 415 416 sensor_settings[HFLIP_IDX] = val; 417 418 i2c_data = ((val & 0x01) << 5) | 419 (sensor_settings[VFLIP_IDX] << 4); 420 421 err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); 422 423 return err; 424 } 425 426 static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 427 { 428 struct sd *sd = (struct sd *) gspca_dev; 429 s32 *sensor_settings = sd->sensor_priv; 430 431 *val = sensor_settings[VFLIP_IDX]; 432 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 433 434 return 0; 435 } 436 437 static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 438 { 439 int err; 440 u8 i2c_data; 441 struct sd *sd = (struct sd *) gspca_dev; 442 s32 *sensor_settings = sd->sensor_priv; 443 444 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 445 sensor_settings[VFLIP_IDX] = val; 446 447 i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5); 448 err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); 449 if (err < 0) 450 return err; 451 452 /* When vflip is toggled we need to readjust the bridge hsync/vsync */ 453 if (gspca_dev->streaming) 454 err = ov7660_start(sd); 455 456 return err; 457 } 458 459 static void ov7660_dump_registers(struct sd *sd) 460 { 461 int address; 462 pr_info("Dumping the ov7660 register state\n"); 463 for (address = 0; address < 0xa9; address++) { 464 u8 value; 465 m5602_read_sensor(sd, address, &value, 1); 466 pr_info("register 0x%x contains 0x%x\n", address, value); 467 } 468 469 pr_info("ov7660 register state dump complete\n"); 470 471 pr_info("Probing for which registers that are read/write\n"); 472 for (address = 0; address < 0xff; address++) { 473 u8 old_value, ctrl_value; 474 u8 test_value[2] = {0xff, 0xff}; 475 476 m5602_read_sensor(sd, address, &old_value, 1); 477 m5602_write_sensor(sd, address, test_value, 1); 478 m5602_read_sensor(sd, address, &ctrl_value, 1); 479 480 if (ctrl_value == test_value[0]) 481 pr_info("register 0x%x is writeable\n", address); 482 else 483 pr_info("register 0x%x is read only\n", address); 484 485 /* Restore original value */ 486 m5602_write_sensor(sd, address, &old_value, 1); 487 } 488 } 489