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_s_ctrl(struct v4l2_ctrl *ctrl); 24 static void ov7660_dump_registers(struct sd *sd); 25 26 static const unsigned char preinit_ov7660[][4] = { 27 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, 28 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, 29 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 30 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 31 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 32 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, 33 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 34 {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, 35 {BRIDGE, M5602_XB_GPIO_DIR, 0x03}, 36 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 37 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 38 39 {SENSOR, OV7660_OFON, 0x0c}, 40 {SENSOR, OV7660_COM2, 0x11}, 41 {SENSOR, OV7660_COM7, 0x05}, 42 43 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 44 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 45 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 46 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 47 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, 48 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, 49 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 50 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 51 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 52 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 53 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 54 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 55 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 56 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 57 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00} 58 }; 59 60 static const unsigned char init_ov7660[][4] = { 61 {BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02}, 62 {BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0}, 63 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 64 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 65 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 66 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, 67 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 68 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 69 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 70 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 71 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 72 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 73 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 74 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 75 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 76 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 77 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, 78 {SENSOR, OV7660_COM7, 0x80}, 79 {SENSOR, OV7660_CLKRC, 0x80}, 80 {SENSOR, OV7660_COM9, 0x4c}, 81 {SENSOR, OV7660_OFON, 0x43}, 82 {SENSOR, OV7660_COM12, 0x28}, 83 {SENSOR, OV7660_COM8, 0x00}, 84 {SENSOR, OV7660_COM10, 0x40}, 85 {SENSOR, OV7660_HSTART, 0x0c}, 86 {SENSOR, OV7660_HSTOP, 0x61}, 87 {SENSOR, OV7660_HREF, 0xa4}, 88 {SENSOR, OV7660_PSHFT, 0x0b}, 89 {SENSOR, OV7660_VSTART, 0x01}, 90 {SENSOR, OV7660_VSTOP, 0x7a}, 91 {SENSOR, OV7660_VSTOP, 0x00}, 92 {SENSOR, OV7660_COM7, 0x05}, 93 {SENSOR, OV7660_COM6, 0x42}, 94 {SENSOR, OV7660_BBIAS, 0x94}, 95 {SENSOR, OV7660_GbBIAS, 0x94}, 96 {SENSOR, OV7660_RSVD29, 0x94}, 97 {SENSOR, OV7660_RBIAS, 0x94}, 98 {SENSOR, OV7660_COM1, 0x00}, 99 {SENSOR, OV7660_AECH, 0x00}, 100 {SENSOR, OV7660_AECHH, 0x00}, 101 {SENSOR, OV7660_ADC, 0x05}, 102 {SENSOR, OV7660_COM13, 0x00}, 103 {SENSOR, OV7660_RSVDA1, 0x23}, 104 {SENSOR, OV7660_TSLB, 0x0d}, 105 {SENSOR, OV7660_HV, 0x80}, 106 {SENSOR, OV7660_LCC1, 0x00}, 107 {SENSOR, OV7660_LCC2, 0x00}, 108 {SENSOR, OV7660_LCC3, 0x10}, 109 {SENSOR, OV7660_LCC4, 0x40}, 110 {SENSOR, OV7660_LCC5, 0x01}, 111 112 {SENSOR, OV7660_AECH, 0x20}, 113 {SENSOR, OV7660_COM1, 0x00}, 114 {SENSOR, OV7660_OFON, 0x0c}, 115 {SENSOR, OV7660_COM2, 0x11}, 116 {SENSOR, OV7660_COM7, 0x05}, 117 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 118 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 119 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 120 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 121 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, 122 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, 123 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 124 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 125 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 126 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 127 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 128 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 129 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 130 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 131 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, 132 {SENSOR, OV7660_AECH, 0x5f}, 133 {SENSOR, OV7660_COM1, 0x03}, 134 {SENSOR, OV7660_OFON, 0x0c}, 135 {SENSOR, OV7660_COM2, 0x11}, 136 {SENSOR, OV7660_COM7, 0x05}, 137 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 138 {BRIDGE, M5602_XB_GPIO_DAT, 0x04}, 139 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 140 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06}, 141 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00}, 142 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08}, 143 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 144 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 145 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 146 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 147 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 148 {BRIDGE, M5602_XB_GPIO_DIR, 0x05}, 149 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 150 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 151 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, 152 153 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, 154 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 155 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 156 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c}, 157 {BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81}, 158 {BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82}, 159 {BRIDGE, M5602_XB_SIG_INI, 0x01}, 160 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 161 {BRIDGE, M5602_XB_VSYNC_PARA, 0x08}, 162 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 163 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 164 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, 165 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec}, 166 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 167 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 168 {BRIDGE, M5602_XB_SIG_INI, 0x00}, 169 {BRIDGE, M5602_XB_SIG_INI, 0x02}, 170 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00}, 171 {BRIDGE, M5602_XB_HSYNC_PARA, 0x27}, 172 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02}, 173 {BRIDGE, M5602_XB_HSYNC_PARA, 0xa7}, 174 {BRIDGE, M5602_XB_SIG_INI, 0x00}, 175 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 176 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 177 }; 178 179 static struct v4l2_pix_format ov7660_modes[] = { 180 { 181 640, 182 480, 183 V4L2_PIX_FMT_SBGGR8, 184 V4L2_FIELD_NONE, 185 .sizeimage = 186 640 * 480, 187 .bytesperline = 640, 188 .colorspace = V4L2_COLORSPACE_SRGB, 189 .priv = 0 190 } 191 }; 192 193 static const struct v4l2_ctrl_ops ov7660_ctrl_ops = { 194 .s_ctrl = ov7660_s_ctrl, 195 }; 196 197 int ov7660_probe(struct sd *sd) 198 { 199 int err = 0, i; 200 u8 prod_id = 0, ver_id = 0; 201 202 if (force_sensor) { 203 if (force_sensor == OV7660_SENSOR) { 204 pr_info("Forcing an %s sensor\n", ov7660.name); 205 goto sensor_found; 206 } 207 /* If we want to force another sensor, 208 don't try to probe this one */ 209 return -ENODEV; 210 } 211 212 /* Do the preinit */ 213 for (i = 0; i < ARRAY_SIZE(preinit_ov7660) && !err; i++) { 214 u8 data[2]; 215 216 if (preinit_ov7660[i][0] == BRIDGE) { 217 err = m5602_write_bridge(sd, 218 preinit_ov7660[i][1], 219 preinit_ov7660[i][2]); 220 } else { 221 data[0] = preinit_ov7660[i][2]; 222 err = m5602_write_sensor(sd, 223 preinit_ov7660[i][1], data, 1); 224 } 225 } 226 if (err < 0) 227 return err; 228 229 if (m5602_read_sensor(sd, OV7660_PID, &prod_id, 1)) 230 return -ENODEV; 231 232 if (m5602_read_sensor(sd, OV7660_VER, &ver_id, 1)) 233 return -ENODEV; 234 235 pr_info("Sensor reported 0x%x%x\n", prod_id, ver_id); 236 237 if ((prod_id == 0x76) && (ver_id == 0x60)) { 238 pr_info("Detected a ov7660 sensor\n"); 239 goto sensor_found; 240 } 241 return -ENODEV; 242 243 sensor_found: 244 sd->gspca_dev.cam.cam_mode = ov7660_modes; 245 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(ov7660_modes); 246 247 return 0; 248 } 249 250 int ov7660_init(struct sd *sd) 251 { 252 int i, err; 253 254 /* Init the sensor */ 255 for (i = 0; i < ARRAY_SIZE(init_ov7660); i++) { 256 u8 data[2]; 257 258 if (init_ov7660[i][0] == BRIDGE) { 259 err = m5602_write_bridge(sd, 260 init_ov7660[i][1], 261 init_ov7660[i][2]); 262 } else { 263 data[0] = init_ov7660[i][2]; 264 err = m5602_write_sensor(sd, 265 init_ov7660[i][1], data, 1); 266 } 267 if (err < 0) 268 return err; 269 } 270 271 if (dump_sensor) 272 ov7660_dump_registers(sd); 273 274 return 0; 275 } 276 277 int ov7660_init_controls(struct sd *sd) 278 { 279 struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler; 280 281 sd->gspca_dev.vdev.ctrl_handler = hdl; 282 v4l2_ctrl_handler_init(hdl, 6); 283 284 v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 285 0, 1, 1, 1); 286 v4l2_ctrl_new_std_menu(hdl, &ov7660_ctrl_ops, 287 V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO); 288 289 sd->autogain = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, 290 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 291 sd->gain = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_GAIN, 0, 292 255, 1, OV7660_DEFAULT_GAIN); 293 294 sd->hflip = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_HFLIP, 295 0, 1, 1, 0); 296 sd->vflip = v4l2_ctrl_new_std(hdl, &ov7660_ctrl_ops, V4L2_CID_VFLIP, 297 0, 1, 1, 0); 298 299 if (hdl->error) { 300 pr_err("Could not initialize controls\n"); 301 return hdl->error; 302 } 303 304 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); 305 v4l2_ctrl_cluster(2, &sd->hflip); 306 307 return 0; 308 } 309 310 int ov7660_start(struct sd *sd) 311 { 312 return 0; 313 } 314 315 int ov7660_stop(struct sd *sd) 316 { 317 return 0; 318 } 319 320 void ov7660_disconnect(struct sd *sd) 321 { 322 ov7660_stop(sd); 323 324 sd->sensor = NULL; 325 } 326 327 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val) 328 { 329 int err; 330 u8 i2c_data = val; 331 struct sd *sd = (struct sd *) gspca_dev; 332 333 gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val); 334 335 err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1); 336 return err; 337 } 338 339 static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev, 340 __s32 val) 341 { 342 int err; 343 u8 i2c_data; 344 struct sd *sd = (struct sd *) gspca_dev; 345 346 gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val); 347 348 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); 349 if (err < 0) 350 return err; 351 352 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1)); 353 err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); 354 355 return err; 356 } 357 358 static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val) 359 { 360 int err; 361 u8 i2c_data; 362 struct sd *sd = (struct sd *) gspca_dev; 363 364 gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val); 365 366 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); 367 if (err < 0) 368 return err; 369 370 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2)); 371 372 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); 373 } 374 375 static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, 376 __s32 val) 377 { 378 int err; 379 u8 i2c_data; 380 struct sd *sd = (struct sd *) gspca_dev; 381 382 gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val); 383 384 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1); 385 if (err < 0) 386 return err; 387 388 val = (val == V4L2_EXPOSURE_AUTO); 389 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0)); 390 391 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1); 392 } 393 394 static int ov7660_set_hvflip(struct gspca_dev *gspca_dev) 395 { 396 int err; 397 u8 i2c_data; 398 struct sd *sd = (struct sd *) gspca_dev; 399 400 gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d, %d\n", 401 sd->hflip->val, sd->vflip->val); 402 403 i2c_data = (sd->hflip->val << 5) | (sd->vflip->val << 4); 404 405 err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1); 406 407 return err; 408 } 409 410 static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl) 411 { 412 struct gspca_dev *gspca_dev = 413 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 414 struct sd *sd = (struct sd *) gspca_dev; 415 int err; 416 417 if (!gspca_dev->streaming) 418 return 0; 419 420 switch (ctrl->id) { 421 case V4L2_CID_AUTO_WHITE_BALANCE: 422 err = ov7660_set_auto_white_balance(gspca_dev, ctrl->val); 423 break; 424 case V4L2_CID_EXPOSURE_AUTO: 425 err = ov7660_set_auto_exposure(gspca_dev, ctrl->val); 426 break; 427 case V4L2_CID_AUTOGAIN: 428 err = ov7660_set_auto_gain(gspca_dev, ctrl->val); 429 if (err || ctrl->val) 430 return err; 431 err = ov7660_set_gain(gspca_dev, sd->gain->val); 432 break; 433 case V4L2_CID_HFLIP: 434 err = ov7660_set_hvflip(gspca_dev); 435 break; 436 default: 437 return -EINVAL; 438 } 439 440 return err; 441 } 442 443 static void ov7660_dump_registers(struct sd *sd) 444 { 445 int address; 446 pr_info("Dumping the ov7660 register state\n"); 447 for (address = 0; address < 0xa9; address++) { 448 u8 value; 449 m5602_read_sensor(sd, address, &value, 1); 450 pr_info("register 0x%x contains 0x%x\n", address, value); 451 } 452 453 pr_info("ov7660 register state dump complete\n"); 454 455 pr_info("Probing for which registers that are read/write\n"); 456 for (address = 0; address < 0xff; address++) { 457 u8 old_value, ctrl_value; 458 u8 test_value[2] = {0xff, 0xff}; 459 460 m5602_read_sensor(sd, address, &old_value, 1); 461 m5602_write_sensor(sd, address, test_value, 1); 462 m5602_read_sensor(sd, address, &ctrl_value, 1); 463 464 if (ctrl_value == test_value[0]) 465 pr_info("register 0x%x is writeable\n", address); 466 else 467 pr_info("register 0x%x is read only\n", address); 468 469 /* Restore original value */ 470 m5602_write_sensor(sd, address, &old_value, 1); 471 } 472 } 473