/* Shared Code for OmniVision Camera Chip Drivers
 *
 * Copyright (c) 2004 Mark McClelland <mark@alpha.dyndns.org>
 * http://alpha.dyndns.org/ov511/
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
 */

#define DEBUG

#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
#include <media/v4l2-i2c-drv.h>
#include "ovcamchip_priv.h"

#define DRIVER_VERSION "v2.27 for Linux 2.6"
#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org>"
#define DRIVER_DESC "OV camera chip I2C driver"

#define PINFO(fmt, args...) printk(KERN_INFO "ovcamchip: " fmt "\n" , ## args);
#define PERROR(fmt, args...) printk(KERN_ERR "ovcamchip: " fmt "\n" , ## args);

#ifdef DEBUG
int ovcamchip_debug = 0;
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug,
  "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=all");
#endif

/* By default, let bridge driver tell us if chip is monochrome. mono=0
 * will ignore that and always treat chips as color. mono=1 will force
 * monochrome mode for all chips. */
static int mono = -1;
module_param(mono, int, 0);
MODULE_PARM_DESC(mono,
  "1=chips are monochrome (OVx1xx), 0=force color, -1=autodetect (default)");

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");


/* Registers common to all chips, that are needed for detection */
#define GENERIC_REG_ID_HIGH       0x1C	/* manufacturer ID MSB */
#define GENERIC_REG_ID_LOW        0x1D	/* manufacturer ID LSB */
#define GENERIC_REG_COM_I         0x29	/* misc ID bits */

static char *chip_names[NUM_CC_TYPES] = {
	[CC_UNKNOWN]	= "Unknown chip",
	[CC_OV76BE]	= "OV76BE",
	[CC_OV7610]	= "OV7610",
	[CC_OV7620]	= "OV7620",
	[CC_OV7620AE]	= "OV7620AE",
	[CC_OV6620]	= "OV6620",
	[CC_OV6630]	= "OV6630",
	[CC_OV6630AE]	= "OV6630AE",
	[CC_OV6630AF]	= "OV6630AF",
};

/* ----------------------------------------------------------------------- */

int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals)
{
	int rc;

	while (rvals->reg != 0xff) {
		rc = ov_write(c, rvals->reg, rvals->val);
		if (rc < 0)
			return rc;
		rvals++;
	}

	return 0;
}

/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
 * the same position as 1's in "mask" are cleared and set to "value". Bits
 * that are in the same position as 0's in "mask" are preserved, regardless
 * of their respective state in "value".
 */
int ov_write_mask(struct i2c_client *c,
		  unsigned char reg,
		  unsigned char value,
		  unsigned char mask)
{
	int rc;
	unsigned char oldval, newval;

	if (mask == 0xff) {
		newval = value;
	} else {
		rc = ov_read(c, reg, &oldval);
		if (rc < 0)
			return rc;

		oldval &= (~mask);		/* Clear the masked bits */
		value &= mask;			/* Enforce mask on value */
		newval = oldval | value;	/* Set the desired bits */
	}

	return ov_write(c, reg, newval);
}

/* ----------------------------------------------------------------------- */

/* Reset the chip and ensure that I2C is synchronized. Returns <0 if failure.
 */
static int init_camchip(struct i2c_client *c)
{
	int i, success;
	unsigned char high, low;

	/* Reset the chip */
	ov_write(c, 0x12, 0x80);

	/* Wait for it to initialize */
	msleep(150);

	for (i = 0, success = 0; i < I2C_DETECT_RETRIES && !success; i++) {
		if (ov_read(c, GENERIC_REG_ID_HIGH, &high) >= 0) {
			if (ov_read(c, GENERIC_REG_ID_LOW, &low) >= 0) {
				if (high == 0x7F && low == 0xA2) {
					success = 1;
					continue;
				}
			}
		}

		/* Reset the chip */
		ov_write(c, 0x12, 0x80);

		/* Wait for it to initialize */
		msleep(150);

		/* Dummy read to sync I2C */
		ov_read(c, 0x00, &low);
	}

	if (!success)
		return -EIO;

	PDEBUG(1, "I2C synced in %d attempt(s)", i);

	return 0;
}

/* This detects the OV7610, OV7620, or OV76BE chip. */
static int ov7xx0_detect(struct i2c_client *c)
{
	struct ovcamchip *ov = i2c_get_clientdata(c);
	int rc;
	unsigned char val;

	PDEBUG(4, "");

	/* Detect chip (sub)type */
	rc = ov_read(c, GENERIC_REG_COM_I, &val);
	if (rc < 0) {
		PERROR("Error detecting ov7xx0 type");
		return rc;
	}

	if ((val & 3) == 3) {
		PINFO("Camera chip is an OV7610");
		ov->subtype = CC_OV7610;
	} else if ((val & 3) == 1) {
		rc = ov_read(c, 0x15, &val);
		if (rc < 0) {
			PERROR("Error detecting ov7xx0 type");
			return rc;
		}

		if (val & 1) {
			PINFO("Camera chip is an OV7620AE");
			/* OV7620 is a close enough match for now. There are
			 * some definite differences though, so this should be
			 * fixed */
			ov->subtype = CC_OV7620;
		} else {
			PINFO("Camera chip is an OV76BE");
			ov->subtype = CC_OV76BE;
		}
	} else if ((val & 3) == 0) {
		PINFO("Camera chip is an OV7620");
		ov->subtype = CC_OV7620;
	} else {
		PERROR("Unknown camera chip version: %d", val & 3);
		return -ENOSYS;
	}

	if (ov->subtype == CC_OV76BE)
		ov->sops = &ov76be_ops;
	else if (ov->subtype == CC_OV7620)
		ov->sops = &ov7x20_ops;
	else
		ov->sops = &ov7x10_ops;

	return 0;
}

/* This detects the OV6620, OV6630, OV6630AE, or OV6630AF chip. */
static int ov6xx0_detect(struct i2c_client *c)
{
	struct ovcamchip *ov = i2c_get_clientdata(c);
	int rc;
	unsigned char val;

	PDEBUG(4, "");

	/* Detect chip (sub)type */
	rc = ov_read(c, GENERIC_REG_COM_I, &val);
	if (rc < 0) {
		PERROR("Error detecting ov6xx0 type");
		return -1;
	}

	if ((val & 3) == 0) {
		ov->subtype = CC_OV6630;
		PINFO("Camera chip is an OV6630");
	} else if ((val & 3) == 1) {
		ov->subtype = CC_OV6620;
		PINFO("Camera chip is an OV6620");
	} else if ((val & 3) == 2) {
		ov->subtype = CC_OV6630;
		PINFO("Camera chip is an OV6630AE");
	} else if ((val & 3) == 3) {
		ov->subtype = CC_OV6630;
		PINFO("Camera chip is an OV6630AF");
	}

	if (ov->subtype == CC_OV6620)
		ov->sops = &ov6x20_ops;
	else
		ov->sops = &ov6x30_ops;

	return 0;
}

static int ovcamchip_detect(struct i2c_client *c)
{
	/* Ideally we would just try a single register write and see if it NAKs.
	 * That isn't possible since the OV518 can't report I2C transaction
	 * failures. So, we have to try to initialize the chip (i.e. reset it
	 * and check the ID registers) to detect its presence. */

	/* Test for 7xx0 */
	PDEBUG(3, "Testing for 0V7xx0");
	if (init_camchip(c) < 0)
		return -ENODEV;
	/* 7-bit addresses with bit 0 set are for the OV7xx0 */
	if (c->addr & 1) {
		if (ov7xx0_detect(c) < 0) {
			PERROR("Failed to init OV7xx0");
			return -EIO;
		}
		return 0;
	}
	/* Test for 6xx0 */
	PDEBUG(3, "Testing for 0V6xx0");
	if (ov6xx0_detect(c) < 0) {
		PERROR("Failed to init OV6xx0");
		return -EIO;
	}
	return 0;
}

/* ----------------------------------------------------------------------- */

static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
	struct ovcamchip *ov = to_ovcamchip(sd);
	struct i2c_client *c = v4l2_get_subdevdata(sd);

	if (!ov->initialized &&
	    cmd != OVCAMCHIP_CMD_Q_SUBTYPE &&
	    cmd != OVCAMCHIP_CMD_INITIALIZE) {
		v4l2_err(sd, "Camera chip not initialized yet!\n");
		return -EPERM;
	}

	switch (cmd) {
	case OVCAMCHIP_CMD_Q_SUBTYPE:
	{
		*(int *)arg = ov->subtype;
		return 0;
	}
	case OVCAMCHIP_CMD_INITIALIZE:
	{
		int rc;

		if (mono == -1)
			ov->mono = *(int *)arg;
		else
			ov->mono = mono;

		if (ov->mono) {
			if (ov->subtype != CC_OV7620)
				v4l2_warn(sd, "Monochrome not "
					"implemented for this chip\n");
			else
				v4l2_info(sd, "Initializing chip as "
					"monochrome\n");
		}

		rc = ov->sops->init(c);
		if (rc < 0)
			return rc;

		ov->initialized = 1;
		return 0;
	}
	default:
		return ov->sops->command(c, cmd, arg);
	}
}

/* ----------------------------------------------------------------------- */

static const struct v4l2_subdev_core_ops ovcamchip_core_ops = {
	.ioctl = ovcamchip_ioctl,
};

static const struct v4l2_subdev_ops ovcamchip_ops = {
	.core = &ovcamchip_core_ops,
};

static int ovcamchip_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct ovcamchip *ov;
	struct v4l2_subdev *sd;
	int rc = 0;

	ov = kzalloc(sizeof *ov, GFP_KERNEL);
	if (!ov) {
		rc = -ENOMEM;
		goto no_ov;
	}
	sd = &ov->sd;
	v4l2_i2c_subdev_init(sd, client, &ovcamchip_ops);

	rc = ovcamchip_detect(client);
	if (rc < 0)
		goto error;

	v4l_info(client, "%s found @ 0x%02x (%s)\n",
			chip_names[ov->subtype], client->addr << 1, client->adapter->name);

	PDEBUG(1, "Camera chip detection complete");

	return rc;
error:
	kfree(ov);
no_ov:
	PDEBUG(1, "returning %d", rc);
	return rc;
}

static int ovcamchip_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd = i2c_get_clientdata(client);
	struct ovcamchip *ov = to_ovcamchip(sd);
	int rc;

	v4l2_device_unregister_subdev(sd);
	rc = ov->sops->free(client);
	if (rc < 0)
		return rc;

	kfree(ov);
	return 0;
}

/* ----------------------------------------------------------------------- */

static const struct i2c_device_id ovcamchip_id[] = {
	{ "ovcamchip", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ovcamchip_id);

static struct v4l2_i2c_driver_data v4l2_i2c_data = {
	.name = "ovcamchip",
	.probe = ovcamchip_probe,
	.remove = ovcamchip_remove,
	.id_table = ovcamchip_id,
};
