Subject: [PATCH] ALCHEMY: Alchemy Camera Interface (CIM) driver

From: "Jordan Crouse" <[email-masked]>
Date: Fri, 2 Dec 2005 12:06:35 -0700

A driver for the AU1200 Camera Interface (CIM).  Definately 
should be postponed post 2.6.15.  This is the most complex one
I'm sending up right now, so comments and flames are definately
welcome.

Signed-off-by: Jordan Crouse <[email-masked]>
---

 drivers/Makefile                          |    2 
 drivers/char/Kconfig                      |    4 
 drivers/char/Makefile                     |    1 
 drivers/char/au1xxx_cameras.h             |  572 ++++++++++++++++++++++++++
 drivers/char/au1xxx_cim.c                 |  647 +++++++++++++++++++++++++++++
 include/asm-mips/mach-au1x00/au1xxx_cim.h |  190 +++++++++
 6 files changed, 1415 insertions(+), 1 deletions(-)

diff --git a/drivers/Makefile b/drivers/Makefile
index fac1e16..7ab1608 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PNP)		+= pnp/
 
 # char/ comes before serial/ etc so that the VT console is the boot-time
 # default.
+obj-$(CONFIG_I2C)               += i2c/
 obj-y				+= char/
 
 obj-$(CONFIG_CONNECTOR)		+= connector/
@@ -53,7 +54,6 @@ obj-$(CONFIG_USB_GADGET)	+= usb/gadget/
 obj-$(CONFIG_GAMEPORT)		+= input/gameport/
 obj-$(CONFIG_INPUT)		+= input/
 obj-$(CONFIG_I2O)		+= message/
-obj-$(CONFIG_I2C)		+= i2c/
 obj-$(CONFIG_W1)		+= w1/
 obj-$(CONFIG_HWMON)		+= hwmon/
 obj-$(CONFIG_PHONE)		+= telephony/
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 9424f62..2b0cf62 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -347,6 +347,10 @@ config AU1X00_USB_RAW
 	tristate "Au1000 USB Raw Device support"
 	depends on MIPS && MIPS_AU1000 && AU1000_USB_DEVICE=y && AU1000_USB_TTY!=y && AU1X00_USB_DEVICE
 
+config AU1XXX_CIM
+       tristate "Au1200 Camera Interface Module (CIM)"
+       depends on MIPS && SOC_AU1X00 && I2C_AU1550
+
 config SIBYTE_SB1250_DUART
 	bool "Support for BCM1xxx onchip DUART"
 	depends on MIPS && SIBYTE_SB1xxx_SOC=y
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index ecc5670..6629394 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
 obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o
 obj-$(CONFIG_AU1000_USB_TTY) += au1000_usbtty.o
 obj-$(CONFIG_AU1000_USB_RAW) += au1000_usbraw.o
+obj-$(CONFIG_AU1XXX_CIM) += au1xxx_cim.o
 obj-$(CONFIG_PPDEV) += ppdev.o
 obj-$(CONFIG_NWBUTTON) += nwbutton.o
 obj-$(CONFIG_NWFLASH) += nwflash.o
diff --git a/drivers/char/au1xxx_cameras.h b/drivers/char/au1xxx_cameras.h
new file mode 100644
index 0000000..3ecfa30
--- /dev/null
+++ b/drivers/char/au1xxx_cameras.h
@@ -0,0 +1,572 @@
+#ifndef AU1XXX_CAMERAS_H_
+#define AU1XXX_CAMERAS_H_
+
+/* List of cameras to be used with the AU1XXX Camera interface
+   Copyright 2005, Advanced Micro Devices, Inc.
+
+   This software may be used and distributed according to the terms
+   of the GNU General Public License, incorporated herein by reference.
+*/
+
+
+typedef struct cim_cmos_camera_config {
+	uint32_t frame_width;	       /* Frame Width (Pixel per Line) */
+	uint32_t frame_height;	       /* Frame Height */
+	unsigned char camera_name[32]; /* Camera Name (Display/Debug) */
+	unsigned char camera_mode[32]; /* Camera Mode(Display/Debug) */
+	uint32_t cmos_output_format;   /* CMOS Camera output */
+	uint32_t camera_resformat;     /* Camera Mode(Display/Debug) */
+	uint32_t au1200_dpsmode;       /* Data Pattern Select */
+	uint32_t au1200_baymode;       /* Mode within BAYER mode */
+	uint32_t dbdma_channel;	       /* Number of channels to be used */
+	u8 device_addr;		       /* Camera Device address */
+	uint32_t cmd_size;	       /* Number of device sub register */
+	u8 config_cmd[MAX_DEVICE_CMD][2]; /* Sub device address and values */
+} CAMERA;
+
+
+
+static CAMERA au1xxx_cameras[] = {
+	/* Omnivision OV9640 Camera 1280x960 Mode (SXGA) in "Pass Thru Mode"
+	   1.3 MP at 15 Fps
+	*/
+
+	{  1280, 960, "omnivision", "raw_SXGA", CMOS_RAW,
+	   RAW_SXGA, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	   1, 0x30, 50,
+	   {
+		   {0x12, 0x80}, {0x12, 0x05}, {0x11, 0x80},
+		   {0x3b, 0x00}, {0x33, 0x02},
+		   {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		   {0x6c, 0x40}, {0x6d, 0x30},
+		   {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		   {0x71, 0x70}, {0x74, 0x60},
+		   {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		   {0x78, 0x3a}, {0x79, 0x2e},
+		   {0x7a, 0x2a}, {0x7b, 0x22}, {0x7c, 0x04},
+		   {0x7d, 0x07}, {0x7e, 0x10},
+		   {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		   {0x82, 0x52}, {0x83, 0x60},
+		   {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		   {0x87, 0x9e}, {0x88, 0xbb},
+		   {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x4f},
+		   {0x3c, 0x40}, {0x14, 0xca},
+		   {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		   {0x26, 0xd4}, {0x27, 0x90},
+		   {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		   {0x41, 0x00}, {0x60, 0x8d},
+	   }
+	},
+
+	/* Omnivision OV9640 Camera 640x480 Mode (VGA) in "Pass Through Mode" */
+	{  640, 480, "omnivision", "raw_VGA", CMOS_RAW,
+	   RAW_VGA,CIM_CONFIG_RAW,CIM_CONFIG_BGGR,
+	   1, 0x30, 54,
+	   {
+		   {0x12, 0x80}, {0x12, 0x45}, {0x11, 0x81},
+		   {0x0c, 0x04}, {0x0d, 0x40}, {0x3b, 0x00},
+		   {0x33, 0x02},
+		   {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		   {0x6c, 0x40}, {0x6d, 0x30},
+		   {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		   {0x71, 0x70}, {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60},
+		   {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		   {0x78, 0x3a}, {0x79, 0x2e},
+		   {0x7a, 0x28}, {0x7b, 0x22}, {0x7c, 0x04},
+		   {0x7d, 0x07}, {0x7e, 0x2e},
+		   {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		   {0x82, 0x52}, {0x83, 0x60},
+		   {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		   {0x87, 0x9e}, {0x88, 0xbb},
+		   {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x4f},
+		   {0x3c, 0x40}, {0x14, 0xca},
+		   {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		   {0x26, 0xd4}, {0x27, 0x90},
+		   {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		   {0x41, 0x00}, {0x60, 0x8d},
+	   }
+	},
+
+	/* Omnivision OV9640 Camera 352x288 Mode CIF "Pass Through Mode" */
+	{  352, 288, "omnivision", "raw_CIF", CMOS_RAW,
+	   RAW_CIF, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	   1, 0x30, 54,
+	   {
+		   {0x12, 0x80}, {0x12, 0x25}, {0x11, 0x80},
+		   {0x0c, 0x04}, {0x0d, 0x40}, {0x3b, 0x00},
+		   {0x33, 0x02},
+		   {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		   {0x6c, 0x40}, {0x6d, 0x30},
+		   {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		   {0x71, 0x70}, {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60},
+		   {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		   {0x78, 0x3a}, {0x79, 0x2e},
+		   {0x7a, 0x28}, {0x7b, 0x22}, {0x7c, 0x04},
+		   {0x7d, 0x07}, {0x7e, 0x10},
+		   {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		   {0x82, 0x52}, {0x83, 0x60},
+		   {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		   {0x87, 0x9e}, {0x88, 0xbb},
+		   {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x4f},
+		   {0x3c, 0x40}, {0x14, 0xca},
+		   {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		   {0x26, 0xd4}, {0x27, 0x90},
+		   {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		   {0x41, 0x00}, {0x60, 0x8d},
+		}
+
+	},
+
+	/* Omnivision OV9640 Camera 320x240 Mode (QVGA) in "Pass Through Mode" */
+	{ 320, 240, "omnivision", "raw_QVGA", CMOS_RAW,
+	  RAW_QVGA, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	  1, 0x30, 54,
+	  {
+		  {0x12, 0x80}, {0x12, 0x15}, {0x11, 0x83},
+		  {0x0c, 0x04}, {0x0d, 0xc0}, {0x3b, 0x00},
+		  {0x33, 0x02},
+		  {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		  {0x6c, 0x40}, {0x6d, 0x30},
+		  {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		  {0x71, 0x70}, {0x72, 0x70}, {0x73, 0x70},
+		  {0x74, 0x60},
+		  {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		  {0x78, 0x3a}, {0x79, 0x2e},
+		  {0x7a, 0x28}, {0x7b, 0x22}, {0x7c, 0x04},
+		  {0x7d, 0x07}, {0x7e, 0x10},
+		  {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		  {0x82, 0x52}, {0x83, 0x60},
+		  {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		  {0x87, 0x9e}, {0x88, 0xbb},
+		  {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x4f},
+		  {0x3c, 0x40}, {0x14, 0xca},
+		  {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		  {0x26, 0xd4}, {0x27, 0x90},
+		  {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		  {0x41, 0x00}, {0x60, 0x8d},
+	  }
+	},
+
+	/* Omnivision OV9640 Camera 176x144 QCIF Mode "Pass Through Mode" */
+	{ 176, 144, "omnivision", "raw_QCIF", CMOS_RAW,
+	  RAW_QCIF, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	  1, 0x30, 54,
+	  {
+		  {0x12, 0x80}, {0x12, 0x0D}, {0x11, 0x80},
+		  {0x0c, 0x04}, {0x0d, 0xc0}, {0x3b, 0x00},
+		  {0x33, 0x02},
+		  {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		  {0x6c, 0x40}, {0x6d, 0x30},
+		  {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		  {0x71, 0x70}, {0x72, 0x70}, {0x73, 0x70},
+		  {0x74, 0x60},
+		  {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		  {0x78, 0x3a}, {0x79, 0x2e},
+		  {0x7a, 0x28}, {0x7b, 0x22}, {0x7c, 0x04},
+		  {0x7d, 0x07}, {0x7e, 0x10},
+		  {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		  {0x82, 0x52}, {0x83, 0x60},
+		  {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		  {0x87, 0x9e}, {0x88, 0xbb},
+		  {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x6f},
+		  {0x3c, 0x60}, {0x14, 0xca},
+		  {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		  {0x26, 0xd4}, {0x27, 0x90},
+		  {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		  {0x41, 0x00}, {0x60, 0x8d},
+	  }
+	},
+
+
+	/* Omnivision OV9640 Camera 1280x960 Mode (SXGA) in BAYER Mode (Planar) */
+	{  1280, 960, "omnivision", "bayer_SXGA", CMOS_RAW,
+	   BAYER_SXGA, CIM_CONFIG_BAYER, CIM_CONFIG_BGGR,
+	   3, 0x30, 50,
+	   {
+		   {0x12, 0x80}, {0x12, 0x05}, {0x11, 0x80},
+		   {0x3b, 0x00}, {0x33, 0x02},
+		   {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		   {0x6c, 0x40}, {0x6d, 0x30},
+		   {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		   {0x71, 0x70}, {0x74, 0x60},
+		   {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		   {0x78, 0x3a}, {0x79, 0x2e},
+		   {0x7a, 0x2a}, {0x7b, 0x22}, {0x7c, 0x04},
+		   {0x7d, 0x07}, {0x7e, 0x10},
+		   {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		   {0x82, 0x52}, {0x83, 0x60},
+		   {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		   {0x87, 0x9e}, {0x88, 0xbb},
+		   {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x4f},
+		   {0x3c, 0x40}, {0x14, 0xca},
+		   {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		   {0x26, 0xd4}, {0x27, 0x90},
+		   {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		   {0x41, 0x00}, {0x60, 0x8d},
+		}
+	},
+
+	/* Omnivision OV9640 Camera 640x480 Mode (VGA) in BAYER Mode (Planar) */
+	{  640, 480, "omnivision", "bayer_VGA", CMOS_RAW,
+	   BAYER_VGA, CIM_CONFIG_BAYER, CIM_CONFIG_BGGR,
+	   3, 0x30, 54,
+	   {
+		   {0x12, 0x80}, {0x12, 0x45}, {0x11, 0x81},
+		   {0x0c, 0x04}, {0x0d, 0x40}, {0x3b, 0x00},
+		   {0x33, 0x02},
+		   {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		   {0x6c, 0x40}, {0x6d, 0x30},
+		   {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		   {0x71, 0x70}, {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60},
+		   {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		   {0x78, 0x3a}, {0x79, 0x2e},
+		   {0x7a, 0x28}, {0x7b, 0x22}, {0x7c, 0x04},
+		   {0x7d, 0x07}, {0x7e, 0x2e},
+		   {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		   {0x82, 0x52}, {0x83, 0x60},
+		   {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		   {0x87, 0x9e}, {0x88, 0xbb},
+		   {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x4f},
+		   {0x3c, 0x40}, {0x14, 0xca},
+		   {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		   {0x26, 0xd4}, {0x27, 0x90},
+		   {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		   {0x41, 0x00}, {0x60, 0x8d},
+		}
+	},
+
+	/* Omnivision OV9640 Camera 352x288 CIF Mode in BAYER Mode (Planar) */
+	{  352, 288, "omnivision", "bayer_CIF", CMOS_RAW,
+	   BAYER_CIF, CIM_CONFIG_BAYER, CIM_CONFIG_BGGR,
+	   3, 0x30, 54,
+	   {
+		   {0x12, 0x80}, {0x12, 0x25}, {0x11, 0x80},
+		   {0x0c, 0x04}, {0x0d, 0x40}, {0x3b, 0x00},
+		   {0x33, 0x02},
+		   {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		   {0x6c, 0x40}, {0x6d, 0x30},
+		   {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		   {0x71, 0x70}, {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60},
+		   {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		   {0x78, 0x3a}, {0x79, 0x2e},
+		   {0x7a, 0x28}, {0x7b, 0x22}, {0x7c, 0x04},
+		   {0x7d, 0x07}, {0x7e, 0x10},
+		   {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		   {0x82, 0x52}, {0x83, 0x60},
+		   {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		   {0x87, 0x9e}, {0x88, 0xbb},
+		   {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x4f},
+		   {0x3c, 0x40}, {0x14, 0xca},
+		   {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		   {0x26, 0xd4}, {0x27, 0x90},
+		   {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		   {0x41, 0x00}, {0x60, 0x8d},
+		}
+	},
+
+	/* Omnivision OV9640 Camera 320x240 Mode (QVGA) in BAYER Mode (Planar) */
+	{  320, 240, "omnivision", "bayer_QVGA", CMOS_RAW,
+	   BAYER_QVGA, CIM_CONFIG_BAYER, CIM_CONFIG_BGGR,
+	   3, 0x30, 54,
+	   {
+		   {0x12, 0x80}, {0x12, 0x15}, {0x11, 0x83},
+		   {0x0c, 0x04}, {0x0d, 0xc0}, {0x3b, 0x00},
+		   {0x33, 0x02},
+		   {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		   {0x6c, 0x40}, {0x6d, 0x30},
+		   {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		   {0x71, 0x70}, {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60},
+		   {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		   {0x78, 0x3a}, {0x79, 0x2e},
+		   {0x7a, 0x28}, {0x7b, 0x22}, {0x7c, 0x04},
+		   {0x7d, 0x07}, {0x7e, 0x10},
+		   {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		   {0x82, 0x52}, {0x83, 0x60},
+		   {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		   {0x87, 0x9e}, {0x88, 0xbb},
+		   {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x4f},
+		   {0x3c, 0x40}, {0x14, 0xca},
+		   {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		   {0x26, 0xd4}, {0x27, 0x90},
+		   {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		   {0x41, 0x00}, {0x60, 0x8d},
+		}
+	},
+
+	/* Omnivision OV9640 Camera 640x480 Mode (QCIF) in BAYER Mode (Planar) */
+	{  176, 144, "omnivision", "bayer_QCIF", CMOS_RAW,
+	   BAYER_QCIF, CIM_CONFIG_BAYER, CIM_CONFIG_BGGR,
+	   3, 0x30, 54,
+	   {
+		   {0x12, 0x80}, {0x12, 0x0D}, {0x11, 0x80},
+		   {0x0c, 0x04}, {0x0d, 0xc0}, {0x3b, 0x00},
+		   {0x33, 0x02},
+		   {0x37, 0x02}, {0x38, 0x13}, {0x39, 0xf0},
+		   {0x6c, 0x40}, {0x6d, 0x30},
+		   {0x6e, 0x4b}, {0x6f, 0x60}, {0x70, 0x70},
+		   {0x71, 0x70}, {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60},
+		   {0x75, 0x60}, {0x76, 0x50}, {0x77, 0x48},
+		   {0x78, 0x3a}, {0x79, 0x2e},
+		   {0x7a, 0x28}, {0x7b, 0x22}, {0x7c, 0x04},
+		   {0x7d, 0x07}, {0x7e, 0x10},
+		   {0x7f, 0x28}, {0x80, 0x36}, {0x81, 0x44},
+		   {0x82, 0x52}, {0x83, 0x60},
+		   {0x84, 0x6c}, {0x85, 0x78}, {0x86, 0x8c},
+		   {0x87, 0x9e}, {0x88, 0xbb},
+		   {0x89, 0xd2}, {0x8a, 0xe6}, {0x0f, 0x6f},
+		   {0x3c, 0x60}, {0x14, 0xca},
+		   {0x42, 0x89}, {0x24, 0x78}, {0x25, 0x68},
+		   {0x26, 0xd4}, {0x27, 0x90},
+		   {0x2a, 0x00}, {0x2b, 0x00}, {0x3d, 0x80},
+		   {0x41, 0x00}, {0x60, 0x8d},
+	   }
+	},
+
+	/* Omnivision OV9640 Camera 1280x960 Mode (SXGA) in YCbCr Camera pass Thru Mode */
+	{  1280, 960, "omnivision", "YCbCr_SXGA", CMOS_CCIR656,
+	   YCbCr_SXGA_RAW, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	   1, 0x30, 115,
+	   {
+		   {0x12, 0x80}, {0x11, 0x80}, {0x12, 0x00},
+		   {0x13, 0xA8}, {0x01, 0x80},
+		   {0x02, 0x80}, {0x04, 0x40}, {0x0C, 0x04},
+		   {0x0D, 0xC0}, {0x0E, 0x81},
+		   {0x0f, 0x4F}, {0x14, 0x4A}, {0x16, 0x02},
+		   {0x1B, 0x01}, {0x24, 0x70},
+		   {0x25, 0x68}, {0x26, 0xD3}, {0x27, 0x90},
+		   {0x2A, 0x00}, {0x2B, 0x00},
+		   {0x33, 0x28}, {0x37, 0x02}, {0x38, 0x13},
+		   {0x39, 0xF0}, {0x3A, 0x00},
+		   {0x3B, 0x01}, {0x3C, 0x46}, {0x3D, 0x90},
+		   {0x3E, 0x02}, {0x3F, 0xF2},
+		   {0x41, 0x02}, {0x42, 0xC9}, {0x43, 0xF0},
+		   {0x44, 0x10}, {0x45, 0x6C},
+		   {0x46, 0x6C}, {0x47, 0x44}, {0x48, 0x44},
+		   {0x49, 0x03}, {0x4F, 0x50},
+		   {0x50, 0x43}, {0x51, 0x0D}, {0x52, 0x19},
+		   {0x53, 0x4C}, {0x54, 0x65},
+		   {0x59, 0x49}, {0x5A, 0x94}, {0x5B, 0x46},
+		   {0x5C, 0x84}, {0x5D, 0x5C},
+		   {0x5E, 0x08}, {0x5F, 0x00}, {0x60, 0x14},
+		   {0x61, 0xCE}, {0x62, 0x70},
+		   {0x63, 0x00}, {0x64, 0x04}, {0x65, 0x00},
+		   {0x66, 0x00}, {0x69, 0x00},
+		   {0x6A, 0x3E}, {0x6B, 0x3F}, {0x6C, 0x40},
+		   {0x6D, 0x30}, {0x6E, 0x4B},
+		   {0x6F, 0x60}, {0x70, 0x70}, {0x71, 0x70},
+		   {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x70}, {0x75, 0x60}, {0x76, 0x50},
+		   {0x77, 0x48}, {0x78, 0x3A},
+		   {0x79, 0x2E}, {0x7A, 0x28}, {0x7B, 0x22},
+		   {0x7C, 0x04}, {0x7D, 0x07},
+		   {0x7E, 0x10}, {0x7F, 0x28}, {0x80, 0x36},
+		   {0x81, 0x44}, {0x82, 0x52},
+		   {0x83, 0x60}, {0x84, 0x6C}, {0x85, 0x78},
+		   {0x86, 0x8C}, {0x87, 0x9E},
+		   {0x88, 0xBB}, {0x89, 0xD2}, {0x8A, 0xE6},
+		   {0x13, 0xAF}, {0x13, 0x8D},
+		   {0x01, 0x80}, {0x02, 0x80}, {0x42, 0xC9},
+		   {0x16, 0x02}, {0x43, 0xF0},
+		   {0x44, 0x10}, {0x45, 0x20}, {0x46, 0x20},
+		   {0x47, 0x20}, {0x48, 0x20},
+		   {0x59, 0x17}, {0x5A, 0x71}, {0x5B, 0x56},
+		   {0x5C, 0x74}, {0x5D, 0x68},
+		   {0x5e, 0x10}, {0x5f, 0x00}, {0x60, 0x14},
+		   {0x61, 0xCE}, {0x13, 0x8F},
+	   }
+	},
+
+	/* Omnivision OV9640 Camera 640x480 Mode (SXGA) in YCbCr Camera pass Thru Mode */
+	{  640, 480, "omnivision", "YCbCr_VGA_raw", CMOS_CCIR656,
+	   YCbCr_VGA_RAW, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	   1, 0x30, 94,
+	   {
+		   {0x12, 0x80}, {0x11, 0x81}, {0x12, 0x40},
+		   {0x13, 0xA8}, {0x01, 0x80},
+		   {0x02, 0x80}, {0x04, 0x40}, {0x0C, 0x04},
+		   {0x0D, 0xC0}, {0x0E, 0x81},
+		   {0x0f, 0x4F}, {0x14, 0x4A}, {0x16, 0x02},
+		   {0x1B, 0x01}, {0x24, 0x70},
+		   {0x25, 0x68}, {0x26, 0xD3}, {0x27, 0x90},
+		   {0x2A, 0x00}, {0x2B, 0x00},
+		   {0x33, 0x02}, {0x37, 0x02}, {0x38, 0x13},
+		   {0x39, 0xF0}, {0x3A, 0x00},
+		   {0x3B, 0x01}, {0x3C, 0x46}, {0x3D, 0x90},
+		   {0x3E, 0x02}, {0x3F, 0xF2},
+		   {0x41, 0x02}, {0x42, 0xC9}, {0x43, 0xF0},
+		   {0x44, 0x10}, {0x45, 0x6C},
+		   {0x46, 0x6C}, {0x47, 0x44}, {0x48, 0x44},
+		   {0x49, 0x03}, {0x4F, 0x50},
+		   {0x50, 0x43}, {0x51, 0x0D}, {0x52, 0x19},
+		   {0x53, 0x4C}, {0x54, 0x65},
+		   {0x59, 0x49}, {0x5A, 0x94}, {0x5B, 0x46},
+		   {0x5C, 0x84}, {0x5D, 0x5C},
+		   {0x5E, 0x08}, {0x5F, 0x00}, {0x60, 0x14},
+		   {0x61, 0xCE}, {0x62, 0x70},
+		   {0x63, 0x00}, {0x64, 0x04}, {0x65, 0x00},
+		   {0x66, 0x00}, {0x69, 0x00},
+		   {0x6A, 0x3E}, {0x6B, 0x3F}, {0x6C, 0x40},
+		   {0x6D, 0x30}, {0x6E, 0x4B},
+		   {0x6F, 0x60}, {0x70, 0x70}, {0x71, 0x70},
+		   {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60}, {0x75, 0x60}, {0x76, 0x50},
+		   {0x77, 0x48}, {0x78, 0x3A},
+		   {0x79, 0x2E}, {0x7A, 0x28}, {0x7B, 0x22},
+		   {0x7C, 0x04}, {0x7D, 0x07},
+		   {0x7E, 0x10}, {0x7F, 0x28}, {0x80, 0x36},
+		   {0x81, 0x44}, {0x82, 0x52},
+		   {0x83, 0x60}, {0x84, 0x6C}, {0x85, 0x78},
+		   {0x86, 0x8C}, {0x87, 0x9E},
+		   {0x88, 0xBB}, {0x89, 0xD2}, {0x8A, 0xE6},
+		   {0x13, 0xAF},
+	   }
+	},
+
+	/* Omnivision OV9640 Camera 352x288 Mode (CIF) in YCbCr Camera pass Thru Mode */
+	{  352, 288, "omnivision", "YCbCr_CIF_raw", CMOS_CCIR656,
+	   YCbCr_CIF_RAW, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	   1, 0x30, 94,
+	   {
+		   {0x12, 0x80}, {0x11, 0x81}, {0x12, 0x20},
+		   {0x13, 0xA8}, {0x01, 0x80},
+		   {0x02, 0x80}, {0x04, 0x40}, {0x0C, 0x04},
+		   {0x0D, 0xC0}, {0x0E, 0x81},
+		   {0x0f, 0x4F}, {0x14, 0x4A}, {0x16, 0x02},
+		   {0x1B, 0x01}, {0x24, 0x70},
+		   {0x25, 0x68}, {0x26, 0xD3}, {0x27, 0x90},
+		   {0x2A, 0x00}, {0x2B, 0x00},
+		   {0x33, 0x02}, {0x37, 0x02}, {0x38, 0x13},
+		   {0x39, 0xF0}, {0x3A, 0x00},
+		   {0x3B, 0x01}, {0x3C, 0x46}, {0x3D, 0x90},
+		   {0x3E, 0x02}, {0x3F, 0xF2},
+		   {0x41, 0x02}, {0x42, 0xC9}, {0x43, 0xF0},
+		   {0x44, 0x10}, {0x45, 0x6C},
+		   {0x46, 0x6C}, {0x47, 0x44}, {0x48, 0x44},
+		   {0x49, 0x03}, {0x4F, 0x50},
+		   {0x50, 0x43}, {0x51, 0x0D}, {0x52, 0x19},
+		   {0x53, 0x4C}, {0x54, 0x65},
+		   {0x59, 0x49}, {0x5A, 0x94}, {0x5B, 0x46},
+		   {0x5C, 0x84}, {0x5D, 0x5C},
+		   {0x5E, 0x08}, {0x5F, 0x00}, {0x60, 0x14},
+		   {0x61, 0xCE}, {0x62, 0x70},
+		   {0x63, 0x00}, {0x64, 0x04}, {0x65, 0x00},
+		   {0x66, 0x00}, {0x69, 0x00},
+		   {0x6A, 0x3E}, {0x6B, 0x3F}, {0x6C, 0x40},
+		   {0x6D, 0x30}, {0x6E, 0x4B},
+		   {0x6F, 0x60}, {0x70, 0x70}, {0x71, 0x70},
+		   {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60}, {0x75, 0x60}, {0x76, 0x50},
+		   {0x77, 0x48}, {0x78, 0x3A},
+		   {0x79, 0x2E}, {0x7A, 0x28}, {0x7B, 0x22},
+		   {0x7C, 0x04}, {0x7D, 0x07},
+		   {0x7E, 0x10}, {0x7F, 0x28}, {0x80, 0x36},
+		   {0x81, 0x44}, {0x82, 0x52},
+		   {0x83, 0x60}, {0x84, 0x6C}, {0x85, 0x78},
+		   {0x86, 0x8C}, {0x87, 0x9E},
+		   {0x88, 0xBB}, {0x89, 0xD2}, {0x8A, 0xE6},
+		   {0x13, 0xAF},
+	   }
+	},
+
+	/* Omnivision OV9640 Camera 320x240 Mode QVGA in YCbCr Camera pass Thru Mode */
+	{ 320, 240, "omnivision", "YCbCr_QVGA_raw", CMOS_CCIR656,
+	  YCbCr_QVGA_RAW, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	  1, 0x30, 94,
+	  {
+		  {0x12, 0x80}, {0x11, 0x81}, {0x12, 0x10},
+		  {0x13, 0xA8}, {0x01, 0x80},
+		  {0x02, 0x80}, {0x04, 0x40}, {0x0C, 0x04},
+		  {0x0D, 0xC0}, {0x0E, 0x81},
+		  {0x0f, 0x4F}, {0x14, 0x4A}, {0x16, 0x02},
+		  {0x1B, 0x01}, {0x24, 0x70},
+		  {0x25, 0x68}, {0x26, 0xD3}, {0x27, 0x90},
+		  {0x2A, 0x00}, {0x2B, 0x00},
+		  {0x33, 0x02}, {0x37, 0x02}, {0x38, 0x13},
+		  {0x39, 0xF0}, {0x3A, 0x00},
+		  {0x3B, 0x01}, {0x3C, 0x46}, {0x3D, 0x90},
+		  {0x3E, 0x02}, {0x3F, 0xF2},
+		  {0x41, 0x02}, {0x42, 0xC9}, {0x43, 0xF0},
+		  {0x44, 0x10}, {0x45, 0x6C},
+		  {0x46, 0x6C}, {0x47, 0x44}, {0x48, 0x44},
+		  {0x49, 0x03}, {0x4F, 0x50},
+		  {0x50, 0x43}, {0x51, 0x0D}, {0x52, 0x19},
+		  {0x53, 0x4C}, {0x54, 0x65},
+		  {0x59, 0x49}, {0x5A, 0x94}, {0x5B, 0x46},
+		  {0x5C, 0x84}, {0x5D, 0x5C},
+		  {0x5E, 0x08}, {0x5F, 0x00}, {0x60, 0x14},
+		  {0x61, 0xCE}, {0x62, 0x70},
+		  {0x63, 0x00}, {0x64, 0x04}, {0x65, 0x00},
+		  {0x66, 0x00}, {0x69, 0x00},
+		  {0x6A, 0x3E}, {0x6B, 0x3F}, {0x6C, 0x40},
+		  {0x6D, 0x30}, {0x6E, 0x4B},
+		  {0x6F, 0x60}, {0x70, 0x70}, {0x71, 0x70},
+		  {0x72, 0x70}, {0x73, 0x70},
+		  {0x74, 0x60}, {0x75, 0x60}, {0x76, 0x50},
+		  {0x77, 0x48}, {0x78, 0x3A},
+		  {0x79, 0x2E}, {0x7A, 0x28}, {0x7B, 0x22},
+		  {0x7C, 0x04}, {0x7D, 0x07},
+		  {0x7E, 0x10}, {0x7F, 0x28}, {0x80, 0x36},
+		  {0x81, 0x44}, {0x82, 0x52},
+		  {0x83, 0x60}, {0x84, 0x6C}, {0x85, 0x78},
+		  {0x86, 0x8C}, {0x87, 0x9E},
+		  {0x88, 0xBB}, {0x89, 0xD2}, {0x8A, 0xE6},
+		  {0x13, 0xAF},
+	  }
+	},
+
+	/* Omnivision OV9640 Camera 176x144 Mode (QCIF) in YCbCr Camera pass Thru Mode */
+	{  176, 144, "omnivision", "YCbCr_QCIF_raw", CMOS_CCIR656,
+	   YCbCr_QCIF_RAW, CIM_CONFIG_RAW, CIM_CONFIG_BGGR,
+	   1, 0x30, 94,
+	   {
+		   {0x12, 0x80}, {0x11, 0x81}, {0x12, 0x08},
+		   {0x13, 0xA8}, {0x01, 0x80},
+		   {0x02, 0x80}, {0x04, 0x40}, {0x0C, 0x04},
+		   {0x0D, 0xC0}, {0x0E, 0x81},
+		   {0x0f, 0x4F}, {0x14, 0x4A}, {0x16, 0x02},
+		   {0x1B, 0x01}, {0x24, 0x70},
+		   {0x25, 0x68}, {0x26, 0xD3}, {0x27, 0x90},
+		   {0x2A, 0x00}, {0x2B, 0x00},
+		   {0x33, 0x02}, {0x37, 0x02}, {0x38, 0x13},
+		   {0x39, 0xF0}, {0x3A, 0x00},
+		   {0x3B, 0x01}, {0x3C, 0x46}, {0x3D, 0x90},
+		   {0x3E, 0x02}, {0x3F, 0xF2},
+		   {0x41, 0x02}, {0x42, 0xC9}, {0x43, 0xF0},
+		   {0x44, 0x10}, {0x45, 0x6C},
+		   {0x46, 0x6C}, {0x47, 0x44}, {0x48, 0x44},
+		   {0x49, 0x03}, {0x4F, 0x50},
+		   {0x50, 0x43}, {0x51, 0x0D}, {0x52, 0x19},
+		   {0x53, 0x4C}, {0x54, 0x65},
+		   {0x59, 0x49}, {0x5A, 0x94}, {0x5B, 0x46},
+		   {0x5C, 0x84}, {0x5D, 0x5C},
+		   {0x5E, 0x08}, {0x5F, 0x00}, {0x60, 0x14},
+		   {0x61, 0xCE}, {0x62, 0x70},
+		   {0x63, 0x00}, {0x64, 0x04}, {0x65, 0x00},
+		   {0x66, 0x00}, {0x69, 0x00},
+		   {0x6A, 0x3E}, {0x6B, 0x3F}, {0x6C, 0x40},
+		   {0x6D, 0x30}, {0x6E, 0x4B},
+		   {0x6F, 0x60}, {0x70, 0x70}, {0x71, 0x70},
+		   {0x72, 0x70}, {0x73, 0x70},
+		   {0x74, 0x60}, {0x75, 0x60}, {0x76, 0x50},
+		   {0x77, 0x48}, {0x78, 0x3A},
+		   {0x79, 0x2E}, {0x7A, 0x28}, {0x7B, 0x22},
+		   {0x7C, 0x04}, {0x7D, 0x07},
+		   {0x7E, 0x10}, {0x7F, 0x28}, {0x80, 0x36},
+		   {0x81, 0x44}, {0x82, 0x52},
+		   {0x83, 0x60}, {0x84, 0x6C}, {0x85, 0x78},
+		   {0x86, 0x8C}, {0x87, 0x9E},
+		   {0x88, 0xBB}, {0x89, 0xD2}, {0x8A, 0xE6},
+		   {0x13, 0xAF},
+	   }
+	}
+};
+
+#define CAMERA_COUNT (sizeof(au1xxx_cameras) / sizeof(au1xxx_cameras[0]))
+
+#endif
diff --git a/drivers/char/au1xxx_cim.c b/drivers/char/au1xxx_cim.c
new file mode 100644
index 0000000..0890986
--- /dev/null
+++ b/drivers/char/au1xxx_cim.c
@@ -0,0 +1,647 @@
+/*
+ *  Alchemy Camera Interface (CIM) driver
+ *
+ * Copyright 2004 Advanced Micro Devices, Inc
+ *
+ *  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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE        LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/irq.h>
+#include <asm/mach-au1x00/au1xxx_cim.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+#include <asm/mman.h>
+
+#ifdef CONFIG_MIPS_PB1200
+#include <asm/mach-pb1x00/pb1200.h>
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#include <asm/mach-db1x00/db1200.h>
+#endif
+
+/*
+  Camera Interface Driver will always work in DBDMA Mode.
+  PIO Mode will result in OverFlow Error
+*/
+
+/*
+ * Global Variables
+ */
+
+#define CIM_NAME               "au1xxx_cim"
+#define CIM_MAJOR              238
+#define VERSION                "1.2"
+
+/* Number of DMA channel used by CIM interface */
+#define MAX_DBDMA_CHANNEL       3
+
+/*Max Command Send over SMbus to configure external camera */
+#define MAX_DEVICE_CMD         115
+
+/* Number of descriptor used */
+#define NUM_DBDMA_DESCRIPTORS   1
+#define MAX_FRAME_SIZE          (1280*960)
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINTK(fmt,args...) \
+printk(KERN_DEBUG "%s: " fmt,__FUNCTION__, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+static uint32_t nInterruptDoneNumber;
+static uint32_t ciminterruptcheck;
+static uint32_t prev_mode;
+static uint32_t DBDMA_SourceID[] =
+    { DSCR_CMD0_CIM_RXA, DSCR_CMD0_CIM_RXB, DSCR_CMD0_CIM_RXC };
+static void *mem_buf;
+
+extern int pb1550_wm_codec_write(u8, u8, u8);
+
+static volatile AU1200_CIM *au1200_cim = (AU1200_CIM *) CIM_BASE_ADDRESS;
+
+/* Get the array of camera modes */
+#include "au1xxx_cameras.h"
+
+typedef struct cim_camera_runtime {
+	chan_tab_t **ChannelArray[MAX_DBDMA_CHANNEL];
+	void *memory[MAX_DBDMA_CHANNEL]	;
+	uint32_t nTransferSize[MAX_DBDMA_CHANNEL];
+	CAMERA *cmos_camera;
+} CAMERA_RUNTIME;
+
+static CAMERA_RUNTIME cam_base;
+static CAMERA *OrigCimArryPtr = au1xxx_cameras;
+
+static int
+find_mode_index(uint32_t res_format)
+{
+	int i;
+	CAMERA_RUNTIME *findex;
+
+	findex = &cam_base;
+	findex->cmos_camera = OrigCimArryPtr;
+
+	for (i = 0; i < CAMERA_COUNT; i++) {
+		if (res_format == (findex->cmos_camera->camera_resformat)) {
+
+			return i;
+		}
+		(findex->cmos_camera)++;
+	}
+	printk(KERN_ERR " Au1xxx_CIM: ERROR: Camera Index Failed \n");
+	return -1;
+}
+
+static void
+Cim_DDMA_Done_Interrupt(int irq, void *param, struct pt_regs *regs)
+{
+	nInterruptDoneNumber++;
+}
+
+static int
+Capture_Image(void)
+{
+	au1200_cim->capture = 0;
+	au1200_cim->capture = CIM_CAPTURE_CLR;
+	au1200_cim->capture = CIM_CAPTURE_SCE;
+	return 1;
+}
+
+static void
+Camera_pwr_down(void)
+{
+	/* Power shut to Camera */
+	bcsr->board |= BCSR_BOARD_CAMPWR;
+}
+
+static void
+Camera_pwr_up(void)
+{
+	bcsr->board &= ~BCSR_BOARD_CAMPWR;
+}
+
+static void
+CIM_Cleanup(CAMERA_RUNTIME * cim_cleanup)
+{
+	CAMERA *cim_ptr;
+	uint32_t frame_size;
+	int i;
+	cim_ptr = cim_cleanup->cmos_camera;
+	frame_size = (cim_ptr->frame_width) * (cim_ptr->frame_height);
+
+	for (i = 0; i < cim_ptr->dbdma_channel; i++) {
+		if (cim_cleanup->ChannelArray[i]) {
+
+			au1xxx_dbdma_stop((u32) (cim_cleanup->ChannelArray[i]));
+			au1xxx_dbdma_reset((u32)
+					   (cim_cleanup->ChannelArray[i]));
+			au1xxx_dbdma_chan_free((u32)
+					       (cim_cleanup->ChannelArray[i]));
+		}
+
+		if ((cim_cleanup->memory[i]) != NULL) {
+			free_pages((unsigned long)cim_cleanup->memory[i],
+				   get_order(frame_size));
+		}
+	}
+
+}
+
+static int
+Camera_Config(CAMERA_RUNTIME * cim_config)
+{
+	uint32_t nAckCount = 0;
+	int i, ErrorCheck;
+	ErrorCheck = 0;
+	uint32_t nCameraModeConfig = 0;
+	uint32_t nClearSetInterrupt = 0;
+	CAMERA *cim_config_ptr;
+
+	cim_config_ptr = cim_config->cmos_camera;
+
+	/* To get rid of hard coded number from Transfer Size */
+	/* Now transfer size will be calulated on the on the fly */
+	/*******************************************************************
+		    In YCbCr 4:2:2 data size is twice the frame size
+		     Y=Frame Size
+		     Cb=Frame Size/2
+		     Cr=Frame Size/2
+		     Total size of Frame: Y+Cb+Cr effectively 2*FrameSize
+	*********************************************************************/
+
+	if ((cim_config_ptr->au1200_dpsmode) == CIM_CONFIG_RAW) {
+		if (cim_config_ptr->cmos_output_format == CMOS_CCIR656) {
+
+			cim_config->nTransferSize[0] =
+			    2 * (cim_config_ptr->frame_width) *
+			    (cim_config_ptr->frame_height);
+			DPRINTK("FIFO-A YCbCR Transfer Size in Raw mode %d \n",
+				cim_config->nTransferSize[0]);
+		} else {
+			cim_config->nTransferSize[0] =
+			    (cim_config_ptr->frame_width) *
+			    (cim_config_ptr->frame_height);
+			DPRINTK("FIFO-A Transfer Size in Raw mode %d \n",
+				cim_config->nTransferSize[0]);
+		}
+		cim_config->memory[0] = mem_buf;
+	} else if ((cim_config_ptr->au1200_dpsmode) == CIM_CONFIG_BAYER) {
+		/* FIFO A Hold Red Pixels which is Total Pixels/4 */
+		cim_config->nTransferSize[0] =
+			((cim_config_ptr->frame_width) *
+			 (cim_config_ptr->frame_height)) / 4;
+		cim_config->nTransferSize[1] =
+			((cim_config_ptr->frame_width) *
+			 (cim_config_ptr->frame_height)) / 2;
+		cim_config->nTransferSize[2] =
+			((cim_config_ptr->frame_width) *
+			 (cim_config_ptr->frame_height)) / 4;
+
+		cim_config->memory[0] = mem_buf;
+		cim_config->memory[1] = mem_buf + cim_config->nTransferSize[0];
+		cim_config->memory[2] = mem_buf + cim_config->nTransferSize[0]
+			+ cim_config->nTransferSize[1];
+	} else {
+		cim_config->nTransferSize[0] =
+		    ((cim_config_ptr->frame_width) *
+		     (cim_config_ptr->frame_height));
+		cim_config->nTransferSize[1] =
+			((cim_config_ptr->frame_width) *
+			 (cim_config_ptr->frame_height)) / 2;
+		cim_config->nTransferSize[2] =
+			((cim_config_ptr->frame_width) *
+			 (cim_config_ptr->frame_height)) / 2;
+
+		cim_config->memory[0] = mem_buf;
+		cim_config->memory[1] = mem_buf + cim_config->nTransferSize[0];
+		cim_config->memory[2] = mem_buf + cim_config->nTransferSize[0]
+			+ cim_config->nTransferSize[1];
+
+	}
+
+	for (i = 0; i < cim_config->cmos_camera->dbdma_channel; i++) {
+		/* Allocate Channel */
+		cim_config->ChannelArray[i] =
+			(chan_tab_t **) au1xxx_dbdma_chan_alloc(DBDMA_SourceID[i],
+							    DSCR_CMD0_ALWAYS,
+							    Cim_DDMA_Done_Interrupt,
+							    (void *)NULL);
+
+		if (cim_config->ChannelArray[i] != NULL) {
+			au1xxx_dbdma_set_devwidth((u32)
+						  (cim_config->ChannelArray[i]),
+						  32);
+			if (au1xxx_dbdma_ring_alloc
+			    ((u32) (cim_config->ChannelArray[i]), 16) == 0) {
+				printk(KERN_ERR \
+				       "Failed to allocate a DDMA channel\n");
+
+				ErrorCheck++;
+				goto error_ch_alloc;
+			}
+			au1xxx_dbdma_start((u32) (cim_config->ChannelArray[i]));
+			int j = 0;
+			for (j = 0; j < NUM_DBDMA_DESCRIPTORS; j++) {
+
+				if (!au1xxx_dbdma_put_dest
+				    ((u32) (cim_config->ChannelArray[i]),
+				     cim_config->memory[i],
+				     cim_config->nTransferSize[i])) {
+					printk(KERN_ERR \
+					       "Error while putting descriptor on DBDMA channnel.\n");
+				}
+			}
+
+		} else {
+			ErrorCheck++;
+			goto error_ch_alloc;
+		}
+
+	}
+
+	for (i = 0; i < cim_config_ptr->cmd_size; i++) {
+		while ((pb1550_wm_codec_write(cim_config_ptr->device_addr,
+					      cim_config_ptr->config_cmd[i][0],
+					      cim_config_ptr->
+					      config_cmd[i][1]) != 1)
+		       && (nAckCount < 50)) {
+			nAckCount++;
+		}
+		if (i == 0) {
+			mdelay(1);
+		}
+
+	}
+	if (nAckCount == 50) {
+		printk(KERN_ERR "External CMOS Camera Not Present or not properly connected !!!! !\n");
+		goto error_ch_alloc;
+	}
+
+	au1200_cim->enable = CIM_ENABLE_EN;
+	au1200_cim->capture = CIM_CAPTURE_CLR;
+
+	if (cim_config_ptr->au1200_dpsmode == 1) {
+		nCameraModeConfig =
+			CIM_CONFIG_DPS_N(cim_config_ptr->
+					 au1200_dpsmode) | CIM_CONFIG_FS |
+			CIM_CONFIG_BAY_N(cim_config_ptr->
+					 au1200_baymode) | CIM_CONFIG_BYT |
+			CIM_CONFIG_LEN(CIM_CONFIG_LEN_10BIT);
+	} else if (cim_config_ptr->au1200_dpsmode == 0) {
+		nCameraModeConfig =
+			CIM_CONFIG_DPS_N(cim_config_ptr->
+					 au1200_dpsmode) | CIM_CONFIG_FS |
+			CIM_CONFIG_BYT | CIM_CONFIG_LEN(CIM_CONFIG_LEN_10BIT) |
+			CIM_CONFIG_BAY_N(cim_config_ptr->
+					 au1200_baymode) | CIM_CONFIG_PM;
+	} else {
+		/* Need to re check........ */
+		nCameraModeConfig =
+			CIM_CONFIG_DPS_N(cim_config_ptr->
+					 au1200_dpsmode) | CIM_CONFIG_FS |
+			CIM_CONFIG_BYT | CIM_CONFIG_LEN(CIM_CONFIG_LEN_10BIT) |
+			CIM_CONFIG_FSEL_N(CIM_CONFIG_FIELD12);
+	}
+
+	au1200_cim->config = nCameraModeConfig;
+	nClearSetInterrupt = CIM_INSTAT_CD | CIM_INSTAT_FD |
+		CIM_INSTAT_UFA | CIM_INSTAT_OFA |
+		CIM_INSTAT_UFB | CIM_INSTAT_OFB | CIM_INSTAT_UFB | CIM_INSTAT_OFC;
+
+	au1200_cim->instat = nClearSetInterrupt;
+	au1200_cim->inten = nClearSetInterrupt;
+
+	for (i = 0; i < 6; i++) {
+		mdelay(1);
+	}
+
+      error_ch_alloc:
+	if (ErrorCheck) {
+		CIM_Cleanup(cim_config);
+		return -1;
+	}
+	return 0;
+}
+
+#define MAX_GFP 0x00200000
+
+/* To get contigious Memroy location using GetFree pages*/
+
+static unsigned long
+Camera_mem_alloc(unsigned long size)
+{
+	/* __get_free_pages() fulfills a max request of 2MB */
+	/* do multiple requests to obtain large contigous mem */
+
+	unsigned long mem, amem, alloced = 0, allocsize;
+
+	size += 0x1000;
+	allocsize = (size < MAX_GFP) ? size : MAX_GFP;
+
+	/* Get first chunk */
+	mem = (unsigned long)
+	    __get_free_pages(GFP_ATOMIC | GFP_DMA, get_order(allocsize));
+	if (mem != 0)
+		alloced = allocsize;
+
+	/* Get remaining, contiguous chunks */
+	while (alloced < size) {
+		amem = (unsigned long)
+		    __get_free_pages(GFP_ATOMIC | GFP_DMA,
+				     get_order(allocsize));
+		if (amem != 0)
+			alloced += allocsize;
+
+		/* check for contiguous mem alloced */
+		if ((amem == 0) || (amem + allocsize) != mem)
+			break;
+		else
+			mem = amem;
+	}
+	return mem;
+}
+
+static irqreturn_t 
+Cim_Interrupt_Handler(int irq, void *dev_id,struct pt_regs *regs)
+{
+
+	uint32_t nStatus;
+
+	disable_irq(AU1200_CAMERA_INT);
+	nStatus = au1200_cim->instat;
+
+	if (nStatus & CIM_INSTAT_CD) {
+		au1200_cim->instat = CIM_INSTAT_CD;
+	} else if (nStatus & CIM_INSTAT_FD) {
+		au1200_cim->instat = CIM_INSTAT_FD;
+	} else if (nStatus & CIM_INSTAT_UFA) {
+		au1200_cim->instat = CIM_INSTAT_UFA;
+		ciminterruptcheck = 1;
+	} else if (nStatus & CIM_INSTAT_OFA) {
+		au1200_cim->instat = CIM_INSTAT_OFA;
+		ciminterruptcheck = 1;
+	} else if (nStatus & CIM_INSTAT_UFB) {
+		au1200_cim->instat = CIM_INSTAT_UFB;
+		ciminterruptcheck = 1;
+	} else if (nStatus & CIM_INSTAT_OFB) {
+		au1200_cim->instat = CIM_INSTAT_OFB;
+		ciminterruptcheck = 1;
+	} else if (nStatus & CIM_INSTAT_UFC) {
+		au1200_cim->instat = CIM_INSTAT_UFC;
+		ciminterruptcheck = 1;
+	} else if (nStatus & CIM_INSTAT_OFC) {
+		au1200_cim->instat = CIM_INSTAT_OFC;
+		ciminterruptcheck = 1;
+	} else if (nStatus & CIM_INSTAT_ERR) {
+		au1200_cim->instat = CIM_INSTAT_ERR;
+	}
+
+	enable_irq(AU1200_CAMERA_INT);
+	return IRQ_HANDLED;
+}
+
+static int
+au1xxxcim_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	nInterruptDoneNumber = 0;
+	uint32_t mode_index, i;
+	CAMERA_RUNTIME *capture;
+	CAMERA *capture_ptr;
+
+	capture = &cam_base;
+
+	switch (cmd) {
+
+	case AU1XXXCIM_QUERY:{
+			/*returing previous mode */
+			DPRINTK
+			    ("QUERY Mode- Return Camera Index to Application is %d \n",
+			     prev_mode);
+			return prev_mode;
+		}
+	case AU1XXXCIM_CONFIGURE:{
+			DPRINTK(" CONFIGURE Mode\n");
+			mode_index = find_mode_index(arg);
+			capture->cmos_camera = OrigCimArryPtr + prev_mode;
+			capture_ptr = capture->cmos_camera;
+			DPRINTK
+			    ("CONFIGURE Mode: Calling CleanUP as Camera needs to be re-configured \n");
+			CIM_Cleanup(capture);
+			DPRINTK("CONFIGURE:Camera Array Index value is %d \n",
+				mode_index);
+			capture->cmos_camera = OrigCimArryPtr + mode_index;
+			capture_ptr = capture->cmos_camera;
+			DPRINTK
+			    (" CONFIGURE: Camera configured in  ** %s ** Mode \n",
+			     capture_ptr->camera_mode);
+			au1200_cim->enable &= ~CIM_ENABLE_EN;
+			Camera_Config(capture);
+			Camera_pwr_down();
+			mdelay(1);
+			Camera_pwr_up();
+			mdelay(6);
+			prev_mode = mode_index;
+			return mode_index;
+		}
+	case AU1XXXCIM_CAPTURE:{
+			capture->cmos_camera = OrigCimArryPtr + prev_mode;
+			capture_ptr = capture->cmos_camera;
+			DPRINTK("CAPTURE: Camera Array Index # %d \n",
+				prev_mode);
+			DPRINTK("CAPTURE:Picture taken in **%s** Mode \n",
+				capture_ptr->camera_mode);
+			Capture_Image();
+			DPRINTK("CAPTURE:Status Reg %x Capture Reg %x \n",
+				au1200_cim->stat, au1200_cim->capture);
+			DPRINTK("Waiting for %d DMA Interrupt \n",
+				capture_ptr->dbdma_channel);
+			while ((nInterruptDoneNumber !=
+				(capture_ptr->dbdma_channel))
+			       && (!ciminterruptcheck)) ;
+
+			if (ciminterruptcheck) {
+				printk(" !! ERROR: DMA Transfer Error \n");
+				ciminterruptcheck = 0;
+				return 0;
+			}
+
+			DPRINTK
+			    ("CAPTURE:Putting back descriptor back to ring\n");
+			for (i = 0; i < capture_ptr->dbdma_channel; i++) {
+				if (!au1xxx_dbdma_put_dest
+				    ((u32) (capture->ChannelArray[i]),
+				     capture->memory[i],
+				     capture->nTransferSize[i])) {
+					printk
+					    ("DBDMA Error..Putting Descriptor on Buffer Ring Channel A in Single Channel \n");
+				}
+			}
+			DPRINTK(" CAPTURE: Exiting Capture \n");
+
+			return 1;
+			break;
+		}
+
+	}
+
+	return -EINVAL;
+}
+
+static int
+au1xxxcim_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	unsigned int len;
+	unsigned long start = 0, off;
+
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
+		printk(" Error vma->vm_pgoff > !OUL PAGE_SHIFT \n");
+		return -EINVAL;
+	}
+
+	start = virt_to_phys(mem_buf) & PAGE_MASK;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + 2 * MAX_FRAME_SIZE);
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if ((vma->vm_end - vma->vm_start + off) > len) {
+		printk(" Error vma->vm_end-vma->vm_start\n");
+		return -EINVAL;
+	}
+
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+	pgprot_val(vma->vm_page_prot) |= PAGE_CACHABLE_DEFAULT;
+
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
+
+	return io_remap_pfn_range(vma, vma->vm_start, off,
+				  vma->vm_end - vma->vm_start,
+				  vma->vm_page_prot);
+}
+
+static struct file_operations au1xxxcim_fops = {
+      owner:THIS_MODULE,
+      ioctl:au1xxxcim_ioctl,
+      mmap:au1xxxcim_mmap
+};
+
+int __init
+au1xxxcim_init(void)
+{
+	int retval, error;
+	unsigned long page;
+	CAMERA_RUNTIME *cam_init;
+	CAMERA *cim_ptr;
+
+	cam_init = &cam_base;
+	cam_init->cmos_camera = OrigCimArryPtr + prev_mode;
+	cim_ptr = cam_init->cmos_camera;
+
+	/*Allocating memory for MMAP */
+	mem_buf = (unsigned long *)Camera_mem_alloc(2 * MAX_FRAME_SIZE);
+	if (mem_buf == NULL) {
+		printk(KERN_ERR "MMAP unable to allocate memory \n");
+	}
+
+	for (page = (unsigned long)mem_buf;
+	     page < PAGE_ALIGN((unsigned long)mem_buf + MAX_FRAME_SIZE);
+	     page += PAGE_SIZE) {
+		SetPageReserved(virt_to_page(page));
+	}
+	Camera_pwr_up();
+	error = Camera_Config(cam_init);
+	if (error == -1) {
+		DPRINTK
+		    ("Camera Config Un-Sucessful: Calling Clean Up function \n");
+		CIM_Cleanup(cam_init);
+	}
+
+	Camera_pwr_down();
+	mdelay(1);
+	Camera_pwr_up();
+
+	/* Register Device */
+	retval = register_chrdev(CIM_MAJOR, CIM_NAME, &au1xxxcim_fops);
+	if (retval < 0) {
+		printk(KERN_ERR "Could not register CIM device\n");
+		return 0;
+	}
+	printk(KERN_INFO "Au1XXX CIM driver registered Sucessfully v%s\n",
+	       VERSION);
+	if ((retval =
+	     request_irq(AU1200_CAMERA_INT, Cim_Interrupt_Handler,
+			 SA_SHIRQ | SA_INTERRUPT, CIM_NAME,
+			 (void *)au1200_cim))) {
+		printk(KERN_ERR "CIM: Could not get IRQ %d.\n",
+		       AU1200_CAMERA_INT);
+		CIM_Cleanup(cam_init);
+		return retval;
+	}
+
+	return 0;
+
+}
+
+void __exit
+au1xxxcim_exit(void)
+{
+	int retval;
+	CAMERA_RUNTIME *cam_exit;
+	CAMERA *cam_exit_ptr;
+
+	cam_exit = &cam_base;
+	cam_exit->cmos_camera = OrigCimArryPtr + prev_mode;
+	cam_exit_ptr = cam_exit->cmos_camera;
+
+	/* Cleanup funtion will clean allocated memory, free DMA channels */
+	CIM_Cleanup(cam_exit);
+
+	/*Unregister Device */
+	retval = unregister_chrdev(CIM_MAJOR, CIM_NAME);
+	if (retval != -EINVAL) {
+		printk(KERN_INFO "CIM driver unregistered Sucessfully \n");
+	}
+}
+
+module_init(au1xxxcim_init);
+module_exit(au1xxxcim_exit);
+
+MODULE_AUTHOR("AMD");
+MODULE_DESCRIPTION("AMD CIM Interface Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/asm-mips/mach-au1x00/au1xxx_cim.h b/include/asm-mips/mach-au1x00/au1xxx_cim.h
new file mode 100644
index 0000000..50fe557
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1xxx_cim.h
@@ -0,0 +1,190 @@
+ /*	Defines for using the Camera Interfaces on the
+  *      Alchemy Au1100 mips processor.
+  *
+  *  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.
+  *
+  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+  *   ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *  You should have received a copy of the  GNU General Public License along
+  *  with this program; if not, write  to the Free Software Foundation, Inc.,
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  *
+  */
+#ifndef AUXXX_CIM_H
+#define AUXXX_CIM_H
+
+#include <linux/ioctl.h>
+
+#define AU1XXXCIM_IOC_MAGIC 'C'
+
+#define RAW_SXGA              _IOW(AU1XXXCIM_IOC_MAGIC,1, int *)
+#define RAW_VGA               _IOW(AU1XXXCIM_IOC_MAGIC,2, int *)
+#define RAW_CIF               _IOW(AU1XXXCIM_IOC_MAGIC,3, int *)
+#define RAW_QVGA              _IOW(AU1XXXCIM_IOC_MAGIC,4, int *)
+#define RAW_QCIF              _IOW(AU1XXXCIM_IOC_MAGIC,5, int *)
+#define RAW_QQVGA             _IOW(AU1XXXCIM_IOC_MAGIC,6, int *)
+#define RAW_QQCIF             _IOW(AU1XXXCIM_IOC_MAGIC,7, int *)
+#define BAYER_SXGA            _IOW(AU1XXXCIM_IOC_MAGIC,8, int *)
+#define BAYER_VGA             _IOW(AU1XXXCIM_IOC_MAGIC,9, int *)
+#define BAYER_CIF             _IOW(AU1XXXCIM_IOC_MAGIC,10, int *)
+#define BAYER_QVGA            _IOW(AU1XXXCIM_IOC_MAGIC,11, int *)
+#define BAYER_QCIF            _IOW(AU1XXXCIM_IOC_MAGIC,12, int *)
+#define BAYER_QQVG            _IOW(AU1XXXCIM_IOC_MAGIC,13, int *)
+#define BAYER_QQCI            _IOW(AU1XXXCIM_IOC_MAGIC,14, int *)
+#define YCbCr_SXGA_RAW        _IOW(AU1XXXCIM_IOC_MAGIC,18, int *)
+#define YCbCr_VGA_RAW         _IOW(AU1XXXCIM_IOC_MAGIC,19, int *)
+#define YCbCr_CIF_RAW         _IOW(AU1XXXCIM_IOC_MAGIC,20, int *)
+#define YCbCr_QVGA_RAW        _IOW(AU1XXXCIM_IOC_MAGIC,21, int *)
+#define YCbCr_QCIF_RAW        _IOW(AU1XXXCIM_IOC_MAGIC,22, int *)
+#define YCbCr_SXGA            _IOW(AU1XXXCIM_IOC_MAGIC,23, int *)
+#define YCbCr_VGA             _IOW(AU1XXXCIM_IOC_MAGIC,24, int *)
+#define YCbCr_CIF             _IOW(AU1XXXCIM_IOC_MAGIC,25, int *)
+#define YCbCr_QVGA            _IOW(AU1XXXCIM_IOC_MAGIC,26, int *)
+#define YCbCr_QCIF            _IOW(AU1XXXCIM_IOC_MAGIC,27, int *)
+#define AU1XXXCIM_CAPTURE     _IOW(AU1XXXCIM_IOC_MAGIC, 100, int *)
+#define AU1XXXCIM_QUERY       _IOW(AU1XXXCIM_IOC_MAGIC, 50, int *)
+#define AU1XXXCIM_CONFIGURE   _IOW(AU1XXXCIM_IOC_MAGIC, 75, int *)
+
+#define  CMOS_RAW               0
+#define  CMOS_CCIR656           1
+
+#define CIM_BASE_ADDRESS        0xB4004000
+
+#define CIM_FIFOA		0xB4004020
+#define CIM_FIFOB		0xB4004040
+#define CIM_FIFOC		0xB4004060
+
+typedef struct
+{
+        unsigned long         enable;                /* 00 */
+        unsigned long         config;                /* 04 */
+        unsigned long         reserve0;              /* 08 */
+	unsigned long         reserve1;              /* 0C */
+	unsigned long         capture;               /* 10 */
+	unsigned long         stat;                  /* 14 */
+        unsigned long         inten;                 /* 18 */
+	unsigned long         instat;                /* 1C */
+	unsigned long         fifoa;                 /* 20 */
+	unsigned long         reserve2;              /* 24 */
+        unsigned long         reserve3;              /* 28 */
+        unsigned long         reserve4;              /* 2C */
+        unsigned long         reserve5;              /* 30 */
+        unsigned long         reserve6;              /* 34 */
+        unsigned long         reserve7;              /* 38 */
+        unsigned long         reserve8;              /* 3C */
+        unsigned long         fifob;                 /* 40 */
+	unsigned long         reserve9;              /* 44 */
+        unsigned long         reserve10;              /* 48 */
+        unsigned long         reserve11;              /* 4C */
+        unsigned long         reserve12;              /* 50 */
+        unsigned long         reserve13;              /* 54 */
+        unsigned long         reserve14;              /* 58 */
+        unsigned long         reserve15;              /* 5C */
+	unsigned long         fifoc;                  /* 60 */
+}AU1200_CIM;
+
+
+#define CIM_ENABLE              0x00000000
+#define CIM_CONFIG		0x00000004
+#define CIM_CAPTURE	        0x00000010
+#define CIM_STAT                0x00000014
+#define CIM_INTEN		0x00000018
+#define CIM_INSTAT		0x0000001C
+
+#define   CIM_ENABLE_EN		        (1<<0)       /* enable/disable/reset the block*/
+
+/* CIM Configuration Register */
+
+#define   CIM_CONFIG_PM			(1<<0)
+#define   CIM_CONFIG_CLK	        (1<<1)   /* Rising Edge of the Clock */
+#define   CIM_CONFIG_LS			(1<<2)	 /* Line Sync Active Low */
+#define   CIM_CONFIG_FS			(1<<3)	 /* Frame Sync is Active Low */
+
+#define   CIM_CONFIG_RAW                 0  /* RAW MODE */
+#define   CIM_CONFIG_BAYER               1  /*Bayer Mode*/
+#define   CIM_CONFIG_656                 2  /* 656 YCbCr Mode*/
+
+#define   CIM_CONFIG_DPS_N(n)           (((n) & 0x03)<<6)
+
+
+#define   CIM_CONFIG_RGGB                 0
+#define   CIM_CONFIG_GRBG                 1
+#define   CIM_CONFIG_BGGR                 2
+#define   CIM_CONFIG_GBRG                 3
+
+#define   CIM_CONFIG_BAY_N(n)           (((n) & 0x03)<<8)
+
+#define   CIM_CONFIG_LEN_8BIT              0
+#define   CIM_CONFIG_LEN_9BIT              1
+#define   CIM_CONFIG_LEN_10BIT             2
+
+
+#define   CIM_CONFIG_LEN(n)		(((n) & 0x0f)<<10)
+#define   CIM_CONFIG_BYT		(1<<14)
+#define   CIM_CONFIG_SF			(1<<15)
+
+#define   CIM_CONFIG_FIELD1              0  /* Capture from Field 1*/
+#define   CIM_CONFIG_FIELD2              1  /*Capture from Field 2*/
+#define   CIM_CONFIG_FIELD12             2  /*Capture from Either Field*/
+
+#define   CIM_CONFIG_FSEL_N(n)	        (((n) & 0x03)<<16)
+
+#define   CIM_CONFIG_SI			(1<<18)
+
+/* CIM Capture Control Register */
+
+#define CIM_CAPTURE_VCE			(1<<0)
+#define CIM_CAPTURE_SCE			(1<<1)
+#define CIM_CAPTURE_CLR			(1<<2)
+
+/* CIM Status Register */
+
+#define CIM_STATUS_VC			(1<<0)
+#define CIM_STATUS_SC			(1<<1)
+#define CIM_STATUS_AF			(1<<2)
+#define CIM_STATUS_AE			(1<<3)
+#define CIM_STATUS_AR			(1<<4)
+#define CIM_STATUS_BF			(1<<5)
+#define CIM_STATUS_BE			(1<<6)
+#define CIM_STATUS_BR			(1<<7)
+#define CIM_STATUS_CF			(1<<8)
+#define CIM_STATUS_CE			(1<<9)
+#define CIM_STATUS_CR			(1<<10)
+
+
+/* Interrupt  Rgister */
+#define CIM_INTEN_CD			(1<<0)
+#define CIM_INTEN_FD			(1<<1)
+#define CIM_INTEN_UFA			(1<<2)
+#define CIM_INTEN_OFA			(1<<3)
+#define CIM_INTEN_UFB			(1<<4)
+#define CIM_INTEN_OFB			(1<<5)
+#define CIM_INTEN_UFC			(1<<6)
+#define CIM_INTEN_OFC			(1<<7)
+#define CIM_INTEN_ERR			(1<<8)
+
+
+/* Interrupt Status Rgister */
+
+#define CIM_INSTAT_CD			(1<<0)
+#define CIM_INSTAT_FD			(1<<1)
+#define CIM_INSTAT_UFA			(1<<2)
+#define CIM_INSTAT_OFA			(1<<3)
+#define CIM_INSTAT_UFB			(1<<4)
+#define CIM_INSTAT_OFB			(1<<5)
+#define CIM_INSTAT_UFC			(1<<6)
+#define CIM_INSTAT_OFC			(1<<7)
+#define CIM_INSTAT_ERR			(1<<8)
+
+#endif

---

From: Matej Kupljen <[email-masked]>
Date: Mon, 05 Dec 2005 09:49:27 +0100

Hi

> A driver for the AU1200 Camera Interface (CIM).  

Great news!

> I'm sending up right now, so comments and flames are definately

Wouldn't it be wise to support V4L2?
This way, many existing application could use AU1200s camera interface.

> +		printk(KERN_ERR "MMAP unable to allocate memory \n");

IMHO this is a waste of memory, because if the user is going to use
the camera in 320x240 mode and this allocates memory for the biggest
size. Wouldn't it be better to set some default configuration and
allocate memory for this? Later if the user changes the mode those
pages are freed and new (for requested size) are allocated.
Or even allocate memory AFTER the configuration has been set?

BR,
Matej

---

From: Komal Shah <[email-masked]>
Date: Mon, 5 Dec 2005 01:28:55 -0800 (PST)

--- Jordan Crouse <[email-masked]> wrote:

and values
> */

There is already nice way to separate sensor interface from the camera
core and ov9640 camera sensor driver is available at OMAP tree.

Could you please look at that and see if that can be re-used?
http://source.mvista.com/git/gitweb.cgi?p=linux-omap-2.6.git;a=blob;h=c7691d19356f9c5d8cb724a924e8bdebaed7fc65;hb=279a7045accc927dbb2b1d41691424c4d345489c;f=drivers/media/video/omap/sensor_ov9640.c

---Komal Shah
http://komalshah.blogspot.com/

__________________________________________ 
Yahoo! DSL – Something to write home about. 
Just $16.99/mo. or less. 
dsl.yahoo.com

---

From: "Jordan Crouse" <[email-masked]>
Date: Mon, 5 Dec 2005 08:06:18 -0700

> This way, many existing application could use AU1200s camera interface.

Thats possible, but for now this solution has been reasonable enough for
us to send it upstream.  I'm sure that somebody more familiar with V4L2 could
make short work of adapting it to the existing infrastructure.
 
> Or even allocate memory AFTER the configuration has been set?

I agree, that could be handled better.

Thanks,

Jordan
-- 
Jordan Crouse
Senior Linux Engineer
AMD - Personal Connectivity Solutions Group
<www.amd.com/embeddedprocessors>