1/* Shared Code for OmniVision Camera Chip Drivers 2 * 3 * Copyright (c) 2004 Mark McClelland <mark@alpha.dyndns.org> 4 * http://alpha.dyndns.org/ov511/ 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2 of the License, or (at your 9 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied. 10 */ 11 12#define DEBUG 13 14#include <linux/init.h> 15#include <linux/module.h> 16#include <linux/moduleparam.h> 17#include <linux/slab.h> 18#include <linux/delay.h> 19#include "ovcamchip_priv.h" 20 21#define DRIVER_VERSION "v2.27 for Linux 2.6" 22#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org>" 23#define DRIVER_DESC "OV camera chip I2C driver" 24 25#define PINFO(fmt, args...) printk(KERN_INFO "ovcamchip: " fmt "\n" , ## args); 26#define PERROR(fmt, args...) printk(KERN_ERR "ovcamchip: " fmt "\n" , ## args); 27 28#ifdef DEBUG 29int ovcamchip_debug = 0; 30static int debug; 31module_param(debug, int, 0); 32MODULE_PARM_DESC(debug, 33 "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=all"); 34#endif 35 36/* By default, let bridge driver tell us if chip is monochrome. mono=0 37 * will ignore that and always treat chips as color. mono=1 will force 38 * monochrome mode for all chips. */ 39static int mono = -1; 40module_param(mono, int, 0); 41MODULE_PARM_DESC(mono, 42 "1=chips are monochrome (OVx1xx), 0=force color, -1=autodetect (default)"); 43 44MODULE_AUTHOR(DRIVER_AUTHOR); 45MODULE_DESCRIPTION(DRIVER_DESC); 46MODULE_LICENSE("GPL"); 47 48/* Registers common to all chips, that are needed for detection */ 49#define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */ 50#define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */ 51#define GENERIC_REG_COM_I 0x29 /* misc ID bits */ 52 53extern struct ovcamchip_ops ov6x20_ops; 54extern struct ovcamchip_ops ov6x30_ops; 55extern struct ovcamchip_ops ov7x10_ops; 56extern struct ovcamchip_ops ov7x20_ops; 57extern struct ovcamchip_ops ov76be_ops; 58 59static char *chip_names[NUM_CC_TYPES] = { 60 [CC_UNKNOWN] = "Unknown chip", 61 [CC_OV76BE] = "OV76BE", 62 [CC_OV7610] = "OV7610", 63 [CC_OV7620] = "OV7620", 64 [CC_OV7620AE] = "OV7620AE", 65 [CC_OV6620] = "OV6620", 66 [CC_OV6630] = "OV6630", 67 [CC_OV6630AE] = "OV6630AE", 68 [CC_OV6630AF] = "OV6630AF", 69}; 70 71/* Forward declarations */ 72static struct i2c_driver driver; 73static struct i2c_client client_template; 74 75/* ----------------------------------------------------------------------- */ 76 77int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals) 78{ 79 int rc; 80 81 while (rvals->reg != 0xff) { 82 rc = ov_write(c, rvals->reg, rvals->val); 83 if (rc < 0) 84 return rc; 85 rvals++; 86 } 87 88 return 0; 89} 90 91/* Writes bits at positions specified by mask to an I2C reg. Bits that are in 92 * the same position as 1's in "mask" are cleared and set to "value". Bits 93 * that are in the same position as 0's in "mask" are preserved, regardless 94 * of their respective state in "value". 95 */ 96int ov_write_mask(struct i2c_client *c, 97 unsigned char reg, 98 unsigned char value, 99 unsigned char mask) 100{ 101 int rc; 102 unsigned char oldval, newval; 103 104 if (mask == 0xff) { 105 newval = value; 106 } else { 107 rc = ov_read(c, reg, &oldval); 108 if (rc < 0) 109 return rc; 110 111 oldval &= (~mask); /* Clear the masked bits */ 112 value &= mask; /* Enforce mask on value */ 113 newval = oldval | value; /* Set the desired bits */ 114 } 115 116 return ov_write(c, reg, newval); 117} 118 119/* ----------------------------------------------------------------------- */ 120 121/* Reset the chip and ensure that I2C is synchronized. Returns <0 if failure. 122 */ 123static int init_camchip(struct i2c_client *c) 124{ 125 int i, success; 126 unsigned char high, low; 127 128 /* Reset the chip */ 129 ov_write(c, 0x12, 0x80); 130 131 /* Wait for it to initialize */ 132 msleep(150); 133 134 for (i = 0, success = 0; i < I2C_DETECT_RETRIES && !success; i++) { 135 if (ov_read(c, GENERIC_REG_ID_HIGH, &high) >= 0) { 136 if (ov_read(c, GENERIC_REG_ID_LOW, &low) >= 0) { 137 if (high == 0x7F && low == 0xA2) { 138 success = 1; 139 continue; 140 } 141 } 142 } 143 144 /* Reset the chip */ 145 ov_write(c, 0x12, 0x80); 146 147 /* Wait for it to initialize */ 148 msleep(150); 149 150 /* Dummy read to sync I2C */ 151 ov_read(c, 0x00, &low); 152 } 153 154 if (!success) 155 return -EIO; 156 157 PDEBUG(1, "I2C synced in %d attempt(s)", i); 158 159 return 0; 160} 161 162/* This detects the OV7610, OV7620, or OV76BE chip. */ 163static int ov7xx0_detect(struct i2c_client *c) 164{ 165 struct ovcamchip *ov = i2c_get_clientdata(c); 166 int rc; 167 unsigned char val; 168 169 PDEBUG(4, ""); 170 171 /* Detect chip (sub)type */ 172 rc = ov_read(c, GENERIC_REG_COM_I, &val); 173 if (rc < 0) { 174 PERROR("Error detecting ov7xx0 type"); 175 return rc; 176 } 177 178 if ((val & 3) == 3) { 179 PINFO("Camera chip is an OV7610"); 180 ov->subtype = CC_OV7610; 181 } else if ((val & 3) == 1) { 182 rc = ov_read(c, 0x15, &val); 183 if (rc < 0) { 184 PERROR("Error detecting ov7xx0 type"); 185 return rc; 186 } 187 188 if (val & 1) { 189 PINFO("Camera chip is an OV7620AE"); 190 /* OV7620 is a close enough match for now. There are 191 * some definite differences though, so this should be 192 * fixed */ 193 ov->subtype = CC_OV7620; 194 } else { 195 PINFO("Camera chip is an OV76BE"); 196 ov->subtype = CC_OV76BE; 197 } 198 } else if ((val & 3) == 0) { 199 PINFO("Camera chip is an OV7620"); 200 ov->subtype = CC_OV7620; 201 } else { 202 PERROR("Unknown camera chip version: %d", val & 3); 203 return -ENOSYS; 204 } 205 206 if (ov->subtype == CC_OV76BE) 207 ov->sops = &ov76be_ops; 208 else if (ov->subtype == CC_OV7620) 209 ov->sops = &ov7x20_ops; 210 else 211 ov->sops = &ov7x10_ops; 212 213 return 0; 214} 215 216/* This detects the OV6620, OV6630, OV6630AE, or OV6630AF chip. */ 217static int ov6xx0_detect(struct i2c_client *c) 218{ 219 struct ovcamchip *ov = i2c_get_clientdata(c); 220 int rc; 221 unsigned char val; 222 223 PDEBUG(4, ""); 224 225 /* Detect chip (sub)type */ 226 rc = ov_read(c, GENERIC_REG_COM_I, &val); 227 if (rc < 0) { 228 PERROR("Error detecting ov6xx0 type"); 229 return -1; 230 } 231 232 if ((val & 3) == 0) { 233 ov->subtype = CC_OV6630; 234 PINFO("Camera chip is an OV6630"); 235 } else if ((val & 3) == 1) { 236 ov->subtype = CC_OV6620; 237 PINFO("Camera chip is an OV6620"); 238 } else if ((val & 3) == 2) { 239 ov->subtype = CC_OV6630; 240 PINFO("Camera chip is an OV6630AE"); 241 } else if ((val & 3) == 3) { 242 ov->subtype = CC_OV6630; 243 PINFO("Camera chip is an OV6630AF"); 244 } 245 246 if (ov->subtype == CC_OV6620) 247 ov->sops = &ov6x20_ops; 248 else 249 ov->sops = &ov6x30_ops; 250 251 return 0; 252} 253 254static int ovcamchip_detect(struct i2c_client *c) 255{ 256 /* Ideally we would just try a single register write and see if it NAKs. 257 * That isn't possible since the OV518 can't report I2C transaction 258 * failures. So, we have to try to initialize the chip (i.e. reset it 259 * and check the ID registers) to detect its presence. */ 260 261 /* Test for 7xx0 */ 262 PDEBUG(3, "Testing for 0V7xx0"); 263 c->addr = OV7xx0_SID; 264 if (init_camchip(c) < 0) { 265 /* Test for 6xx0 */ 266 PDEBUG(3, "Testing for 0V6xx0"); 267 c->addr = OV6xx0_SID; 268 if (init_camchip(c) < 0) { 269 return -ENODEV; 270 } else { 271 if (ov6xx0_detect(c) < 0) { 272 PERROR("Failed to init OV6xx0"); 273 return -EIO; 274 } 275 } 276 } else { 277 if (ov7xx0_detect(c) < 0) { 278 PERROR("Failed to init OV7xx0"); 279 return -EIO; 280 } 281 } 282 283 return 0; 284} 285 286/* ----------------------------------------------------------------------- */ 287 288static int ovcamchip_attach(struct i2c_adapter *adap) 289{ 290 int rc = 0; 291 struct ovcamchip *ov; 292 struct i2c_client *c; 293 294 /* I2C is not a PnP bus, so we can never be certain that we're talking 295 * to the right chip. To prevent damage to EEPROMS and such, only 296 * attach to adapters that are known to contain OV camera chips. */ 297 298 switch (adap->id) { 299 case I2C_HW_SMBUS_OV511: 300 case I2C_HW_SMBUS_OV518: 301 case I2C_HW_SMBUS_OVFX2: 302 case I2C_HW_SMBUS_W9968CF: 303 PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id); 304 break; 305 default: 306 PDEBUG(1, "Adapter ID 0x%06x rejected", adap->id); 307 return -ENODEV; 308 } 309 310 c = kmalloc(sizeof *c, GFP_KERNEL); 311 if (!c) { 312 rc = -ENOMEM; 313 goto no_client; 314 } 315 memcpy(c, &client_template, sizeof *c); 316 c->adapter = adap; 317 strcpy(c->name, "OV????"); 318 319 ov = kzalloc(sizeof *ov, GFP_KERNEL); 320 if (!ov) { 321 rc = -ENOMEM; 322 goto no_ov; 323 } 324 i2c_set_clientdata(c, ov); 325 326 rc = ovcamchip_detect(c); 327 if (rc < 0) 328 goto error; 329 330 strcpy(c->name, chip_names[ov->subtype]); 331 332 PDEBUG(1, "Camera chip detection complete"); 333 334 i2c_attach_client(c); 335 336 return rc; 337error: 338 kfree(ov); 339no_ov: 340 kfree(c); 341no_client: 342 PDEBUG(1, "returning %d", rc); 343 return rc; 344} 345 346static int ovcamchip_detach(struct i2c_client *c) 347{ 348 struct ovcamchip *ov = i2c_get_clientdata(c); 349 int rc; 350 351 rc = ov->sops->free(c); 352 if (rc < 0) 353 return rc; 354 355 i2c_detach_client(c); 356 357 kfree(ov); 358 kfree(c); 359 return 0; 360} 361 362static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg) 363{ 364 struct ovcamchip *ov = i2c_get_clientdata(c); 365 366 if (!ov->initialized && 367 cmd != OVCAMCHIP_CMD_Q_SUBTYPE && 368 cmd != OVCAMCHIP_CMD_INITIALIZE) { 369 dev_err(&c->dev, "ERROR: Camera chip not initialized yet!\n"); 370 return -EPERM; 371 } 372 373 switch (cmd) { 374 case OVCAMCHIP_CMD_Q_SUBTYPE: 375 { 376 *(int *)arg = ov->subtype; 377 return 0; 378 } 379 case OVCAMCHIP_CMD_INITIALIZE: 380 { 381 int rc; 382 383 if (mono == -1) 384 ov->mono = *(int *)arg; 385 else 386 ov->mono = mono; 387 388 if (ov->mono) { 389 if (ov->subtype != CC_OV7620) 390 dev_warn(&c->dev, "Warning: Monochrome not " 391 "implemented for this chip\n"); 392 else 393 dev_info(&c->dev, "Initializing chip as " 394 "monochrome\n"); 395 } 396 397 rc = ov->sops->init(c); 398 if (rc < 0) 399 return rc; 400 401 ov->initialized = 1; 402 return 0; 403 } 404 default: 405 return ov->sops->command(c, cmd, arg); 406 } 407} 408 409/* ----------------------------------------------------------------------- */ 410 411static struct i2c_driver driver = { 412 .driver = { 413 .name = "ovcamchip", 414 }, 415 .id = I2C_DRIVERID_OVCAMCHIP, 416 .class = I2C_CLASS_CAM_DIGITAL, 417 .attach_adapter = ovcamchip_attach, 418 .detach_client = ovcamchip_detach, 419 .command = ovcamchip_command, 420}; 421 422static struct i2c_client client_template = { 423 .name = "(unset)", 424 .driver = &driver, 425}; 426 427static int __init ovcamchip_init(void) 428{ 429#ifdef DEBUG 430 ovcamchip_debug = debug; 431#endif 432 433 PINFO(DRIVER_VERSION " : " DRIVER_DESC); 434 return i2c_add_driver(&driver); 435} 436 437static void __exit ovcamchip_exit(void) 438{ 439 i2c_del_driver(&driver); 440} 441 442module_init(ovcamchip_init); 443module_exit(ovcamchip_exit); 444