/* 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);

#if 0
	// Full 30/25 Frame rate
	printk("Full 30/25 Frame rate\n");
	buf[0]=BT832_VP_CONTROL0; // Reg.39
        buf[1]= 0x00;
        if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
                printk("bt832: i2c i/o error FFR: rc == %d (should be 2)\n",rc);

        bt832_hexdump(i2c_client_s,buf);
#endif

#if 1
	// 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);
#endif

	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_ALGO_BIT | 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 =
{
	I2C_DEVNAME("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:
 */
