/* Driver for Bt832 CMOS Camera Video Processor
    i2c-addresses: 0x88 or 0x8a

  The BT832 interfaces to a Quartzsight Digital Camera (352x288, 25 or 30 fps)
  via a 9 pin connector ( 4-wire SDATA, 2-wire i2c, SCLK, VCC, GND).
  It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly
  connected to bt848/bt878 GPIO pins on this purpose.
  (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets)

  Supported Cards:
  -  Pixelview Rev.4E: 0x8a
		GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 !

  (c) Gunther Mayer, 2002

  STATUS:
  - detect chip and hexdump
  - reset chip and leave low power mode
  - detect camera present

  TODO:
  - make it work (find correct setup for Bt832 and Bt878)
*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/types.h>
#include <linux/videodev.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>

#include <media/audiochip.h>
#include <media/id.h>
#include "bttv.h"
#include "bt832.h"

MODULE_LICENSE("GPL");

/* Addresses to scan */
static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1,
				       I2C_CLIENT_END };
I2C_CLIENT_INSMOD;

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

#define dprintk     if (debug) printk

static int bt832_detach(struct i2c_client *client);


static struct i2c_driver driver;
static struct i2c_client client_template;

struct bt832 {
	struct i2c_client client;
};

int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
{
	int i,rc;
	buf[0]=0x80; // start at register 0 with auto-increment
	if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
		printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);

	for(i=0;i<65;i++)
		buf[i]=0;
	if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
		printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);

	// Note: On READ the first byte is the current index
	//  (e.g. 0x80, what we just wrote)

	if(1) {
		int i;
		printk("BT832 hexdump:\n");
		for(i=1;i<65;i++) {
			if(i!=1) {
			  if(((i-1)%8)==0) printk(" ");
			  if(((i-1)%16)==0) printk("\n");
			}
			printk(" %02x",buf[i]);
		}
		printk("\n");
	}
	return 0;
}

// Return: 1 (is a bt832), 0 (No bt832 here)
int bt832_init(struct i2c_client *i2c_client_s)
{
	unsigned char *buf;
	int rc;

	buf=kmalloc(65,GFP_KERNEL);
	bt832_hexdump(i2c_client_s,buf);

	if(buf[0x40] != 0x31) {
		printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
		kfree(buf);
		return 0;
	}

	printk("Write 0 tp VPSTATUS\n");
	buf[0]=BT832_VP_STATUS; // Reg.52
	buf[1]= 0x00;
	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
		printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);

	bt832_hexdump(i2c_client_s,buf);


	// Leave low power mode:
	printk("Bt832: leave low power mode.\n");
	buf[0]=BT832_CAM_SETUP0; //0x39 57
	buf[1]=0x08;
	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
		printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);

	bt832_hexdump(i2c_client_s,buf);

	printk("Write 0 tp VPSTATUS\n");
	buf[0]=BT832_VP_STATUS; // Reg.52
	buf[1]= 0x00;
	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
		printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);

	bt832_hexdump(i2c_client_s,buf);


	// Enable Output
	printk("Enable Output\n");
	buf[0]=BT832_VP_CONTROL1; // Reg.40
	buf[1]= 0x27 & (~0x01); // Default | !skip
	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
		printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);

	bt832_hexdump(i2c_client_s,buf);


	// for testing (even works when no camera attached)
	printk("bt832: *** Generate NTSC M Bars *****\n");
	buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
	buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
		printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);

	printk("Bt832: Camera Present: %s\n",
		(buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");

	bt832_hexdump(i2c_client_s,buf);
	kfree(buf);
	return 1;
}



static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
{
	struct bt832 *t;

	printk("bt832_attach\n");

	client_template.adapter = adap;
	client_template.addr    = addr;

	printk("bt832: chip found @ 0x%x\n", addr<<1);

	if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
		return -ENOMEM;
	memset(t,0,sizeof(*t));
	t->client = client_template;
	i2c_set_clientdata(&t->client, t);
	i2c_attach_client(&t->client);

	if(! bt832_init(&t->client)) {
		bt832_detach(&t->client);
		return -1;
	}

	return 0;
}

static int bt832_probe(struct i2c_adapter *adap)
{
#ifdef I2C_CLASS_TV_ANALOG
	if (adap->class & I2C_CLASS_TV_ANALOG)
		return i2c_probe(adap, &addr_data, bt832_attach);
#else
	if (adap->id == I2C_HW_B_BT848)
		return i2c_probe(adap, &addr_data, bt832_attach);
#endif
	return 0;
}

static int bt832_detach(struct i2c_client *client)
{
	struct bt832 *t = i2c_get_clientdata(client);

	printk("bt832: detach.\n");
	i2c_detach_client(client);
	kfree(t);
	return 0;
}

static int
bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
	struct bt832 *t = i2c_get_clientdata(client);

	printk("bt832: command %x\n",cmd);

	switch (cmd) {
		case BT832_HEXDUMP: {
			unsigned char *buf;
			buf=kmalloc(65,GFP_KERNEL);
			bt832_hexdump(&t->client,buf);
			kfree(buf);
		}
		break;
		case BT832_REATTACH:
			printk("bt832: re-attach\n");
			i2c_del_driver(&driver);
			i2c_add_driver(&driver);
		break;
	}
	return 0;
}

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

static struct i2c_driver driver = {
	.owner          = THIS_MODULE,
        .name           = "i2c bt832 driver",
        .id             = -1, /* FIXME */
        .flags          = I2C_DF_NOTIFY,
        .attach_adapter = bt832_probe,
        .detach_client  = bt832_detach,
        .command        = bt832_command,
};
static struct i2c_client client_template =
{
	.name       = "bt832",
	.flags      = I2C_CLIENT_ALLOW_USE,
        .driver     = &driver,
};


static int __init bt832_init_module(void)
{
	return i2c_add_driver(&driver);
}

static void __exit bt832_cleanup_module(void)
{
	i2c_del_driver(&driver);
}

module_init(bt832_init_module);
module_exit(bt832_cleanup_module);

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-basic-offset: 8
 * End:
 */
