diff options
Diffstat (limited to 'packages/linux/linux-ezx/ezx_camera.patch')
-rw-r--r-- | packages/linux/linux-ezx/ezx_camera.patch | 26846 |
1 files changed, 0 insertions, 26846 deletions
diff --git a/packages/linux/linux-ezx/ezx_camera.patch b/packages/linux/linux-ezx/ezx_camera.patch deleted file mode 100644 index bec5687e0f..0000000000 --- a/packages/linux/linux-ezx/ezx_camera.patch +++ /dev/null @@ -1,26846 +0,0 @@ -EZX phone platform device drivers for camera - -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/i2c/chips/Kconfig linux-2.6.16.5-exz/drivers/i2c/chips/Kconfig ---- linux-2.6.16.5/drivers/i2c/chips/Kconfig 2006-04-12 22:27:57.000000000 +0200 -+++ linux-2.6.16.5-exz/drivers/i2c/chips/Kconfig 2006-04-16 18:49:29.000000000 +0200 -@@ -135,4 +135,25 @@ - This driver can also be built as a module. If so, the module - will be called x1205. - -+config I2C_ADCM2700 -+ tristate "ADCM2700 support" -+ depends on I2C_PXA -+ -+config I2C_A780_CAMERA -+ tristate "A780 camera support" -+ depends on I2C_PXA -+ -+config I2C_OV9640 -+ depends on I2C_A780_CAMERA -+ bool "OV9640 support" -+config I2C_OV9650 -+ depends on I2C_A780_CAMERA -+ bool "OV9650 support" -+config I2C_MT9M111 -+ depends on I2C_A780_CAMERA -+ bool "MT9M111 support" -+config I2C_ADCM3800 -+ depends on I2C_A780_CAMERA -+ bool "ADCM3800 support" -+ - endmenu -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/i2c/chips/Makefile linux-2.6.16.5-exz/drivers/i2c/chips/Makefile ---- linux-2.6.16.5/drivers/i2c/chips/Makefile 2006-04-12 22:27:57.000000000 +0200 -+++ linux-2.6.16.5-exz/drivers/i2c/chips/Makefile 2006-04-16 18:49:29.000000000 +0200 -@@ -15,6 +15,10 @@ - obj-$(CONFIG_TPS65010) += tps65010.o - obj-$(CONFIG_RTC_X1205_I2C) += x1205.o - -+obj-$(CONFIG_I2C_ADCM2700) += e680_camera.o -+obj-$(CONFIG_I2C_A780_CAMERA) += a780_camera.o -+obj-$(CONFIG_PXA_EZX_E680) += boomer.o -+ - ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) - EXTRA_CFLAGS += -DDEBUG - endif -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/i2c/chips/a780_camera.c linux-2.6.16.5-exz/drivers/i2c/chips/a780_camera.c ---- linux-2.6.16.5/drivers/i2c/chips/a780_camera.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/i2c/chips/a780_camera.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,905 @@ -+/* -+ * linux/drivers/i2c/a780_camera.c -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Jay Jia -+ * Created: Nov 25, 2003 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * -+ */ -+#include <linux/miscdevice.h> -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/string.h> -+#include <linux/timer.h> -+#include <linux/delay.h> -+#include <linux/errno.h> -+#include <linux/slab.h> -+#include <linux/i2c.h> -+#include <linux/videodev.h> -+#include <linux/pxa_camera.h> -+#include <linux/init.h> -+#include <linux/kdev_t.h> -+#include <asm/semaphore.h> -+ -+#include <linux/sound.h> -+#include <linux/soundcard.h> -+#include <asm/uaccess.h> -+#include <asm/irq.h> -+ -+/* Major 10, Minor 244, /dev/camerai2c */ -+#define CAM_NAME "cami2c" -+#define CAM_MINOR 244 -+ -+#define TESTCODE -+#undef TESTCODE -+#define I2C_A780_CAMERA 0x86 -+ -+//#define DEBUG 2 -+ -+/*-----------------------------------------------------------*/ -+#define err_print(fmt, args...) printk(KERN_ERR "I2C-CAMERA in fun:%s "fmt"\n", __FUNCTION__, ##args) -+ -+#ifndef NDEBUG -+#define dbg_print(fmt, args...) printk(KERN_INFO "I2C-CAMERA in fun:%s "fmt"\n", __FUNCTION__, ##args) -+#if DEBUG > 1 -+#define ddbg_print(fmt, args...) dbg_print(fmt, ##args) -+#else -+#define ddbg_print(fmt, args...) ; -+#endif -+#else -+#define dbg_print(fmt, args...) ; -+#define ddbg_print(fmt, args...) ; -+#endif -+/*-----------------------------------------------------------*/ -+ -+#define I2C_CLIENT_NONE 100 -+#define I2C_CLIENT_MT9M111 101 -+#define I2C_CLIENT_OV9640 102 -+#define I2C_CLIENT_OV9650 103 -+#define I2C_CLIENT_ADCM3800 104 -+static int i2c_camera_client_type = I2C_CLIENT_NONE; -+static unsigned long i2c_camera_chipid = 0; -+ -+ -+static int a780_camera_adapter_attach(struct i2c_adapter *adap); -+static int a780_camera_detach(struct i2c_client *client); -+static int a780_camera_client_register(struct i2c_client *client); -+static int a780_camera_client_unregister(struct i2c_client *client); -+/* ----------------------------------------------------------------------- */ -+static struct i2c_driver driver = { -+ .name = "a780 camera driver", -+ .id = I2C_A780_CAMERA, -+ //flags: I2C_DF_DUMMY, -+ .attach_adapter = a780_camera_adapter_attach, -+ .detach_client = a780_camera_detach, -+ .owner = THIS_MODULE, -+}; -+ -+static struct i2c_adapter a780_camera_adapter = { -+ name: "a780 camera adapter", -+ id: I2C_A780_CAMERA, -+ client_register: a780_camera_client_register, -+ client_unregister: a780_camera_client_unregister, -+}; -+ -+static struct i2c_client client_template = -+{ -+ name: "(unset)", -+ adapter:&a780_camera_adapter, -+}; -+ -+struct i2c_client *a780_camera_client; -+unsigned int a780_camera_minor; -+ -+static int a780_camera_open(void) -+{ -+ //MOD_INC_USE_COUNT; -+ -+ return 0; -+} -+ -+static int a780_camera_release(void) -+{ -+ //MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+ -+int a780_camera_read(char *buf, size_t count) -+{ -+ int ret; -+ unsigned int flags; -+ -+ a780_camera_open(); -+ local_irq_save(flags); -+ enable_irq(IRQ_I2C); -+ ret = i2c_master_recv(a780_camera_client, buf, count); -+ local_irq_restore(flags); -+ a780_camera_release(); -+ return ret; -+ -+} -+ -+int a780_camera_write(const char *buf, size_t count) -+{ -+ int ret; -+ unsigned int flags; -+ -+ a780_camera_open(); -+ local_irq_save(flags); -+ enable_irq(IRQ_I2C); -+ ret = i2c_master_send(a780_camera_client, buf, count); -+ local_irq_restore(flags); -+ a780_camera_release(); -+ return ret; -+} -+ -+static int a780_camera_client_register(struct i2c_client *client) -+{ -+ -+ return 0; -+} -+ -+static int a780_camera_client_unregister(struct i2c_client *client) -+{ -+ -+ return 0; -+} -+/* ----------------------------------------------------------------------- */ -+ -+static int a780_camera_adapter_attach(struct i2c_adapter *adap) -+{ -+ if(! (a780_camera_client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) -+ return -ENOMEM; -+ memcpy(a780_camera_client,&client_template,sizeof(struct i2c_client)); -+ a780_camera_client->adapter = adap; -+ -+ a780_camera_client->addr = 0x5D; -+ -+ i2c_attach_client(a780_camera_client); -+ return 0; -+} -+ -+static int a780_camera_detach(struct i2c_client *client) -+{ -+ i2c_detach_client(a780_camera_client); -+ return 0; -+} -+/* ----------------------------------------------------------------------- */ -+static int cam_open(struct inode *inode, struct file *file) -+{ -+ if(i2c_camera_client_type == I2C_CLIENT_NONE) -+ return -EINVAL; -+ -+ //MOD_INC_USE_COUNT; -+ return 0; -+} -+ -+static int i2c_camera_readw(unsigned short addr, unsigned short *pvalue); -+static int i2c_camera_readb(unsigned short addr, unsigned char *pvalue); -+static int i2c_camera_writew(unsigned short addr, unsigned short value); -+static int i2c_camera_writeb(unsigned short addr, unsigned char value); -+ -+static int cam_close(struct inode * inode, struct file *file) -+{ -+ //MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+#define DETECT_BUFLEN 256 -+static int cam_ioctl_detectid (void * arg) -+{ -+ int buflen, idlen; -+ char* id; -+ struct camera_i2c_detectid * param = arg; -+ if(copy_from_user(&buflen, &(param->buflen), sizeof(buflen))) -+ { -+ return -EFAULT; -+ } -+ if(buflen > DETECT_BUFLEN) -+ { -+ return -ENOMEM; -+ } -+ id = kmalloc(DETECT_BUFLEN, GFP_KERNEL); -+ if(id == NULL) -+ { -+ return -ENOMEM; -+ } -+ -+ idlen = 0; -+ switch(i2c_camera_client_type) -+ { -+#ifdef CONFIG_I2C_MT9M111 -+ case I2C_CLIENT_MT9M111: -+ idlen = snprintf(id, DETECT_BUFLEN-1, "%s %s %lx", -+ "MICRON", "MT9M111", i2c_camera_chipid); -+ break; -+#endif -+#ifdef CONFIG_I2C_ADCM3800 -+ case I2C_CLIENT_ADCM3800: -+ idlen = snprintf(id, DETECT_BUFLEN-1, "%s %s %lx", -+ "AGILENT", "ADCM3800", i2c_camera_chipid); -+ break; -+#endif -+#ifdef CONFIG_I2C_OV9640 -+ case I2C_CLIENT_OV9640: -+ idlen = snprintf(id, DETECT_BUFLEN-1, "%s %s %lx", -+ "OMNIVISION", "OV9640", i2c_camera_chipid); -+ break; -+#endif -+#ifdef CONFIG_I2C_OV9650 -+ case I2C_CLIENT_OV9650: -+ idlen = snprintf(id, DETECT_BUFLEN-1, "%s %s %lx", -+ "OMNIVISION", "OV9650", i2c_camera_chipid); -+ break; -+#endif -+ default: -+ break; -+ } -+ id[DETECT_BUFLEN-1] = 0; -+ idlen = strlen(id)+1; -+ if(buflen < idlen) -+ { -+ kfree(id); -+ return -ENOMEM; -+ } -+ if(copy_to_user(param->data, id, idlen)) -+ { -+ kfree(id); -+ return -EFAULT; -+ } -+ kfree(id); -+ return 0; -+} -+ -+static int cam_ioctl_register_rw (unsigned int cmd, void * arg) -+{ -+ int ret = -ENOTSUPP; -+ struct camera_i2c_register reg; -+ if(copy_from_user(®, arg, sizeof(reg))) -+ { -+ return -EFAULT; -+ } -+ switch(cmd) -+ { -+ case CAMERA_I2C_WRITEW: -+ ret=i2c_camera_writew(reg.addr, reg.value.w); -+ break; -+ case CAMERA_I2C_WRITEB: -+ ret=i2c_camera_writeb(reg.addr, reg.value.b); -+ break; -+ case CAMERA_I2C_READW: -+ if((ret=i2c_camera_readw(reg.addr, &(reg.value.w)))>=0) -+ { -+ if(copy_to_user(arg, ®, sizeof(reg))) -+ ret = -EFAULT; -+ } -+ break; -+ case CAMERA_I2C_READB: -+ if((ret=i2c_camera_readb(reg.addr, &(reg.value.b)))>=0) -+ { -+ if(copy_to_user(arg, ®, sizeof(reg))) -+ ret = -EFAULT; -+ } -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static int cam_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int ret = -ENOTSUPP; -+ switch (cmd) -+ { -+ case CAMERA_I2C_WRITEW: -+ case CAMERA_I2C_WRITEB: -+ case CAMERA_I2C_READW: -+ case CAMERA_I2C_READB: -+ ret = cam_ioctl_register_rw(cmd, (void *)arg); -+ break; -+ case CAMERA_I2C_DETECTID: -+ ret = cam_ioctl_detectid((void *)arg); -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+static struct file_operations cam_fops = { -+ ioctl: cam_ioctl, -+ open: cam_open, -+ release: cam_close, -+}; -+ -+static struct miscdevice cam_misc_device = { -+ CAM_MINOR, -+ CAM_NAME, -+ &cam_fops, -+}; -+ -+/* ----------------------------------------------------------------------- */ -+static int a780_camera_init_module(void) -+{ -+ int res; -+ -+ res = i2c_add_driver(&driver); -+ if( res < 0 ) -+ { -+ printk("error in add i2c driver\n"); -+ return res; -+ } -+ if (misc_register (&cam_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register cam driver\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void a780_camera_cleanup_module(void) -+{ -+ i2c_del_driver(&driver); -+ misc_deregister(&cam_misc_device); -+} -+ -+ -+#ifdef CONFIG_I2C_MT9M111 -+ -+/*-----------------------------------------------------------*/ -+#define MT9M111_PAGE(a) ((u8)(((a) >> 8) & 0xFF)) -+#define MT9M111_OFFSET(a) ((u8)((a) & 0xFF)) -+ -+//#define MT9M111_LOG -+ -+#ifdef MT9M111_LOG -+#define mt9m111_dbg_print(fmt, args...) dbg_print(fmt, ##args) -+#else -+#define mt9m111_dbg_print(fmt, args...) ; -+#endif -+ -+static int mt9m111_ChangePage(unsigned char page) -+{ -+ static unsigned char old_page = 0xFF; -+ int res; -+ char tmp[3]={0xF0, 0, page}; -+ -+ if(page == old_page) -+ { -+ return 0; -+ } -+ -+ res = a780_camera_write(tmp, 3); -+ if(res < 0) -+ { -+ return res; -+ } -+ old_page = page; -+ -+ return 0; -+} -+ -+int mt9m111_read(unsigned short addr, unsigned short *pvalue) -+{ -+ unsigned char pageaddr = MT9M111_PAGE(addr); -+ unsigned char offset = MT9M111_OFFSET(addr); -+ unsigned short value; -+ int ret; -+ -+ if((ret = mt9m111_ChangePage(pageaddr)) != 0) -+ { -+ mt9m111_dbg_print("Change block address failed. block = 0x%2x", pageaddr); -+ mt9m111_dbg_print("Error code = 0x%x", ret); -+ return ret; -+ } -+ if(a780_camera_write(&offset, 1) < 0) -+ { -+ mt9m111_dbg_print("read error!"); -+ return ret; -+ } -+ -+ ret = a780_camera_read((char *)&value, 2); -+ if(ret < 0) -+ { -+ mt9m111_dbg_print("read error"); -+ return ret; -+ } -+ -+ *pvalue = (value >> 8) | (value << 8); -+ mt9m111_dbg_print("addr = 0x%04x, value = 0x%04x", addr, *pvalue); -+ return 0; -+} -+ -+int mt9m111_write(unsigned short addr, unsigned short value) -+{ -+ unsigned char pageaddr = MT9M111_PAGE(addr); -+ unsigned char offset = MT9M111_OFFSET(addr); -+ char tmp[3]={offset, (char)(value>>8), (char)(value&0xFF)}; -+ int ret; -+ -+ if((ret = mt9m111_ChangePage(pageaddr)) != 0) -+ { -+ mt9m111_dbg_print("Change block address failed. block = 0x%2x", pageaddr); -+ mt9m111_dbg_print("error code = 0x%x", ret); -+ return ret; -+ } -+ ret = a780_camera_write(tmp, 3); -+ if(ret < 0) -+ { -+ return ret; -+ } -+ mt9m111_dbg_print("addr = 0x%04x, value = 0x%04x", addr,value); -+ return 0; -+} -+ -+int i2c_mt9m111_cleanup(void) -+{ -+ i2c_camera_client_type = I2C_CLIENT_NONE; -+ return 0; -+} -+int i2c_mt9m111_init(void) -+{ -+ //unsigned short chipid; -+ a780_camera_client->addr = 0x5D; -+ -+ //mt9m111_read(0, &chipid); -+ //mt9m111_dbg_print("mt9m111 chip id is 0x%x", chipid); -+ -+ i2c_camera_client_type = I2C_CLIENT_MT9M111; -+ return 0; -+} -+ -+#endif // CONFIG_I2C_MT9M111 -+ -+#ifdef CONFIG_I2C_OV9650 -+ -+#define OV_REG_PID 0x0a -+#define OV_REG_VER 0x0b -+#define OV9650_CHIPID_M 0x96 -+#define OV9650_CHIPID_L_0 0x51 -+#define OV9650_CHIPID_L 0x52 -+ -+int i2c_ov9650_read(u8 addr, u8 *pvalue) -+{ -+ int ret; -+ -+ if((ret = a780_camera_write(&addr, 1)) < 0) -+ { -+ err_print("i2c write error code =%d", ret); -+ return -EIO; -+ } -+ -+ ret = a780_camera_read((char *)pvalue, 1); -+ if(ret < 0) -+ { -+ err_print("i2c read error code =%d", ret); -+ return -EIO; -+ } -+ -+ ddbg_print("addr = 0x%02x, value = 0x%02x", addr, *pvalue); -+ return 0; -+} -+ -+int i2c_ov9650_write(u8 addr, u8 value) -+{ -+ char tmp[2]={addr, value}; -+ int ret; -+ -+ ret = a780_camera_write(tmp, 2); -+ if(ret < 0) -+ { -+ err_print("i2c write error code =%d", ret); -+ return -EIO; -+ } -+ -+ ddbg_print("addr = 0x%02x, value = 0x%02x", addr,value); -+ return 0; -+} -+ -+int i2c_ov9650_cleanup(void) -+{ -+ i2c_camera_client_type = I2C_CLIENT_NONE; -+ return 0; -+} -+ -+int i2c_ov9650_init(void) -+{ -+ unsigned char chipid; -+ unsigned char ver; -+ // setup i2c address -+ a780_camera_client->addr = 0x30; //0x60; -+ -+ if( i2c_ov9650_read(OV_REG_PID, &chipid) < 0 ) -+ { -+ err_print("error: failed to read chipid"); -+ return -EIO; -+ } -+ if( chipid != OV9650_CHIPID_M ) -+ { -+ err_print("chip is not Omnivision"); -+ return -EIO; -+ } -+ -+ i2c_ov9650_read(OV_REG_VER, &ver); -+ dbg_print("ov chip id is 0x%x:0x%x", chipid, ver); -+ -+ if( ver != OV9650_CHIPID_L && ver != OV9650_CHIPID_L_0 ) -+ { -+ err_print("chip is not OV9650"); -+ return -EIO; -+ } -+ i2c_camera_client_type = I2C_CLIENT_OV9650; -+ i2c_camera_chipid = (chipid<<8) | ver; -+ -+ return 0; -+} -+ -+#ifdef CONFIG_I2C_OV9640 -+int ov9640_read(u8 addr, u8 *pvalue) -+{ -+ return i2c_ov9650_read(addr, pvalue); -+} -+ -+int ov9640_write(u8 addr, u8 value) -+{ -+ return i2c_ov9650_write(addr, value); -+} -+ -+int i2c_ov9640_cleanup(void) -+{ -+ i2c_camera_client_type = I2C_CLIENT_NONE; -+ return 0; -+} -+ -+#define OV9640_CHIPID_M 0x96 -+#define OV9640_CHIPID_L 0x49 -+#define OV9640_CHIPID_L_V2 0x48 -+ -+int i2c_ov9640_init(void) -+{ -+ unsigned char chipid; -+ unsigned char ver; -+ // setup i2c address -+ a780_camera_client->addr = 0x30; //0x60; -+ -+ if( ov9640_read(OV_REG_PID, &chipid) < 0 ) -+ { -+ err_print("error: failed to read chipid"); -+ return -EIO; -+ } -+ if( chipid != OV9640_CHIPID_M ) -+ { -+ err_print("chip is not Omnivision"); -+ return -EIO; -+ } -+ -+ ov9640_read(OV_REG_VER, &ver); -+ dbg_print("ov chip id is 0x%x:0x%x", chipid, ver); -+ -+ if( ver != OV9640_CHIPID_L && ver != OV9640_CHIPID_L_V2 ) -+ { -+ err_print("chip is not OV9640"); -+ return -EIO; -+ } -+ i2c_camera_client_type = I2C_CLIENT_OV9640; -+ i2c_camera_chipid = (chipid<<8) | ver; -+ -+ return 0; -+} -+#endif // CONFIG_I2C_OV9640 -+ -+#endif // CONFIG_I2C_OV9650 -+ -+#ifdef CONFIG_I2C_ADCM3800 -+ -+#define ADCM3800_I2C_ADDR 0x56 -+#define ADCM3800_BLOCK_SWITCH_CMD 0xFE -+ -+/* Calculating the Module Block Number */ -+#define ADCM3800_BLOCK(a) ((u8)(((a) >> 7) & 0xFF)) /* register's module block address. */ -+#define ADCM3800_OFFSET(a) ((u8)(((a) << 1) & 0xFF)) /* register's offset to this block. */ -+#define ADCM3800_OFFSET_R(a) (ADCM3800_OFFSET(a)|1) /* register's offset ot this block to read*/ -+ -+static int adcm3800_ChgBlock(unsigned char block) -+{ -+ static unsigned char old_blk = 0xFF; -+ int res; -+ char tmp[2]={ADCM3800_BLOCK_SWITCH_CMD, block}; -+ -+ if(block == old_blk) -+ { -+ return 0; -+ } -+ -+ res = a780_camera_write(tmp, 2); -+ if(res < 0) -+ { -+ err_print("error code = %d", res); -+ return -EIO; -+ } -+ old_blk = block; -+ -+ return 0; -+} -+ -+int i2c_adcm3800_read_byte(unsigned short addr, unsigned char *pvalue) -+{ -+ unsigned char blockaddr = ADCM3800_BLOCK(addr); -+ unsigned char offset = ADCM3800_OFFSET_R(addr); -+ int ret; -+ -+ if((ret = adcm3800_ChgBlock(blockaddr)) != 0) -+ { -+ err_print("Change block address failed. block = 0x%2x", blockaddr); -+ return -EIO; -+ } -+ if((ret = a780_camera_write(&offset, 1)) < 0) -+ { -+ err_print("i2c write error code =%d", ret); -+ return -EIO; -+ } -+ -+ ret = a780_camera_read((char *)pvalue, 1); -+ if(ret < 0) -+ { -+ err_print("i2c read error code = %d", ret); -+ return -EIO; -+ } -+ ddbg_print("read b: addr(0x%x) value(0x%x)", addr, *pvalue); -+ -+ return *pvalue; -+} -+ -+int i2c_adcm3800_read(unsigned short addr, unsigned short *pvalue) -+{ -+ unsigned char blockaddr = ADCM3800_BLOCK(addr); -+ unsigned char offset = ADCM3800_OFFSET_R(addr); -+ int ret; -+ -+ if((ret = adcm3800_ChgBlock(blockaddr)) != 0) -+ { -+ err_print("Change block address failed. block = 0x%2x", blockaddr); -+ return -EIO; -+ } -+ if((ret = a780_camera_write(&offset, 1)) < 0) -+ { -+ err_print("i2c write error code =%d", ret); -+ return -EIO; -+ } -+ -+ ret = a780_camera_read((char *)pvalue, 2); -+ if(ret < 0) -+ { -+ err_print("i2c read error code = %d", ret); -+ return -EIO; -+ } -+ ddbg_print("read: addr(0x%x) value(0x%x)", addr, *pvalue); -+ -+ return *pvalue; -+} -+ -+int i2c_adcm3800_write_byte(unsigned short addr, unsigned char value) -+{ -+ unsigned char blockaddr = ADCM3800_BLOCK(addr); -+ unsigned char offset = ADCM3800_OFFSET(addr);; -+ char tmp[3]={offset, value}; -+ int ret; -+ -+ ddbg_print("write b: addr(0x%x) value(0x%x)", addr, value); -+ if((ret = adcm3800_ChgBlock(blockaddr)) != 0) -+ { -+ err_print("Change block address failed. block = 0x%2x", blockaddr); -+ return -EIO; -+ } -+ ret = a780_camera_write(tmp, 2); -+ if(ret < 0) -+ { -+ err_print("i2c write error code = %d", ret); -+ return -EIO; -+ } -+ return 0; -+ -+} -+int i2c_adcm3800_write(unsigned short addr, unsigned short value) -+{ -+ unsigned char blockaddr = ADCM3800_BLOCK(addr); -+ unsigned char offset = ADCM3800_OFFSET(addr);; -+ char tmp[3]={offset, (char)(value&0xFF), (char)(value>>8)}; -+ int ret; -+ -+ ddbg_print("write: addr(0x%x) value(0x%x)", addr, value); -+ if((ret = adcm3800_ChgBlock(blockaddr)) != 0) -+ { -+ err_print("Change block address failed. block = 0x%2x", blockaddr); -+ return -EIO; -+ } -+ ret = a780_camera_write(tmp, 3); -+ if(ret < 0) -+ { -+ err_print("i2c write error code = %d", ret); -+ return -EIO; -+ } -+ return 0; -+} -+ -+int i2c_adcm3800_cleanup(void) -+{ -+ i2c_camera_client_type = I2C_CLIENT_NONE; -+ return 0; -+} -+ -+#define ADCM_SREG_PID 0x0000 -+#define ADCM_EREG_PID 0x0800 -+ -+#define ADCM3800_PIPE_REV 0x0068 -+#define ADCM3800_SENSOR_REV 0x68 -+ -+int i2c_adcm3800_init(void) -+{ -+ unsigned short pid_pipe; -+ unsigned char pid_sensor; -+ a780_camera_client->addr = ADCM3800_I2C_ADDR; -+ -+ if(i2c_adcm3800_read(ADCM_SREG_PID, &pid_pipe) < 0) -+ { -+ return -EIO; -+ } -+ if(i2c_adcm3800_read_byte(ADCM_EREG_PID, &pid_sensor) < 0) -+ { -+ return -EIO; -+ } -+ -+ dbg_print("pipe id is 0x%x, sensor id is 0x%x", pid_pipe, pid_sensor); -+ if(pid_pipe != ADCM3800_PIPE_REV && pid_sensor != ADCM3800_SENSOR_REV) -+ { -+ err_print("sensor is not Agilent ADCM3800"); -+ return -EIO; -+ } -+ i2c_camera_client_type = I2C_CLIENT_ADCM3800; -+ i2c_camera_chipid = (pid_pipe<<8) | pid_sensor; -+ -+ return 0; -+} -+#endif // CONFIG_I2C_ADCM3800 -+ -+static int i2c_camera_readw(unsigned short addr, unsigned short *pvalue) -+{ -+ int ret = -ENOTSUPP; -+ switch(i2c_camera_client_type) -+ { -+#ifdef CONFIG_I2C_MT9M111 -+ case I2C_CLIENT_MT9M111: -+ ret = mt9m111_read(addr, pvalue); -+ break; -+#endif -+#ifdef CONFIG_I2C_ADCM3800 -+ case I2C_CLIENT_ADCM3800: -+ ret = i2c_adcm3800_read(addr, pvalue); -+ break; -+#endif -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static int i2c_camera_readb(unsigned short addr, unsigned char *pvalue) -+{ -+ int ret = -ENOTSUPP; -+ switch(i2c_camera_client_type) -+ { -+#ifdef CONFIG_I2C_ADCM3800 -+ case I2C_CLIENT_ADCM3800: -+ ret = i2c_adcm3800_read_byte(addr, pvalue); -+ break; -+#endif -+#ifdef CONFIG_I2C_OV9640 -+ case I2C_CLIENT_OV9640: -+ ret = ov9640_read(addr, pvalue); -+ break; -+#endif -+#ifdef CONFIG_I2C_OV9650 -+ case I2C_CLIENT_OV9650: -+ ret = i2c_ov9650_read(addr, pvalue); -+ break; -+#endif -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static int i2c_camera_writew(unsigned short addr, unsigned short value) -+{ -+ int ret = -ENOTSUPP; -+ switch(i2c_camera_client_type) -+ { -+#ifdef CONFIG_I2C_MT9M111 -+ case I2C_CLIENT_MT9M111: -+ ret = mt9m111_write(addr, value); -+ break; -+#endif -+#ifdef CONFIG_I2C_ADCM3800 -+ case I2C_CLIENT_ADCM3800: -+ ret = i2c_adcm3800_write(addr, value); -+ break; -+#endif -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static int i2c_camera_writeb(unsigned short addr, unsigned char value) -+{ -+ int ret = -ENOTSUPP; -+ switch(i2c_camera_client_type) -+ { -+#ifdef CONFIG_I2C_ADCM3800 -+ case I2C_CLIENT_ADCM3800: -+ ret = i2c_adcm3800_write_byte(addr, value); -+ break; -+#endif -+#ifdef CONFIG_I2C_OV9640 -+ case I2C_CLIENT_OV9640: -+ ret = ov9640_write(addr, value); -+ break; -+#endif -+#ifdef CONFIG_I2C_OV9650 -+ case I2C_CLIENT_OV9650: -+ ret = i2c_ov9650_write(addr, value); -+ break; -+#endif -+ default: -+ break; -+ } -+ return ret; -+} -+ -+#ifdef CONFIG_I2C_MT9M111 -+EXPORT_SYMBOL(i2c_mt9m111_init); -+EXPORT_SYMBOL(mt9m111_write); -+EXPORT_SYMBOL(mt9m111_read); -+EXPORT_SYMBOL(i2c_mt9m111_cleanup); -+#endif -+ -+#ifdef CONFIG_I2C_OV9650 -+EXPORT_SYMBOL(i2c_ov9650_init); -+EXPORT_SYMBOL(i2c_ov9650_write); -+EXPORT_SYMBOL(i2c_ov9650_read); -+EXPORT_SYMBOL(i2c_ov9650_cleanup); -+#endif -+ -+#ifdef CONFIG_I2C_OV9640 -+EXPORT_SYMBOL(i2c_ov9640_init); -+EXPORT_SYMBOL(ov9640_write); -+EXPORT_SYMBOL(ov9640_read); -+EXPORT_SYMBOL(i2c_ov9640_cleanup); -+#endif -+ -+#ifdef CONFIG_I2C_ADCM3800 -+EXPORT_SYMBOL(i2c_adcm3800_init); -+EXPORT_SYMBOL(i2c_adcm3800_write); -+EXPORT_SYMBOL(i2c_adcm3800_read); -+EXPORT_SYMBOL(i2c_adcm3800_write_byte); -+EXPORT_SYMBOL(i2c_adcm3800_read_byte); -+EXPORT_SYMBOL(i2c_adcm3800_cleanup); -+#endif -+ -+module_init(a780_camera_init_module); -+module_exit(a780_camera_cleanup_module); -+MODULE_AUTHOR("Jay Jia"); -+MODULE_LICENSE("GPL"); -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/i2c/chips/boomer.c linux-2.6.16.5-exz/drivers/i2c/chips/boomer.c ---- linux-2.6.16.5/drivers/i2c/chips/boomer.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/i2c/chips/boomer.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,175 @@ -+/* -+ * linux/drivers/i2c/boomer.c -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Jay Jia -+ * Created: Nov 25, 2003 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * History: -+ * Jin Lihong(w20076),Motorola Jan 13,2004,LIBdd68327 Make the e680 louder speaker work. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/string.h> -+#include <linux/timer.h> -+#include <linux/delay.h> -+#include <linux/errno.h> -+#include <linux/slab.h> -+#include <linux/i2c.h> -+#include <linux/videodev.h> -+#include <linux/init.h> -+#include <linux/kdev_t.h> -+#include <asm/semaphore.h> -+ -+#include <linux/sound.h> -+#include <linux/soundcard.h> -+#include <asm/uaccess.h> -+#include <asm/irq.h> -+ -+ -+#define TESTCODE -+#undef TESTCODE -+#define I2C_MIXER 0x80 -+ -+static int mixer_adapter_attach(struct i2c_adapter *adap); -+static int mixer_detach(struct i2c_client *client); -+static int mixer_client_register(struct i2c_client *client); -+static int mixer_client_unregister(struct i2c_client *client); -+extern struct i2c_client *fmradio_client; -+/* ----------------------------------------------------------------------- */ -+static struct i2c_driver driver = { -+ .name = "mixer driver", -+ .id = I2C_MIXER, -+ //.flags = I2C_DF_DUMMY, -+ .attach_adapter = mixer_adapter_attach, -+ .detach_client = mixer_detach, -+ .owner = THIS_MODULE, -+}; -+ -+static struct i2c_adapter mixer_adapter = { -+ name: "Mixer adapter", -+ id: I2C_MIXER, -+ client_register: mixer_client_register, -+ client_unregister: mixer_client_unregister, -+}; -+ -+static struct i2c_client client_template = -+{ -+ name: "(unset)", -+ adapter:&mixer_adapter, -+}; -+ -+struct i2c_client *mixer_client; -+unsigned int mixer_minor; -+ -+int mixer_write(const char *buf, size_t count); -+int mixer_open(void) -+{ -+ //MOD_INC_USE_COUNT; -+ -+ -+#ifdef TESTCODE -+ char data[4]={0x18,0x7d,0xbd,0xcd}; -+ char freq[5]={0x2e,0x56,0x41,0x11,0x40}; -+ unsigned char s[5]={0, 0, 0, 0, 0}; -+ -+ mixer_write(data,4); -+// i2c_master_send(fmradio_client,freq,5); -+// printk("fmradio test code\n"); -+// mdelay(300); -+// i2c_master_recv(fmradio_client, s, 5); -+// printk("s0=%02x s1=%02x s2=%02x s3=%02x s4=%02x \n",s[0],s[1],s[2],s[3],s[4]); -+#endif -+ -+ -+ return 0; -+} -+ -+int mixer_release(void) -+{ -+ //MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+int mixer_write(const char *buf, size_t count) -+{ -+ int ret; -+ unsigned long flags; -+ -+ mixer_open(); -+ local_irq_save(flags); -+ enable_irq(IRQ_I2C); -+ ret = i2c_master_send(mixer_client, buf, count); -+ local_irq_restore(flags); -+// printk("i2c-%d writing %d bytes.\n", mixer_minor, ret); -+ mixer_release(); -+ return ret; -+} -+ -+static int mixer_client_register(struct i2c_client *client) -+{ -+ return 0; -+} -+ -+static int mixer_client_unregister(struct i2c_client *client) -+{ -+ -+ return 0; -+} -+/* ----------------------------------------------------------------------- */ -+ -+static int mixer_adapter_attach(struct i2c_adapter *adap) -+{ -+ if(! (mixer_client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) -+ return -ENOMEM; -+ memcpy(mixer_client,&client_template,sizeof(struct i2c_client)); -+ mixer_client->adapter = adap; -+ -+ mixer_client->addr = 0x7c; -+ -+ printk("adapter %s\n",adap->name); -+ i2c_attach_client(mixer_client); -+#ifdef TESTCODE -+ mixer_open(); -+#endif -+ return 0; -+} -+ -+static int mixer_detach(struct i2c_client *client) -+{ -+ i2c_detach_client(mixer_client); -+ return 0; -+} -+/* ----------------------------------------------------------------------- */ -+ -+static int mixer_init_module(void) -+{ -+ int res; -+ -+ res = i2c_add_driver(&driver); -+ if( res < 0 ) -+ { -+ printk("error in add i2c driver\n"); -+ return res; -+ } -+ return 0; -+} -+ -+static void mixer_cleanup_module(void) -+{ -+ i2c_del_driver(&driver); -+} -+ -+module_init(mixer_init_module); -+module_exit(mixer_cleanup_module); -+MODULE_AUTHOR("Jay Jia"); -+MODULE_LICENSE("GPL"); -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/i2c/chips/e680_camera.c linux-2.6.16.5-exz/drivers/i2c/chips/e680_camera.c ---- linux-2.6.16.5/drivers/i2c/chips/e680_camera.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/i2c/chips/e680_camera.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,668 @@ -+/* -+ * linux/drivers/i2c/e680_camera.c -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Jay Jia -+ * Created: Nov 25, 2003 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * History: -+ * Jin Lihong(w20076),Motorola Jan 13,2004,LIBdd68327 Make the e680 louder speaker work. -+ * -+ */ -+#include <linux/miscdevice.h> -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/string.h> -+#include <linux/timer.h> -+#include <linux/delay.h> -+#include <linux/errno.h> -+#include <linux/slab.h> -+#include <linux/i2c.h> -+#include <linux/videodev.h> -+#include <linux/pxa_camera.h> -+#include <linux/init.h> -+#include <linux/kdev_t.h> -+#include <asm/semaphore.h> -+ -+ -+#include <linux/sound.h> -+#include <linux/soundcard.h> -+#include <asm/uaccess.h> -+#include <asm/irq.h> -+#include <asm/arch/hardware.h> -+#include "i2c-adcm2700.h" -+ -+/* Major 10, Minor 244, /dev/camerai2c */ -+#define CAM_NAME "cami2c" -+#define CAM_MINOR 244 -+ -+#define TESTCODE -+#undef TESTCODE -+#define I2C_E680_CAMERA 0x86 -+ -+#define I2C_CLIENT_NONE 0 -+#define I2C_CLIENT_ADCM2700 1 -+#define I2C_CLIENT_MT9V111 2 -+static int i2c_camera_client_type = I2C_CLIENT_NONE; -+static unsigned long i2c_camera_chipid = 0; -+#define REG_ADDRSELECT (0x01) -+#undef BLOCK(a) -+#define BLOCK(a) ((u8)(((a)>>7)&0xFF)) -+ -+static int e680_camera_adapter_attach(struct i2c_adapter *adap); -+static int e680_camera_detach(struct i2c_client *client); -+static int e680_camera_client_register(struct i2c_client *client); -+static int e680_camera_client_unregister(struct i2c_client *client); -+ -+typedef struct -+{ -+ u16 addr; -+ union {u16 word; u8 byte;}value; -+}i2c_camera_reg; -+/* ----------------------------------------------------------------------- */ -+static struct i2c_driver driver = { -+ .name = "e680 camera driver", -+ .id = I2C_E680_CAMERA, -+ //.flags = I2C_DF_DUMMY, -+ .attach_adapter = e680_camera_adapter_attach, -+ .detach_client = e680_camera_detach, -+ .owner = THIS_MODULE, -+}; -+ -+static struct i2c_adapter e680_camera_adapter = { -+ .name = "e680 camera adapter", -+ .id = I2C_E680_CAMERA, -+ .client_register = e680_camera_client_register, -+ .client_unregister = e680_camera_client_unregister, -+ .owner = THIS_MODULE, -+}; -+ -+static struct i2c_client client_template = -+{ -+ name: "(unset)", -+ adapter:&e680_camera_adapter, -+}; -+ -+struct i2c_client *e680_camera_client; -+unsigned int e680_camera_minor; -+ -+static int e680_camera_open(void) -+{ -+ //MOD_INC_USE_COUNT; -+ -+ return 0; -+} -+ -+static int e680_camera_release(void) -+{ -+ //MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+ -+int e680_camera_read(char *buf, size_t count) -+{ -+ int ret; -+ unsigned int flags; -+ -+ e680_camera_open(); -+ local_irq_save(flags); -+ enable_irq(IRQ_I2C); -+ ret = i2c_master_recv(e680_camera_client, buf, count); -+ local_irq_restore(flags); -+ e680_camera_release(); -+ return ret; -+ -+} -+ -+int e680_camera_write(const char *buf, size_t count) -+{ -+ int ret; -+ unsigned int flags; -+ -+ e680_camera_open(); -+ local_irq_save(flags); -+ enable_irq(IRQ_I2C); -+ ret = i2c_master_send(e680_camera_client, buf, count); -+ local_irq_restore(flags); -+ e680_camera_release(); -+ return ret; -+} -+ -+static int e680_camera_client_register(struct i2c_client *client) -+{ -+ -+ return 0; -+} -+ -+static int e680_camera_client_unregister(struct i2c_client *client) -+{ -+ -+ return 0; -+} -+/* ----------------------------------------------------------------------- */ -+ -+static int e680_camera_adapter_attach(struct i2c_adapter *adap) -+{ -+ if(! (e680_camera_client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) -+ return -ENOMEM; -+ -+ memcpy(e680_camera_client,&client_template,sizeof(struct i2c_client)); -+ e680_camera_client->adapter = adap; -+ -+ /*adcm2700 i2c client address*/ -+ e680_camera_client->addr = 0x53; -+ i2c_attach_client(e680_camera_client); -+ return 0; -+} -+ -+static int e680_camera_detach(struct i2c_client *client) -+{ -+ i2c_detach_client(e680_camera_client); -+ return 0; -+} -+ -+/* ----------------------------------------------------------------------- */ -+static int cam_open(struct inode *inode, struct file *file) -+{ -+ if(i2c_camera_client_type == I2C_CLIENT_NONE) -+ return -EINVAL; -+ -+ //MOD_INC_USE_COUNT; -+ return 0; -+} -+ -+static int i2c_camera_readw(unsigned short addr, unsigned short *pvalue); -+static int i2c_camera_readb(unsigned short addr, unsigned char *pvalue); -+static int i2c_camera_writew(unsigned short addr, unsigned short value); -+static int i2c_camera_writeb(unsigned short addr, unsigned char value); -+ -+static int cam_close(struct inode * inode, struct file *file) -+{ -+ //MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+#define DETECT_BUFLEN 256 -+static int cam_ioctl_detectid (void * arg) -+{ -+ int buflen, idlen; -+ char* id; -+ struct camera_i2c_detectid * param = arg; -+ if(copy_from_user(&buflen, &(param->buflen), sizeof(buflen))) -+ { -+ return -EFAULT; -+ } -+ if(buflen > DETECT_BUFLEN) -+ { -+ return -ENOMEM; -+ } -+ id = kmalloc(DETECT_BUFLEN, GFP_KERNEL); -+ if(id == NULL) -+ { -+ return -ENOMEM; -+ } -+ -+ idlen = 0; -+ switch(i2c_camera_client_type) -+ { -+ case I2C_CLIENT_MT9V111: -+ idlen = snprintf(id, DETECT_BUFLEN-1, "%s %s %lx", -+ "MICRON", "MT9V111", i2c_camera_chipid); -+ break; -+ case I2C_CLIENT_ADCM2700: -+ idlen = snprintf(id, DETECT_BUFLEN-1, "%s %s %lx", -+ "AGILENT", "ADCM2700", i2c_camera_chipid); -+ break; -+ default: -+ break; -+ } -+ id[DETECT_BUFLEN-1] = 0; -+ idlen = strlen(id)+1; -+ if(buflen < idlen) -+ { -+ kfree(id); -+ return -ENOMEM; -+ } -+ if(copy_to_user(param->data, id, idlen)) -+ { -+ kfree(id); -+ return -EFAULT; -+ } -+ kfree(id); -+ return 0; -+} -+ -+static int cam_ioctl_register_rw (unsigned int cmd, void * arg) -+{ -+ int ret = -ENOTSUPP; -+ struct camera_i2c_register reg; -+ if(copy_from_user(®, arg, sizeof(reg))) -+ { -+ return -EFAULT; -+ } -+ switch(cmd) -+ { -+ case CAMERA_I2C_WRITEW: -+ ret=i2c_camera_writew(reg.addr, reg.value.w); -+ break; -+ case CAMERA_I2C_WRITEB: -+ ret=i2c_camera_writeb(reg.addr, reg.value.b); -+ break; -+ case CAMERA_I2C_READW: -+ if((ret=i2c_camera_readw(reg.addr, &(reg.value.w)))>=0) -+ { -+ if(copy_to_user(arg, ®, sizeof(reg))) -+ ret = -EFAULT; -+ } -+ break; -+ case CAMERA_I2C_READB: -+ if((ret=i2c_camera_readb(reg.addr, &(reg.value.b)))>=0) -+ { -+ if(copy_to_user(arg, ®, sizeof(reg))) -+ ret = -EFAULT; -+ } -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static int cam_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int ret = -ENOTSUPP; -+ switch (cmd) -+ { -+ case CAMERA_I2C_WRITEW: -+ case CAMERA_I2C_WRITEB: -+ case CAMERA_I2C_READW: -+ case CAMERA_I2C_READB: -+ ret = cam_ioctl_register_rw(cmd, (void *)arg); -+ break; -+ case CAMERA_I2C_DETECTID: -+ ret = cam_ioctl_detectid((void *)arg); -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+static struct file_operations cam_fops = { -+ ioctl: cam_ioctl, -+ open: cam_open, -+ release: cam_close, -+}; -+ -+static struct miscdevice cam_misc_device = { -+ CAM_MINOR, -+ CAM_NAME, -+ &cam_fops, -+}; -+ -+/* ----------------------------------------------------------------------- */ -+static int e680_camera_init_module(void) -+{ -+ int res; -+ -+ res = i2c_add_driver(&driver); -+ if( res < 0 ) -+ { -+ printk("error in add i2c driver\n"); -+ return res; -+ } -+ if (misc_register (&cam_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register cam driver\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void e680_camera_cleanup_module(void) -+{ -+ i2c_del_driver(&driver); -+ misc_deregister(&cam_misc_device); -+} -+/*-----------------------------------------------------------*/ -+static int ChgBlockAddr(unsigned char block) -+{ -+ static unsigned char old_blk = 0xFF; -+ int res; -+ char tmp[2]={BLOCK_SWITCH_CMD, block}; -+ -+ if(block == old_blk) -+ { -+ return 0; -+ } -+ -+ res = e680_camera_write(tmp, 2); -+ if(res < 0) -+ { -+ dbg_print("error code = %d", res); -+ return -1; -+ } -+ old_blk = block; -+ -+ return 0; -+} -+ -+int adcm2700_read(unsigned short addr, unsigned short *pvalue) -+{ -+ unsigned char blockaddr = BLOCK(addr); -+ unsigned char offset = OFFSET_R(addr); -+ int ret; -+ -+ if((ret = ChgBlockAddr(blockaddr)) != 0) -+ { -+ dbg_print("Change block address failed. block = 0x%2x", blockaddr); -+ return -1; -+ } -+ if((ret = e680_camera_write(&offset, 1)) < 0) -+ { -+ dbg_print("i2c write error code =%d", ret); -+ return -1; -+ } -+ -+ ret = e680_camera_read((char *)pvalue, 2); -+ if(ret < 0) -+ { -+ dbg_print("i2c read error oce = %d", ret); -+ return -1; -+ } -+ -+ return *pvalue; -+} -+int adcm2700_write_byte(unsigned short addr, unsigned char value) -+{ -+ unsigned char blockaddr = BLOCK(addr); -+ unsigned char offset = OFFSET(addr);; -+ char tmp[3]={offset, value}; -+ int ret; -+ -+ if((ret = ChgBlockAddr(blockaddr)) != 0) -+ { -+ dbg_print("Change block address failed. block = 0x%2x", blockaddr); -+ return -1; -+ } -+ ret = e680_camera_write(tmp, 2); -+ if(ret < 0) -+ { -+ dbg_print("i2c write error code = %d", ret); -+ return -1; -+ } -+ return 0; -+ -+} -+int adcm2700_read_byte(unsigned short addr, unsigned char * pvalue) -+{ -+ unsigned char blockaddr = BLOCK(addr); -+ unsigned char offset = OFFSET_R(addr);; -+ int ret; -+ -+ if((ret = ChgBlockAddr(blockaddr)) != 0) -+ { -+ dbg_print("Change block address failed. block = 0x%2x", blockaddr); -+ return -1; -+ } -+ if((ret = e680_camera_write(&offset, 1)) < 0) -+ { -+ dbg_print("i2c write error code =%d", ret); -+ return -1; -+ } -+ -+ ret = e680_camera_read((char *)pvalue, 1); -+ if(ret < 0) -+ { -+ dbg_print("i2c read error oce = %d", ret); -+ return -1; -+ } -+ return 0; -+ -+} -+int adcm2700_write(unsigned short addr, unsigned short value) -+{ -+ unsigned char blockaddr = BLOCK(addr); -+ unsigned char offset = OFFSET(addr);; -+ char tmp[3]={offset, (char)(value&0xFF), (char)(value>>8)}; -+ int ret; -+ -+ if((ret = ChgBlockAddr(blockaddr)) != 0) -+ { -+ dbg_print("Change block address failed. block = 0x%2x", blockaddr); -+ return -1; -+ } -+ ret = e680_camera_write(tmp, 3); -+ if(ret < 0) -+ { -+ dbg_print("i2c write error code = %d", ret); -+ return -1; -+ } -+ return 0; -+} -+ -+int i2c_adcm2700_cleanup(void) -+{ -+ i2c_camera_client_type = I2C_CLIENT_NONE; -+ return 0; -+} -+int i2c_adcm2700_init(void) -+{ -+ unsigned short chipid; -+ unsigned short adcm_chipids[] = {ADCM2700_CHIP_ID, ADCM2700_CHIP_ID_NEW, 0x62}; -+ int i; -+ e680_camera_client->addr = 0x53; -+ -+ if(adcm2700_read(0, &chipid) < 0) -+ { -+ return -1; -+ } -+ -+ dbg_print("CHIP ID IS %x", chipid); -+ -+ for(i = 0; i < sizeof(adcm_chipids)/sizeof(adcm_chipids[0]); i++) -+ { -+ if(chipid == adcm_chipids[i]) -+ break; -+ } -+ -+ if(i >= sizeof(adcm_chipids)/sizeof(adcm_chipids[0])) -+ { -+ return -1; -+ } -+ -+ i2c_camera_client_type = I2C_CLIENT_ADCM2700; -+ i2c_camera_chipid = chipid; -+ -+ return 0; -+} -+//======================================================================= -+static int mt9v111_addr_select(unsigned char addrSpace) -+{ -+ int ret; -+ static u8 curSpace = 0; -+ char buf[3] = {REG_ADDRSELECT, 0, addrSpace}; -+ -+ if(curSpace != addrSpace) -+ { -+ if((ret = e680_camera_write(buf, 3)) < 0) -+ { -+ dbg_print("i2c write error code = %d", ret); -+ return ret; -+ } -+ curSpace = addrSpace; -+ } -+ return 0; -+} -+ -+int mt9v111_read(unsigned char addrSpace, unsigned short addr) -+{ -+ unsigned short value; -+ unsigned char reg_addr = (unsigned char)addr; -+ -+ if(addr != REG_ADDRSELECT) -+ { -+ if(mt9v111_addr_select(addrSpace) != 0) -+ { -+ dbg_print("Address space select failed. addrSpace = 0x%2x", addrSpace); -+ return -1; -+ } -+ } -+ if(e680_camera_write(®_addr, 1) < 0) -+ { -+ return -1; -+ } -+ -+ if(e680_camera_read((char *)&value, 2) < 0) -+ { -+ return -1; -+ } -+ -+ value = (value << 8 | value >> 8); -+ return value; -+} -+ -+int mt9v111_write(unsigned char addrSpace, unsigned short addr, unsigned short value) -+{ -+ int ret; -+ char buf[3] = {(char)addr, (char)(value>>8), (char)value}; -+ -+ if(addr != REG_ADDRSELECT) -+ { -+ if(mt9v111_addr_select(addrSpace) != 0) -+ { -+ dbg_print("Address space select failed. addrSpace = 0x%2x", addrSpace); -+ return -1; -+ } -+ } -+ -+ if((ret = e680_camera_write(buf, 3)) < 0) -+ { -+ dbg_print("write error code = %d", ret); -+ } -+ -+ return ret; -+} -+int i2c_mt9v111_cleanup(void) -+{ -+ i2c_camera_client_type = I2C_CLIENT_NONE; -+ return 0; -+} -+int i2c_mt9v111_init(void) -+{ -+ int chipid; -+ e680_camera_client->addr = 0x5C; -+ -+ if((chipid = mt9v111_read(0x04, 0x36)) < 0) -+ { -+ return -1; -+ } -+ -+ if((chipid & 0xFF00) != 0x8200) -+ { -+ return -1; -+ } -+ -+ i2c_camera_client_type = I2C_CLIENT_MT9V111; -+ i2c_camera_chipid = chipid; -+ -+ return 0; -+ -+} -+ -+static int i2c_camera_readw(unsigned short addr, unsigned short *pvalue) -+{ -+ int ret = -ENOTSUPP; -+ switch(i2c_camera_client_type) -+ { -+ case I2C_CLIENT_MT9V111: -+ ret = mt9v111_read((addr>>8), (addr&0xFF)); -+ if(ret > 0) -+ { -+ *pvalue = (u16)ret; -+ } -+ break; -+ case I2C_CLIENT_ADCM2700: -+ ret = adcm2700_read(addr, pvalue); -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static int i2c_camera_readb(unsigned short addr, unsigned char *pvalue) -+{ -+ int ret = -ENOTSUPP; -+ unsigned short value; -+ switch(i2c_camera_client_type) -+ { -+ case I2C_CLIENT_ADCM2700: -+ ret = adcm2700_read(addr, &value); -+ *pvalue = (value>>8); -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static int i2c_camera_writew(unsigned short addr, unsigned short value) -+{ -+ int ret = -ENOTSUPP; -+ switch(i2c_camera_client_type) -+ { -+ case I2C_CLIENT_MT9V111: -+ ret = mt9v111_write((addr>>8), (addr&0xFF), value); -+ break; -+ case I2C_CLIENT_ADCM2700: -+ ret = adcm2700_write(addr, value); -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+ -+static int i2c_camera_writeb(unsigned short addr, unsigned char value) -+{ -+ int ret = -ENOTSUPP; -+ switch(i2c_camera_client_type) -+ { -+ case I2C_CLIENT_ADCM2700: -+ ret = adcm2700_write_byte(addr, value); -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+ -+ -+EXPORT_SYMBOL(i2c_adcm2700_init); -+EXPORT_SYMBOL(adcm2700_write); -+EXPORT_SYMBOL(adcm2700_write_byte); -+EXPORT_SYMBOL(adcm2700_read_byte); -+EXPORT_SYMBOL(adcm2700_read); -+EXPORT_SYMBOL(i2c_adcm2700_cleanup); -+ -+EXPORT_SYMBOL(i2c_mt9v111_init); -+EXPORT_SYMBOL(mt9v111_write); -+EXPORT_SYMBOL(mt9v111_read); -+EXPORT_SYMBOL(i2c_mt9v111_cleanup); -+ -+module_init(e680_camera_init_module); -+module_exit(e680_camera_cleanup_module); -+MODULE_AUTHOR("Jay Jia"); -+MODULE_LICENSE("GPL"); -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/i2c/chips/i2c-adcm2700.h linux-2.6.16.5-exz/drivers/i2c/chips/i2c-adcm2700.h ---- linux-2.6.16.5/drivers/i2c/chips/i2c-adcm2700.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/i2c/chips/i2c-adcm2700.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,65 @@ -+ -+/*================================================================================ -+ -+ Header Name: i2c-adcm2700.h -+ -+General Description: Camera module adcm2700 I2C interface head file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+wangfei(w20239) 02/26/2004 LIBdd81055 New chip id support -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+ -+#ifndef __I2C_ADCM2700_H__ -+#define __I2C_ADCM2700_H__ -+ -+#define DEBUG -+ -+/* Calculating the Module Block Number */ -+#define BLOCK(a) ((u8)(((a) >> 7) & 0x7F)) /* register's module block address. */ -+#define OFFSET(a) ((u8)(((a) << 1) & 0xFF)) /* register's offset to this block. */ -+#define OFFSET_R(a) (OFFSET(a)|1) /* register's offset ot this block to read*/ -+ -+#define BLOCK_SWITCH_CMD 0xFE -+#define ADCM2700_I2C_ADDR 0x53 -+#define I2C_DRIVERID_ADCM2700 I2C_DRIVERID_EXP1 -+#define ADCM2700_CHIP_ID 0x0060 -+#define ADCM2700_CHIP_ID_NEW 0x0061 -+#define REV_ID 0x0 /* Register definitions in ADCM2700's chip. */ -+ -+ -+struct adcm2700_data { -+ /* -+ * Because the i2c bus is slow, it is often useful to cache the read -+ * information of a chip for some time (for example, 1 or 2 seconds). -+ * It depends of course on the device whether this is really worthwhile -+ * or even sensible. -+ */ -+ struct semaphore update_lock; /* When we are reading lots of information, -+ another process should not update the -+ below information */ -+ -+ char valid; /* != 0 if the following fields are valid. */ -+ int blockaddr; /* current using block address. */ -+ unsigned long last_updated; /* In jiffies */ -+}; -+ -+#ifdef DEBUG -+#define dbg_print(fmt, args...) printk(KERN_INFO "I2C-ADCM2700 in fun:%s "fmt"\n", __FUNCTION__, ##args) -+#else -+#define dbg_print(fmt, args...) ; -+#endif -+ -+#endif /* __I2C_ADCM2700_H__ */ -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/i2c/chips/i2c-ov9640.c linux-2.6.16.5-exz/drivers/i2c/chips/i2c-ov9640.c ---- linux-2.6.16.5/drivers/i2c/chips/i2c-ov9640.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/i2c/chips/i2c-ov9640.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,303 @@ -+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/i2c.h>
-+#include <asm/hardware.h>
-+#include <asm/types.h>
-+#include <linux/delay.h>
-+
-+#include "i2c-ov9640.h"
-+
-+#define DEBUG 1
-+#define DPRINTK(fmt,args...) do { if (DEBUG) printk("in function %s "fmt,__FUNCTION__,##args);} while(0)
-+extern int i2c_adapter_id(struct i2c_adapter *adap);
-+
-+int i2c_ov9640_cleanup(void);
-+void i2c_ov9640_inc_use (struct i2c_client *client);
-+void i2c_ov9640_dec_use (struct i2c_client *client);
-+int i2c_ov9640_attach_adapter(struct i2c_adapter *adapter);
-+int i2c_ov9640_detect_client(struct i2c_adapter *, int, unsigned short, int);
-+int i2c_ov9640_detach_client(struct i2c_client *client);
-+
-+struct i2c_driver ov9640_driver =
-+{
-+ name: "ov9640 driver", /* name */
-+ id: I2C_DRIVERID_OV9640, /* id */
-+ flags: I2C_DF_NOTIFY, /* flags */
-+ attach_adapter: &i2c_ov9640_attach_adapter, /* attach_adapter */
-+ detach_client: &i2c_ov9640_detach_client, /* detach_client */
-+ command: NULL,
-+ inc_use: &i2c_ov9640_inc_use,
-+ dec_use: &i2c_ov9640_dec_use
-+};
-+
-+extern struct i2c_adapter *i2cdev_adaps[];
-+/* Unique ID allocation */
-+static int ov9640_id = 0;
-+struct i2c_client *g_client = NULL;
-+static unsigned short normal_i2c[] = {OV9640_SLAVE_ADDR ,I2C_CLIENT_END };
-+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
-+I2C_CLIENT_INSMOD;
-+
-+/*
-+ * This call returns a unique low identifier for each registered adapter,
-+ * or -1 if the adapter was not registered.
-+ */
-+void i2c_ov9640_inc_use (struct i2c_client *client)
-+{
-+ MOD_INC_USE_COUNT;
-+#ifdef MODULE
-+#endif
-+}
-+
-+void i2c_ov9640_dec_use (struct i2c_client *client)
-+{
-+ MOD_DEC_USE_COUNT;
-+#ifdef MODULE
-+#endif
-+}
-+
-+char ov9640_read(u8 addr, u8 *pvalue)
-+{
-+ int res=0;
-+ char buf=0;
-+ struct i2c_msg msgs[2] = {
-+ { 0, I2C_M_WR, 1, &addr },
-+ { 0, I2C_M_RD, 1, &buf }};
-+
-+ if( g_client == NULL )
-+ return -1;
-+ i2c_ov9640_inc_use(g_client);
-+ msgs[0].addr=msgs[1].addr=g_client->addr;
-+ res=i2c_transfer(g_client->adapter,&msgs[0],1);
-+ if (res<=0)
-+ goto out;
-+ res=i2c_transfer(g_client->adapter,&msgs[1],1);
-+ if (res<=0)
-+ goto out;
-+ *pvalue = buf;
-+ i2c_ov9640_dec_use(g_client);
-+out:
-+ DPRINTK(KERN_INFO "In funtion %s addr:%x,value=%x\n", __FUNCTION__, addr,*pvalue);
-+ if (res<=0) DPRINTK("res = %d \n",res);
-+ return res;
-+}
-+
-+int ov9640_write(u8 addr, u8 value)
-+{
-+ int res=0;
-+ if( g_client == NULL )
-+ return -1;
-+ /*
-+ char buf=0;
-+ struct i2c_msg msgs[2] = {
-+ { 0, I2C_M_WR, 1, &addr },
-+ { 0, I2C_M_WR, 1, &value }};
-+ msgs[0].addr=msgs[1].addr=g_client->addr;
-+ res=i2c_transfer(g_client->adapter,&msgs[0],1);
-+ if (res<=0) return res;
-+ res=i2c_transfer(g_client->adapter,&msgs[1],1);
-+ if (res<=0) return res;
-+
-+
-+ res=i2c_smbus_write_byte_data(g_client, addr, value );
-+ */
-+ char buf[2]={addr,value};
-+ i2c_ov9640_inc_use(g_client);
-+ res = i2c_master_send(g_client, buf, 2);
-+ i2c_ov9640_dec_use(g_client);
-+ if (res >0) res =0;
-+ else res =-1;
-+ DPRINTK(KERN_INFO "In funtion %s addr:%x value:%xreturn %d \n", __FUNCTION__, addr,value,res);
-+ return res;
-+}
-+
-+
-+int i2c_ov9640_read(struct i2c_client *client, u8 reg)
-+{
-+ unsigned char msgbuf=0;
-+ DPRINTK("in function %s\n",__FUNCTION__);
-+ i2c_master_recv(client,&msgbuf,1);
-+ return msgbuf;
-+ /*
-+ */
-+// return i2c_smbus_read_word_data(client,reg);
-+// return i2c_smbus_read_byte_data(client,reg);
-+}
-+
-+int i2c_ov9640_write(struct i2c_client *client, u8 reg, u16 value)
-+{
-+ return i2c_smbus_write_word_data(client,reg,value);
-+}
-+
-+
-+int i2c_ov9640_attach_adapter(struct i2c_adapter *adap)
-+{
-+ DPRINTK("In function %s.\n", __FUNCTION__);
-+ return i2c_probe(adap,&addr_data,i2c_ov9640_detect_client);
-+}
-+
-+
-+int i2c_ov9640_detect_client(struct i2c_adapter *adapter, int address, unsigned short flags, int kind)
-+{
-+ struct i2c_client *new_client;
-+ int err = 0;
-+ struct ov9640_data *data;
-+
-+ /*check if */
-+ if(g_client != NULL) {
-+ err = -ENXIO;
-+ goto ERROR0;
-+ }
-+
-+
-+ DPRINTK(KERN_INFO "In funtion %s. address=0X%X\n", __FUNCTION__, address);
-+ /* Let's see whether this adapter can support what we need.
-+ Please substitute the things you need here! */
-+ if ( !i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA) ) {
-+ DPRINTK(KERN_INFO "Word op is not permited.\n");
-+ goto ERROR0;
-+ }
-+
-+ /* OK. For now, we presume we have a valid client. We now create the
-+ client structure, even though we cannot fill it completely yet.
-+ But it allows us to access several i2c functions safely */
-+
-+ /* Note that we reserve some space for ov9640_data too. If you don't
-+ need it, remove it. We do it here to help to lessen memory
-+ fragmentation. */
-+
-+ new_client=kmalloc(sizeof(struct i2c_client)+sizeof(struct ov9640_data),
-+ GFP_KERNEL );
-+
-+ if ( !new_client ) {
-+ err = -ENOMEM;
-+ goto ERROR0;
-+ }
-+
-+ data = (struct ov9640_data *) (new_client + 1);
-+
-+ new_client->addr = address;
-+ new_client->data = data;
-+ new_client->adapter = adapter;
-+ new_client->driver = &ov9640_driver;
-+ new_client->flags = 0;
-+
-+ g_client = new_client;
-+
-+ /* Now, we do the remaining detection. If no `force' parameter is used. */
-+
-+ /* First, the generic detection (if any), that is skipped if any force
-+ parameter was used. */
-+
-+ if (kind <= 0) {
-+ char res = -1;
-+ mdelay(2000);
-+ ov9640_read(REV,&res);
-+ /* The below is of course bogus */
-+ DPRINTK("I2C: Probe ov9640 chip..addr=0x%x, REV=%d, res=0x%x\n", address, REV, res);
-+ /*ov9640 chip id is 0x9648
-+ if(res != OV9640_CHIP_ID) {
-+ DPRINTK(KERN_WARNING "Failed.product id =%d \n",res);
-+ goto ERROR1;
-+ }
-+ else {
-+ DPRINTK("OV9640 chip id is 0X%04X\n", OV9640_CHIP_ID);
-+ if ( ov9640_id == 0 )
-+ DPRINTK(" detected.\n");
-+ }*/
-+ }
-+
-+ strcpy(new_client->name, "ov9640");
-+ /* Automatically unique */
-+ new_client->id = ov9640_id++;
-+
-+ /* Only if you use this field */
-+ data->valid = 0;
-+
-+ /* Only if you use this field */
-+ init_MUTEX(&data->update_lock);
-+
-+ /* Tell the i2c layer a new client has arrived */
-+ if ((err = i2c_attach_client(new_client)))
-+ goto ERROR3;
-+
-+ /* This function can write default values to the client registers, if
-+ needed. */
-+ /* ov9640_init_client(new_client); */
-+ return 0;
-+
-+ /* OK, this is not exactly good programming practice, usually. But it is
-+ very code-efficient in this case. */
-+
-+ERROR3:
-+ERROR1:
-+ kfree(new_client);
-+ g_client = NULL;
-+ERROR0:
-+ return err;
-+}
-+
-+int i2c_ov9640_detach_client(struct i2c_client *client)
-+{
-+ int err;
-+
-+ /* Try to detach the client from i2c space */
-+ if ((err = i2c_detach_client(client))) {
-+ DPRINTK("ov9640.o: Client deregistration failed, client not detached.\n");
-+ return err;
-+ }
-+
-+ kfree(client); /* Frees client data too, if allocated at the same time */
-+ g_client = NULL;
-+ return 0;
-+}
-+
-+/* Keep track of how far we got in the initialization process. If several
-+ things have to initialized, and we fail halfway, only those things
-+ have to be cleaned up! */
-+static int ov9640_initialized = 0;
-+
-+int i2c_ov9640_init(void)
-+{
-+ int res;
-+
-+ if (ov9640_initialized)
-+ return 0;
-+ DPRINTK("I2C: driver for device ov9640.\n");
-+ if ( (res = i2c_add_driver(&ov9640_driver)) ) {
-+ DPRINTK("ov9640: Driver registration failed, module not inserted.\n");
-+ i2c_ov9640_cleanup();
-+ return res;
-+ }
-+ ov9640_initialized ++;
-+ if(g_client != NULL)
-+ DPRINTK("I2C: driver for device %s registed!.\n", g_client->name);
-+ else
-+ DPRINTK("I2C: driver for device unregisted!.\n");
-+ return 0;
-+}
-+
-+int i2c_ov9640_cleanup(void)
-+{
-+ int res;
-+
-+ if (ov9640_initialized == 1) {
-+ if ((res = i2c_del_driver(&ov9640_driver))) {
-+ DPRINTK("ov9640: Driver registration failed, module not removed.\n");
-+ return res;
-+ }
-+ ov9640_initialized --;
-+ }
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(i2c_ov9640_init);
-+EXPORT_SYMBOL(ov9640_write);
-+EXPORT_SYMBOL(ov9640_read);
-+EXPORT_SYMBOL(i2c_ov9640_cleanup);
-+//module_init(i2c_ov9640_init);
-+//module_exit(i2c_ov9640_cleanup);
-+MODULE_LICENSE("GPL");
-+
-diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/i2c/chips/i2c-ov9640.h linux-2.6.16.5-exz/drivers/i2c/chips/i2c-ov9640.h ---- linux-2.6.16.5/drivers/i2c/chips/i2c-ov9640.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/i2c/chips/i2c-ov9640.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,42 @@ -+#ifndef __I2C_OV9640_H__
-+#define __I2C_OV9640_H__
-+
-+#define DEBUG
-+
-+/* Calculating the Module Block Number */
-+#define BLOCK(a) (u8)((a) >> 7) /* register's module block address. */
-+#define OFFSET(a) (u8)((a) & 0x7F ) /* register's offset to this block. */
-+
-+/* Update the block address.*/
-+#define BLOCK_SWITCH_CMD 0xFE
-+
-+#define OV9640_SLAVE_ADDR (0x60>>1) /* 60 for write , 61 for read */
-+// #define SENSOR_SLAVE_ADDR 0x0055 /* tbd: */
-+
-+
-+#define I2C_DRIVERID_OV9640 I2C_DRIVERID_EXP2
-+
-+/*ov9640 chip id*/
-+#define OV9640_CHIP_ID 0x9648
-+
-+/* Register definitions in OV9640's chip. */
-+#define PID 0xA
-+#define REV 0xA
-+
-+struct ov9640_data {
-+ /*
-+ * Because the i2c bus is slow, it is often useful to cache the read
-+ * information of a chip for some time (for example, 1 or 2 seconds).
-+ * It depends of course on the device whether this is really worthwhile
-+ * or even sensible.
-+ */
-+ struct semaphore update_lock; /* When we are reading lots of information,
-+ another process should not update the
-+ below information */
-+
-+ char valid; /* != 0 if the following fields are valid. */
-+ int blockaddr; /* current using block address. */
-+ unsigned long last_updated; /* In jiffies */
-+};
-+#endif
-+
-diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/Kconfig linux-2.6.16.5-exz/drivers/media/video/Kconfig ---- linux-2.6.16.5/drivers/media/video/Kconfig 2006-04-12 22:27:57.000000000 +0200 -+++ linux-2.6.16.5-exz/drivers/media/video/Kconfig 2006-04-16 18:49:29.000000000 +0200 -@@ -354,4 +354,35 @@ - Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 - video decoders. - -+config PXA_CAMERA -+ depends on VIDEO_DEV -+ tristate "Camera Interface for PXA27x" -+ -+choice -+ prompt "PXA27x Camera Type" -+ depends on PXA_CAMERA -+ -+config CAMERA_ADCM2700 -+ select I2C_ADCM2700 -+ bool "ADCM2700" -+ -+config CAMERA_MT9M111 -+ select I2C_A780_CAMERA -+ bool "Mt9m111" -+ -+config CAMERA_OV9640 -+ select I2C_A780_CAMERA -+ bool "Omnivision 9640" -+ -+config CAMERA_OV9650 -+ select I2C_A780_CAMERA -+ bool "Omnivision 9650" -+ -+config CAMERA_ADCM3800 -+ select I2C_A780_CAMERA -+ bool "ADCM3900" -+ -+endchoice -+ -+ - endmenu -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/Makefile linux-2.6.16.5-exz/drivers/media/video/Makefile ---- linux-2.6.16.5/drivers/media/video/Makefile 2006-04-12 22:27:57.000000000 +0200 -+++ linux-2.6.16.5-exz/drivers/media/video/Makefile 2006-04-16 18:49:29.000000000 +0200 -@@ -19,6 +19,14 @@ - tda7432.o tda9875.o ir-kbd-i2c.o - obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o - -+obj-$(CONFIG_PXA_CAMERA) += pxa_camera.o -+ -+obj-$(CONFIG_CAMERA_ADCM2700) += adcm2700.o adcm2700_hw.o -+obj-$(CONFIG_CAMERA_OV9640) += ov9640.o ov9640_hw.o -+obj-$(CONFIG_CAMERA_OV9650) += ov9650.o ov9650_hw.o -+obj-$(CONFIG_CAMERA_MT9M111) += mt9m111.o mt9m111_hw.o -+obj-$(CONFIG_CAMERA_ADCM3800) += adcm3800.o adcm3800_hw.o -+ - obj-$(CONFIG_VIDEO_ZR36120) += zoran.o - obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o - obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/adcm2700.c linux-2.6.16.5-exz/drivers/media/video/adcm2700.c ---- linux-2.6.16.5/drivers/media/video/adcm2700.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/adcm2700.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,644 @@ -+ -+/*================================================================================ -+ -+ Header Name: adcm2700.c -+ -+General Description: Camera module adcm2700 interface source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+wangfei(w20239) 02/05/2004 LIBdd74309 Set frame rate in video mode -+wangfei(w20239) 02/26/2004 LIBdd81055 New chip id support -+ Update algorithm for DMA transfer -+ Update strategy for memory management -+ Fix still picture capture failed sometime -+ New Agilent sensor chip ID support -+ Make output height in an even multiple of 8 -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+#include <linux/types.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+ -+#include <asm/pgtable.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+ -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+#include <linux/videodev.h> -+#include <linux/pci.h> -+#include <linux/pm.h> -+#include <linux/poll.h> -+#include <linux/wait.h> -+ -+#include <asm/arch/pxa-regs.h> -+ -+#include "camera.h" -+#include "adcm2700.h" -+#include "adcm2700_hw.h" -+ -+ -+/*********************************************************************** -+ * -+ * ADCM2700 and MT9v111 common functions -+ * -+ ***********************************************************************/ -+#define MAX_WIDTH 640 -+#define MAX_HEIGHT 480 -+#define MIN_WIDTH 64 -+#define MIN_HEIGHT 64 -+#define WIDTH_DEFT 240 -+#define HEIGHT_DEFT 320 -+#define FRAMERATE_DEFT 15 -+#define MCLK_DEFT 6 /* Default Master clock*/ -+#define BUF_SIZE_DEFT ((PAGE_ALIGN(MAX_WIDTH * MAX_HEIGHT) + (PAGE_ALIGN(MAX_WIDTH*MAX_HEIGHT/2)*2))) -+ -+extern int i2c_adcm2700_init(void); -+extern int i2c_mt9v111_init(void); -+ -+////////////////////////////////////////////////////////////////////////////////////// -+//adcm2700 functions -+// -+int camera_func_adcm2700_init(p_camera_context_t); -+int camera_func_adcm2700_deinit(p_camera_context_t); -+int camera_func_adcm2700_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param); -+int camera_func_adcm2700_set_capture_format(p_camera_context_t); -+int camera_func_adcm2700_start_capture(p_camera_context_t, unsigned int frames); -+int camera_func_adcm2700_stop_capture(p_camera_context_t); -+ -+int camera_func_adcm2700_pm_management(p_camera_context_t, int); -+ -+////////////////////////////////////////////////////////////////////////////////////// -+//mt9v111 functions -+// -+int camera_func_mt9v111_init(p_camera_context_t); -+int camera_func_mt9v111_deinit(p_camera_context_t); -+int camera_func_mt9v111_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param); -+int camera_func_mt9v111_set_capture_format(p_camera_context_t); -+int camera_func_mt9v111_start_capture(p_camera_context_t, unsigned int frames); -+int camera_func_mt9v111_stop_capture(p_camera_context_t); -+ -+int camera_func_mt9v111_pm_management(p_camera_context_t, int); -+ -+int camera_func_init(p_camera_context_t cam_ctx); -+ -+ -+camera_function_t e680_camera_func = -+{ -+ init: camera_func_init, -+}; -+ -+int camera_func_init(p_camera_context_t cam_ctx) -+{ -+ int ret = 0; -+ // init context status -+ cam_ctx->dma_channels[0] = 0xFF; -+ cam_ctx->dma_channels[1] = 0xFF; -+ cam_ctx->dma_channels[2] = 0xFF; -+ -+ cam_ctx->capture_width = WIDTH_DEFT; -+ cam_ctx->capture_height = HEIGHT_DEFT; -+ -+ cam_ctx->capture_input_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ cam_ctx->capture_output_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ -+ cam_ctx->frame_rate = cam_ctx->fps = FRAMERATE_DEFT; -+ -+ cam_ctx->mini_fps = FRAMERATE_DEFT-5; -+ -+ cam_ctx->mclk = MCLK_DEFT; -+ cam_ctx->flicker_freq = 50; -+ -+ cam_ctx->buf_size = BUF_SIZE_DEFT; -+ cam_ctx->dma_descriptors_size = (cam_ctx->buf_size/PAGE_SIZE + 10); -+ cam_ctx->vc.maxwidth = MAX_WIDTH; -+ cam_ctx->vc.maxheight = MAX_HEIGHT; -+ cam_ctx->vc.minwidth = MIN_WIDTH; -+ cam_ctx->vc.minheight = MIN_HEIGHT; -+ -+ camera_gpio_init(); -+ ci_init(); -+ -+ // Configure CI according to hardware -+ // master parallel with 8 data pins -+ ci_set_mode(CI_MODE_MP, CI_DATA_WIDTH8); -+ -+ // enable pixel clock(sensor will provide pclock) -+ ci_set_clock(cam_ctx->clk_reg_base, 1, 1, cam_ctx->mclk); -+ -+ // data sample on rising and h,vsync active high -+ ci_set_polarity(0, 0, 0); -+ -+ // fifo control -+ ci_set_fifo(0, CI_FIFO_THL_32, 1, 1); // quality -+ -+ // Turn on M_CLK using xx MHz and wait for 150 ms. -+ ci_enable(1); -+ -+ mdelay(150); -+ -+ if(i2c_adcm2700_init() == 0) -+ { -+ cam_ctx->sensor_type = CAMERA_TYPE_ADCM_2700; -+ e680_camera_func.deinit = camera_func_adcm2700_deinit; -+ e680_camera_func.command = camera_func_adcm2700_docommand; -+ e680_camera_func.set_capture_format = camera_func_adcm2700_set_capture_format; -+ e680_camera_func.start_capture = camera_func_adcm2700_start_capture; -+ e680_camera_func.stop_capture = camera_func_adcm2700_stop_capture; -+ e680_camera_func.pm_management = camera_func_adcm2700_pm_management; -+ -+ if((ret = camera_func_adcm2700_init(cam_ctx)) < 0) -+ { -+ dbg_print("adcm2700 init error! capture format!"); -+ return -1; -+ } -+ ddbg_print("Agilent ADCM2700 camera module detected!"); -+ } -+ else if(i2c_mt9v111_init() == 0) -+ { -+ cam_ctx->sensor_type = CAMERA_TYPE_MT9V111; -+ -+ e680_camera_func.deinit = camera_func_mt9v111_deinit; -+ e680_camera_func.command = camera_func_mt9v111_docommand; -+ e680_camera_func.set_capture_format = camera_func_mt9v111_set_capture_format; -+ e680_camera_func.start_capture = camera_func_mt9v111_start_capture; -+ e680_camera_func.stop_capture = camera_func_mt9v111_stop_capture; -+ e680_camera_func.pm_management = camera_func_mt9v111_pm_management; -+ if((ret = camera_func_mt9v111_init(cam_ctx)) < 0) -+ { -+ dbg_print("mt9v111 init error! capture format!"); -+ return -1; -+ } -+ ddbg_print("Micro MT9V111 camera module detected!"); -+ } -+ else -+ { -+ dbg_print("no camera sensor detected!!!\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+/*********************************************************************** -+ * -+ * ADCM2700 Functions -+ * -+ ***********************************************************************/ -+int camera_func_adcm2700_init( p_camera_context_t camera_context ) -+{ -+ u16 sensor_rev, cm_rev; -+ int i; -+ adcm2700_power_on(camera_context->mclk); -+ //read out version -+ //adcm2700_version_revision(&cm_rev, &sensor_rev); -+ return 0; -+} -+ -+int camera_func_adcm2700_deinit( p_camera_context_t camera_context ) -+{ -+ /* power off the external module */ -+ camera_func_adcm2700_stop_capture(camera_context); -+ /* disable CI */ -+ ci_disable(1); -+ -+ i2c_adcm2700_cleanup(); -+ camera_gpio_deinit(); -+ return 0; -+} -+ -+int camera_func_adcm2700_set_capture_format(p_camera_context_t camera_context) -+{ -+ u16 adcm_format; -+ adcm_window_size size; -+ -+ //set sensor format -+ switch(camera_context->capture_input_format) -+ { -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ adcm_format = O_FORMAT_422_B_YCbYCr; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ adcm_format = O_FORMAT_565_RGB; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB888_PACKED: -+ case CAMERA_IMAGE_FORMAT_RGB888_PLANAR: -+ adcm_format = O_FORMAT_888RGB; -+ break; -+ default: -+ adcm_format = O_FORMAT_422_B_YCbYCr; -+ break; -+ } -+ size.width = camera_context->capture_width; -+ size.height = camera_context->capture_height; -+ //adcm2700_output_size(&size); -+ //adcm2700_viewfinder_cfg_output(adcm_format); -+ return 0; -+} -+ -+int camera_func_adcm2700_start_capture(p_camera_context_t cam_ctx, unsigned int frames) -+{ -+ int cisr; -+ int wait_count; -+ int error_count = 0; -+ static int error_times = 0; -+ -+start: -+ -+ // frames=0 means video mode capture -+ if(frames == 0) -+ { -+ // ddbg_print("video capture!"); -+ wait_count = 1; -+ adcm2700_restore_property(cam_ctx, frames); -+ adcm2700_viewfinder_on(); -+ ci_disable(1); -+ ci_enable(1); -+ -+ } -+ else -+ { -+ // ddbg_print("still capture"); -+ -+ wait_count = 1; -+ adcm2700_restore_property(cam_ctx, frames); -+ adcm2700_snapshot_trigger(); -+ ci_disable(1); -+ ci_enable(1); -+ -+ } -+ -+ dbg_print("wait for EOF %d time", wait_count); -+ unsigned int start_time = 0xFFFFF * 20 * wait_count; -+ unsigned int flags; -+ -+ // local_irq_save(flags); -+ CISR |= CI_CISR_EOF; -+ CISR |= CI_CISR_SOF; -+ cisr=CISR; -+ while(wait_count) -+ { -+ if(cisr & CI_CISR_EOF) -+ { -+ //wait_count -- ; -+ CISR |= CI_CISR_EOF; -+ } -+ -+ if(cisr & CI_CISR_SOF) -+ { -+ wait_count -- ; -+ CISR |= CI_CISR_SOF; -+ } -+ -+ cisr=CISR; -+ if(!(--start_time)) -+ { -+ goto wait_EOF_error; -+ } -+ -+ } -+ ci_disable(1); -+ ci_enable(1); -+ ci_reset_fifo(); -+ ci_clear_int_status(0xFFFFFFFF); -+ mdelay(1); -+ start_dma_transfer(cam_ctx, cam_ctx->block_header); -+// local_irq_restore(flags); -+ dbg_print("wait ok..%d", start_time); -+ return 0; -+ -+wait_EOF_error: -+ // local_irq_restore(flags); -+ error_times++; -+ if(error_count++ >= 3) -+ { -+ return -1; -+ } -+ dbg_print("wait EOF error! error_count = %d", error_count); -+ dbg_print("wait EOF error! error_times = %d", error_times); -+ dbg_print("Reset CIF and camera..."); -+ ci_disable(1); -+ // master parallel with 8 data pins -+ ci_set_mode(CI_MODE_MP, CI_DATA_WIDTH8); -+ // enable pixel clock(sensor will provide pclock) -+ ci_set_clock(cam_ctx->clk_reg_base, 1, 1, cam_ctx->mclk); -+ // data sample on rising and h,vsync active high -+ ci_set_polarity(0, 0, 0); -+ // fifo control -+ ci_set_fifo(0, CI_FIFO_THL_32, 1, 1); // quality -+ // Turn on M_CLK using xx MHz and wait for 150 ms. -+ ci_enable(1); -+ mdelay(10); -+ adcm2700_power_on(cam_ctx->mclk); -+ goto start; -+} -+ -+int camera_func_adcm2700_stop_capture(p_camera_context_t cam_ctx) -+{ -+ adcm2700_viewfinder_off(); -+ stop_dma_transfer(cam_ctx); -+ return 0; -+} -+ -+int camera_func_adcm2700_pm_management(p_camera_context_t cam_ctx, int suspend) -+{ -+ static int resume_dma = 0; -+ if(suspend) -+ { -+ if(cam_ctx != NULL ) -+ { -+ if(cam_ctx->dma_started) -+ { -+ ddbg_print("camera running, suspended"); -+ stop_dma_transfer(cam_ctx); -+ resume_dma = 1; -+ } -+ } -+ -+ disable_irq(IRQ_CAMERA); -+ pxa_set_cken(CKEN24_CAMERA, 0); -+ } -+ else -+ { -+ pxa_set_cken(CKEN24_CAMERA, 1); -+ enable_irq(IRQ_CAMERA); -+ -+ if(cam_ctx != NULL) -+ { -+ ddbg_print("camera running, resumed"); -+ camera_init(cam_ctx); -+ if(resume_dma == 1) -+ { -+ camera_start_video_capture(cam_ctx, 0); -+ resume_dma = 0; -+ } -+ } -+ } -+ return 0; -+} -+ -+/*set picture brightness*/ -+static int pxa_cam_WCAM_VIDIOCSBRIGHT(p_camera_context_t cam_ctx, void * param) -+{ -+ ddbg_print("WCAM_VIDIOCSBRIGHT"); -+ int ret = 0; -+ if(cam_ctx->capture_bright != (int)param) -+ { -+ cam_ctx->capture_bright = (int)param; -+ ret = adcm2700_set_bright(cam_ctx->capture_bright); -+ } -+ return ret; -+} -+ -+/*set picture style*/ -+static int pxa_cam_WCAM_VIDIOCSSTYLE(p_camera_context_t cam_ctx, void * param) -+{ -+ ddbg_print("WCAM_VIDIOCSSTYLE"); -+ int ret = 0; -+ if(cam_ctx->capture_style != (V4l_PIC_STYLE)param) -+ { -+ cam_ctx->capture_style = (V4l_PIC_STYLE)param; -+ if(cam_ctx->dma_started == 1) -+ { -+ camera_func_adcm2700_stop_capture(cam_ctx); -+ ret = camera_func_adcm2700_start_capture(cam_ctx, 0); -+ } -+ -+ } -+ -+ return ret; -+} -+ -+ -+/*set picture light*/ -+static int pxa_cam_WCAM_VIDIOCSLIGHT(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ dbg_print("WCAM_VIDIOCSLIGHT"); -+ int ret = 0; -+ if(cam_ctx->capture_light != (V4l_PIC_WB)param) -+ { -+ cam_ctx->capture_light = (V4l_PIC_WB)param; -+ if(cam_ctx->dma_started == 1) -+ { -+ camera_func_adcm2700_stop_capture(cam_ctx); -+ ret = camera_func_adcm2700_start_capture(cam_ctx, 0); -+ } -+ -+ } -+ return ret; -+} -+ -+ -+//set output size -+static int pxa_cam_WCAM_VIDIOCSOSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ //ddbg_print("WCAM_VIDIOCSOSIZE"); -+ -+ adcm_window_size size; -+ CI_MP_TIMING timing; -+ int ret = 0; -+ -+ if(copy_from_user(&size, param, sizeof(adcm_window_size))) -+ { -+ return -EFAULT; -+ } -+ if(cam_ctx->dma_started == 1) -+ { -+ return -EFAULT; -+ } -+ //make it in an even of multiple of 8 -+ size.width = (size.width +7)/8 * 8; -+ size.height = (size.height+7)/8 * 8; -+ dbg_print("w=%d h=%d", size.width, size.height); -+ if(cam_ctx->capture_width != size.width || cam_ctx->capture_height != size.height) -+ { -+ cam_ctx->capture_width = size.width; -+ cam_ctx->capture_height = size.height; -+ ret = adcm2700_output_size(&size); -+ -+ timing.BFW = timing.BLW = 0; -+ -+ ci_configure_mp(cam_ctx->capture_width-1, cam_ctx->capture_height-1, &timing); -+ camera_ring_buf_init(cam_ctx); -+ } -+ -+ return ret; -+} -+ -+/*Set sensor size*/ -+static int pxa_cam_WCAM_VIDIOCSSSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ //ddbg_print("WCAM_VIDIOCSSSIZE"); -+ adcm_window_size size; -+ int ret = 0; -+ -+ if(copy_from_user(&size, param, sizeof(adcm_window_size))) -+ { -+ return -EFAULT; -+ } -+ if(cam_ctx->dma_started == 1) -+ { -+ return -EFAULT; -+ } -+ //make it in an even of multiple of 8 -+ size.width = (size.width +7)/8 * 8; -+ size.height = (size.height+7)/8 * 8; -+ -+ if(cam_ctx->sensor_width != size.width || cam_ctx->sensor_height != size.height) -+ { -+ cam_ctx->sensor_width = size.width; -+ cam_ctx->sensor_height = size.height; -+ ret = adcm2700_input_size(&size); -+ dbg_print("w = %d h = %d", size.width, size.height); -+ } -+ return ret; -+} -+ -+static int pxa_cam_WCAM_VIDIOCSFPS(p_camera_context_t cam_ctx, void * param) -+{ -+ //ddbg_print("WCAM_VIDIOCSFPS"); -+ -+ struct {int fps, minfps;} cam_fps; -+ int ret = 0; -+ -+ if(copy_from_user(&cam_fps, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ if(cam_fps.fps < 12) -+ { -+ cam_fps.fps = 12; -+ } -+ -+ if(cam_ctx->fps != cam_fps.fps || cam_ctx->mini_fps != cam_fps.minfps) -+ { -+ cam_ctx->fps = cam_fps.fps; -+ cam_ctx->mini_fps = cam_fps.minfps; -+ if(cam_ctx->dma_started == 1) -+ { -+ camera_func_adcm2700_stop_capture(cam_ctx); -+ ret = camera_func_adcm2700_start_capture(cam_ctx, 0); -+ } -+ } -+ return ret; -+} -+ -+static int pxa_camera_WCAM_VIDIOCGCAMREG(p_camera_context_t cam_ctx, void * param) -+{ -+ int reg_value, offset; -+ //ddbg_print("WCAM_VIDIOCGCAMREG"); -+ if(copy_from_user(&offset, param, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ reg_value = (int)adcm2700_reg_read((u16)offset); -+ -+ if(copy_to_user(param, ®_value, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+/*set flicker frequency*/ -+static int pxa_cam_WCAM_VIDIOCSFLICKER(p_camera_context_t cam_ctx, void * param) -+{ -+ dbg_print("WCAM_VIDIOCSFLICKER"); -+ cam_ctx->flicker_freq = (int)param; -+ -+ return adcm2700_set_flicker(cam_ctx->flicker_freq); -+} -+ -+ -+static int pxa_camera_WCAM_VIDIOCSCAMREG(p_camera_context_t cam_ctx, void * param) -+{ -+ struct reg_set_s{int val1, val2} reg_s; -+ //ddbg_print("WCAM_VIDIOCSCAMREG"); -+ -+ if(copy_from_user(®_s, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ adcm2700_write((u16)reg_s.val1, (u16)reg_s.val2); -+ return 0; -+} -+ -+int camera_func_adcm2700_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param) -+{ -+ switch(cmd) -+ { -+ /*read adcm2700 registers*/ -+ case WCAM_VIDIOCGCAMREG: -+ return pxa_camera_WCAM_VIDIOCGCAMREG(cam_ctx, param); -+ -+ /*write adcm2700 registers*/ -+ case WCAM_VIDIOCSCAMREG: -+ return pxa_camera_WCAM_VIDIOCSCAMREG(cam_ctx, param); -+ -+ /*set sensor size */ -+ case WCAM_VIDIOCSSSIZE: -+ return pxa_cam_WCAM_VIDIOCSSSIZE(cam_ctx, param); -+ -+ /*set output size*/ -+ case WCAM_VIDIOCSOSIZE: -+ return pxa_cam_WCAM_VIDIOCSOSIZE(cam_ctx, param); -+ -+ -+ /*set video mode fps*/ -+ case WCAM_VIDIOCSFPS: -+ return pxa_cam_WCAM_VIDIOCSFPS(cam_ctx, param); -+ -+ /*set picture style*/ -+ case WCAM_VIDIOCSSTYLE: -+ return pxa_cam_WCAM_VIDIOCSSTYLE(cam_ctx, param); -+ -+ /*set picture light*/ -+ case WCAM_VIDIOCSLIGHT: -+ return pxa_cam_WCAM_VIDIOCSLIGHT(cam_ctx, param); -+ -+ /*set picture brightness*/ -+ case WCAM_VIDIOCSBRIGHT: -+ return pxa_cam_WCAM_VIDIOCSBRIGHT(cam_ctx, param); -+ -+ /*set flicker frequency*/ -+ case WCAM_VIDIOCSFLICKER: -+ return pxa_cam_WCAM_VIDIOCSFLICKER(cam_ctx, param); -+ -+ default: -+ { -+ dbg_print("Error cmd=0x%x", cmd); -+ return -1; -+ } -+ } -+ return 0; -+ -+ } -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/adcm2700.h linux-2.6.16.5-exz/drivers/media/video/adcm2700.h ---- linux-2.6.16.5/drivers/media/video/adcm2700.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/adcm2700.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,42 @@ -+ -+/*================================================================================ -+ -+ Header Name: adcm2700.h -+ -+General Description: Camera module adcm2700 interface head file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+ -+#ifndef _ADCM2700_H_ -+#define _ADCM2700_H_ -+ -+#include "camera.h" -+ -+////////////////////////////////////////////////////////////////////////////////////// -+// -+// Prototypes -+// -+////////////////////////////////////////////////////////////////////////////////////// -+ -+int camera_func_adcm2700_init(p_camera_context_t); -+int camera_func_adcm2700_deinit(p_camera_context_t); -+int camera_func_adcm2700_set_capture_format(p_camera_context_t); -+int camera_func_adcm2700_start_capture(p_camera_context_t, unsigned int frames); -+int camera_func_adcm2700_stop_capture(p_camera_context_t); -+ -+#endif /* _ADCM2700_H_ */ -+ -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/adcm2700_hw.c linux-2.6.16.5-exz/drivers/media/video/adcm2700_hw.c ---- linux-2.6.16.5/drivers/media/video/adcm2700_hw.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/adcm2700_hw.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,936 @@ -+/*================================================================================ -+ -+ Header Name: adcm2700_hw.c -+ -+General Description: Camera module adcm2700 interface source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+ -+wangfei(w20239) 02/05/2004 LIBdd74309 Set frame rate in video mode -+ -+wangfei(w20239) 02/26/2004 LIBdd81055 New chip id support -+ Update algorithm for DMA transfer -+ Update strategy for memory management -+ Fix still picture capture failed sometime -+ New Agilent sensor chip ID support -+ Make output height in an even multiple of 8 -+ -+wangfei(w20239) 03/08/2004 LIBdd84578 Photo effects setting -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+#include <linux/types.h> -+#include <asm/mach-types.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+ -+#include <linux/types.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/wrapper.h> -+#include <linux/delay.h> -+#include <linux/i2c.h> -+ -+#define MAX_FPS 20 -+ -+#include "adcm2700_hw.h" -+#include "camera.h" -+ -+ -+extern int adcm2700_read(u16 addr, u16 *pvalue); -+extern int adcm2700_write(u16 addr, u16 value); -+extern int adcm2700_read_byte(unsigned short addr, unsigned char * value); -+ -+ -+ -+#define wait_sreg_update() { int retry = adcm2700__TIMEOUT<<2; \ -+ dbg_print("wait for sensor update simple registers"); \ -+ adcm2700_write(SREG_CONTROL, 0x05); \ -+ while(--retry) \ -+ { \ -+ u16 v = adcm2700_reg_read(SREG_CONTROL); \ -+ mdelay(1); \ -+ if(v == 0xFF) break; \ -+ if(!(v & 0x04)) break; \ -+ } \ -+ dbg_print("retry = %d", retry); \ -+ } -+ -+void adcm2700_wait(u32 ms) -+{ -+ if(ms > 10) -+ { -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(ms/10); -+ } -+} -+ -+/**************************************************************************** -+* * -+* I2C Management * -+* * -+*****************************************************************************/ -+u16 adcm2700_reg_read(u16 reg_addr) -+{ -+ u16 value; -+ int ret = adcm2700_read(reg_addr, &value); -+ if(ret < 0) -+ { -+ return 0xFF; -+ } -+ return value; -+} -+ -+void adcm2700_reg_write(u16 reg_addr, u16 reg_value) -+{ -+ -+ /*experts registers or SREG_CONTROL write directly*/ -+ if(reg_addr > 0x26 || reg_addr == SREG_CONTROL) -+ { -+ adcm2700_write(reg_addr, reg_value); -+ return; -+ } -+ -+ /* write sample control register step: -+ 1 Stop the camera ¨C write 0x0000 to the CONTROL register. -+ 2 Change the relevant register. -+ 3 Set the CONFIG bit in the CONTROL register, write 0x0004. -+ 4 Wait for the CONFIG bit in CONTROL to clear. */ -+ adcm2700_write(SREG_CONTROL, 0); -+ adcm2700_write(reg_addr, reg_value); -+ wait_sreg_update(); -+ adcm2700_write(SREG_CONTROL, 0x01); -+ -+} -+ -+/*restore capture property*/ -+int adcm2700_restore_property(p_camera_context_t cam_ctx, int frames) -+{ -+ u16 awb_gain_grn1, awb_gain_grn2, awb_gain_red, awb_gain_blue; -+ u8 ae_gain1, ae_gain2, ae_gain3, ae_gain4; -+ u8 r813, r814, r815, r80e; -+ u16 r80, r84, rp; -+ u16 clk_div, sen_clk_div; -+ u32 texp; -+ -+ dbg_print("sensor width %d", cam_ctx->sensor_width); -+ dbg_print("sensor height %d", cam_ctx->sensor_height); -+ dbg_print("capture_width %d", cam_ctx->capture_width); -+ dbg_print("capture_height %d", cam_ctx->capture_height); -+ ddbg_print("fps %d mini fps %d", cam_ctx->fps, cam_ctx->mini_fps); -+ ddbg_print("light %d", cam_ctx->capture_light); -+ ddbg_print("capture_bright %d", cam_ctx->capture_bright); -+ ddbg_print("capture_style %d", cam_ctx->capture_style); -+ -+ -+ awb_gain_grn1 = adcm2700_reg_read(EREG_APS_COEF_GRN1); -+ awb_gain_grn2 = adcm2700_reg_read(EREG_APS_COEF_GRN2); -+ awb_gain_red = adcm2700_reg_read(EREG_APS_COEF_RED); -+ awb_gain_blue = adcm2700_reg_read(EREG_APS_COEF_BLUE); -+ -+ adcm2700_read_byte(0x080F, &ae_gain1); -+ adcm2700_read_byte(0x0810, &ae_gain2); -+ adcm2700_read_byte(0x0811, &ae_gain3); -+ adcm2700_read_byte(0x0812, &ae_gain4); -+ -+ adcm2700_read_byte(0x813, &r813); -+ adcm2700_read_byte(0x814, &r814); -+ adcm2700_read_byte(0x815, &r815); -+ adcm2700_read_byte(0x80e, &r80e); -+ dbg_print("r813= %x, r814=%x r815 = %x", r813, r814, r815); -+ -+ adcm2700_read(0x80, &r80); -+ adcm2700_read(0x84, &r84); -+ adcm2700_read(0x114, &rp); -+ -+ clk_div = r80+1; -+ sen_clk_div = (r84 == 0) ? 1 : (r84<<1); -+ texp = ((((u32)r814)<<8) + r813) * rp + 4 * r815; -+ texp *= clk_div * sen_clk_div * r80e; -+ dbg_print("before rp = 0x%x r80 = 0x%x r84 = 0x%x", rp, r80, r84); -+ dbg_print("before clk_div = 0x%x sen_clk_div = 0x%x r80e = 0x%x", clk_div, sen_clk_div, r80e); -+ //update simple registers -+ adcm2700_write(SREG_CONTROL, 0); -+ //sensor width and sensor height -+ adcm2700_write(SREG_SIZE, 0x707); -+ adcm2700_write(SREG_SENSOR_WID_V, (u16)(cam_ctx->sensor_width)); -+ adcm2700_write(SREG_SENSOR_HGT_V, (u16)(cam_ctx->sensor_height)); -+ -+ //output width and output height -+ adcm2700_write(SREG_OUTPUT_WID_V, (u16)(cam_ctx->capture_width)); -+ adcm2700_write(SREG_OUTPUT_HGT_V, (u16)(cam_ctx->capture_height)); -+ -+ //default fps -+ adcm2700_write(SREG_FRAME_RATE, cam_ctx->fps*10); -+ wait_sreg_update(); -+ adcm2700_set_light(cam_ctx->capture_light); -+ adcm2700_write(EREG_AE_ETIME_MAX, 100000/(cam_ctx->mini_fps)); -+ -+ //still mode and not night mode -+ if(frames == 1) -+ { -+ adcm2700_write(EREG_AF_CTRL1, 0x10); -+ adcm2700_read_byte(0x80e, &r80e); -+ adcm2700_read(0x80, &r80); -+ adcm2700_read(0x84, &r84); -+ adcm2700_read(0x114, &rp); -+ clk_div = r80+1; -+ sen_clk_div = (r84 == 0) ? 1 : (r84<<1); -+ texp /= (clk_div * sen_clk_div * r80e); -+ u16 ttexp = (texp/rp); -+ r815 = (u8)((texp - ttexp * rp)>>2); -+ r813 = (u8)(ttexp & 0xFF); -+ r814 = (u8)(ttexp >> 8); -+ dbg_print("after r813= %x, r814=%x r815 = %x", r813, r814, r815); -+ adcm2700_write_byte(0x813, r813); -+ adcm2700_write_byte(0x814, r814); -+ adcm2700_write_byte(0x815, r815); -+ dbg_print("after rp = 0x%x r80 = 0x%x r84 = 0x%x", rp, r80, r84); -+ dbg_print("after clk_div = 0x%x sen_clk_div = 0x%x r80e = 0x%x", clk_div, sen_clk_div, r80e); -+ -+ -+ adcm2700_write_byte(0x080F, ae_gain1); -+ adcm2700_write_byte(0x0810, ae_gain2); -+ adcm2700_write_byte(0x0811, ae_gain3); -+ adcm2700_write_byte(0x0812, ae_gain4); -+ -+ adcm2700_write(EREG_APS_COEF_GRN1, awb_gain_grn1); -+ adcm2700_write(EREG_APS_COEF_GRN2, awb_gain_grn2); -+ adcm2700_write(EREG_APS_COEF_RED, awb_gain_red); -+ adcm2700_write(EREG_APS_COEF_BLUE, awb_gain_blue); -+ -+ } -+ else -+ { -+ -+ } -+ -+ -+ //expert registers -+ adcm2700_set_bright(cam_ctx->capture_bright); -+ -+ if(cam_ctx->capture_style == V4l_STYLE_NORMAL && frames == 1) -+ { -+ adcm2700_set_gamma(3); -+ } -+ else -+ { -+ adcm2700_set_style(cam_ctx->capture_style); -+ } -+ -+ adcm2700_write(SREG_CONTROL, 0x01); -+ return ADCM_ERR_NONE; -+ -+} -+ -+ -+/////////////////////////////////////////////////////////////// -+// -+// Programming Guide Chapter 1: Basic Programming -+// -+/////////////////////////////////////////////////////////////// -+ -+void adcm2700_color_init(void); -+ -+int adcm2700_power_on( u8 clk ) -+{ -+ /*Follow these steps to correctly power on the ADCM-2700: -+ 1 Turn on VCC voltage (2.8 volts) and wait 20 milliseconds. -+ 2 Turn on MCLK (13 MHz is the default value) and wait 150 milliseconds. -+ 3 Read register 0x0004; if the return value equals 0x0001, power-up is complete. */ -+ int retry = adcm2700__TIMEOUT<<2; -+ while(--retry) -+ { -+ if(adcm2700_reg_read(SREG_STATUS) == 0x0001) -+ { -+ dbg_print("adcm2700 Power-up complete!!"); -+ break; -+ } -+ adcm2700_wait(2); -+ } -+ -+ -+ -+ /* Program the mafster clock */ -+ adcm2700_master_clock(clk); -+ -+ /* Configure anti-vignetting */ -+ adcm2700_color_init(); -+ -+ return ADCM_ERR_NONE; -+} -+ -+ -+int adcm2700_power_off() -+{ -+ /*stop camera*/ -+ adcm2700_write(SREG_CONTROL, 0); -+ return ADCM_ERR_NONE; -+} -+ -+ -+///////////////////////////////////////////////////////////////////////////////////// -+// -+// Programming Guide Chapter 2: Configuration Methods -+// -+///////////////////////////////////////////////////////////////////////////////////// -+ -+ -+int adcm2700_version_revision(u16 * cm_revision, u16 *sensor_revision) -+{ -+ //Camera module version is 0x060 -+ *cm_revision = adcm2700_reg_read(SREG_ID); -+ dbg_print("adcm2700 SREG_ID is 0x%x", *cm_revision); -+ -+ //Image sensor version is 0x60 -+ *sensor_revision = adcm2700_reg_read(EREG_IDENT); -+ dbg_print("adcm2700 EREG_IDENT is 0x%x", *sensor_revision); -+ return ADCM_ERR_NONE; -+} -+ -+int adcm2700_viewfinder_on() -+{ -+ //adcm2700_write(SREG_CONTROL, 0x01); -+ ddbg_print("camera video mode start!"); -+ return ADCM_ERR_NONE; -+} -+ -+ -+ -+int adcm2700_viewfinder_off() -+{ -+ //adcm2700_write(SREG_CONTROL, 0); -+ ddbg_print("camera video mode stop!"); -+ // adcm2700_store_af_regs(); -+ return ADCM_ERR_NONE; -+} -+ -+ -+int adcm2700_snapshot_trigger() -+{ -+ /* -+ u16 status = adcm2700_reg_read(EREG_AF_STATUS); -+ int retry = adcm2700__TIMEOUT<<1; -+ while(--retry) -+ { -+ if(status & 0x08) -+ break; -+ status = adcm2700_reg_read(EREG_AF_STATUS); -+ } -+ dbg_print("retry = %d", retry); -+ -+ */ -+ return ADCM_ERR_NONE; -+} -+ -+int adcm2700_master_clock(u8 clk) -+{ -+ -+ //0x2712 2X -+ //0x1D09 3X //default -+ //0x2709 4X -+ //0xFC53 -+ u16 div = 0x1D09; -+ -+ clk *= (((div>>8) + 1)/((div&0xFF) + 1)); -+ -+ -+ //adcm2700_reg_write(EREG_SEN_CLK_DIV, 1); -+ -+ /*enable pll*/ -+ adcm2700_write(SREG_CONTROL, 0); -+ -+ adcm2700_write(SREG_CLK_FREQ, (u16)clk * 1000); -+ adcm2700_write(EREG_PLL_DIV_L, div); -+ adcm2700_write(EREG_PLL_DIV_S, div); -+ adcm2700_write(EREG_PLL_CTRL, 0x0025); //0x002D -+ -+ wait_sreg_update(); -+ //adcm2700_reg_write(EREG_I_CLK_DIV, 0); -+ adcm2700_write(SREG_CONTROL, 1); -+ -+ return ADCM_ERR_NONE; -+} -+ -+ -+int adcm2700_input_size(adcm_window_size * window) -+{ -+ -+ /* write sample control register step: -+ 1 Stop the camera ¨C write 0x0000 to the CONTROL register. -+ 2 Change the relevant register. -+ 3 Set the CONFIG bit in the CONTROL register, write 0x0004. -+ 4 Wait for the CONFIG bit in CONTROL to clear. */ -+ /* -+ adcm2700_write(SREG_CONTROL, 0); -+ -+ adcm2700_write(SREG_SIZE, 0x707); -+ adcm2700_write(SREG_SENSOR_WID_V, window->width); -+ adcm2700_write(SREG_SENSOR_HGT_V, window->height); -+ -+ //adcm2700_write(SREG_SENSOR_WID_S, window->width); -+ //adcm2700_write(SREG_SENSOR_HGT_S, window->height); -+ -+ wait_sreg_update(); -+ */ -+ return ADCM_ERR_NONE; -+ } -+int adcm2700_output_size(adcm_window_size * window) -+{ -+ -+ /* write sample control register step: -+ 1 Stop the camera ¨C write 0x0000 to the CONTROL register. -+ 2 Change the relevant register. -+ 3 Set the CONFIG bit in the CONTROL register, write 0x0004. -+ 4 Wait for the CONFIG bit in CONTROL to clear. */ -+/* -+ adcm2700_write(SREG_CONTROL, 0); -+ -+ adcm2700_write(SREG_SIZE, 0x707); -+ adcm2700_write(SREG_OUTPUT_WID_V, window->width); -+ adcm2700_write(SREG_OUTPUT_HGT_V, window->height); -+// adcm2700_write(SREG_OUTPUT_WID_S, window->width); -+// adcm2700_write(SREG_OUTPUT_HGT_S, window->height); -+ -+ wait_sreg_update(); -+ */ -+ return ADCM_ERR_NONE; -+} -+ -+ -+int adcm2700_set_fps(u16 fps, u16 minfps) -+{ -+ if(fps > MAX_FPS || minfps > fps) -+ { -+ return ADCM_ERR_PARAMETER; -+ } -+ -+ adcm2700_reg_write(SREG_FRAME_RATE, fps*10); -+ adcm2700_reg_write(EREG_AE_ETIME_MAX, 100000/(minfps)); -+ -+ return ADCM_ERR_NONE; -+} -+ -+ -+int adcm2700_stillframe_cfg_output(u16 format) -+{ -+ -+ u16 oldcfg = adcm2700_reg_read(SREG_OUTPUT_FORMAT); -+ -+ oldcfg = (oldcfg & 0xF0FF) | ((format & 0x000F) << 8); -+ adcm2700_reg_write( SREG_OUTPUT_FORMAT, oldcfg); -+ -+ return ADCM_ERR_NONE; -+} -+ -+int adcm2700_viewfinder_cfg_output(u16 format) -+{ -+ -+ u16 oldcfg = adcm2700_reg_read( SREG_OUTPUT_FORMAT); -+ -+ oldcfg = (oldcfg & 0xFFF0) | (format & 0x000F); -+ adcm2700_reg_write( SREG_OUTPUT_FORMAT, oldcfg ); -+ return ADCM_ERR_NONE; -+} -+ -+ -+ -+void adcm2700_dump_register(u16 startRegAddr, u16 endRegAddr, u16* buffer) -+{ -+ u16 addr; -+ -+ for(addr = startRegAddr; addr <= endRegAddr; addr+=2) -+ { -+ adcm2700_read(addr, buffer++); -+ } -+} -+ -+int adcm2700_set_gamma(int table) -+{ -+ const u16 regs[] = -+ { -+ 0x1400, 0x1402, 0x1404, 0x1406, 0x1408, 0x140a, 0x140c, 0x140e, 0x1410, 0x1412, 0x1414, -+ 0x1416, 0x1418, 0x141a, 0x141c, 0x141e, 0x1420, 0x1422, 0x1424, 0x1426, 0x1428, 0x142a, -+ 0x142c, 0x142e, 0x1430, 0x1432, 0x1434, 0x1436, 0x1438, 0x143a, 0x143c, 0x143e, 0x1440 -+ }; -+ -+ -+ const u16 regsv[] = -+ { -+ EREG_TM_COEF_00_V, EREG_TM_COEF_01_V, EREG_TM_COEF_02_V, EREG_TM_COEF_03_V, -+ EREG_TM_COEF_04_V, EREG_TM_COEF_05_V, EREG_TM_COEF_06_V, EREG_TM_COEF_07_V, -+ EREG_TM_COEF_08_V, EREG_TM_COEF_09_V, EREG_TM_COEF_10_V, EREG_TM_COEF_11_V, -+ EREG_TM_COEF_12_V, EREG_TM_COEF_13_V, EREG_TM_COEF_14_V, EREG_TM_COEF_15_V, -+ EREG_TM_COEF_16_V, EREG_TM_COEF_17_V, EREG_TM_COEF_18_V, EREG_TM_COEF_19_V, -+ EREG_TM_COEF_20_V, EREG_TM_COEF_21_V, EREG_TM_COEF_22_V, EREG_TM_COEF_23_V, -+ EREG_TM_COEF_24_V, EREG_TM_COEF_25_V, EREG_TM_COEF_26_V, EREG_TM_COEF_27_V, -+ EREG_TM_COEF_28_V, EREG_TM_COEF_29_V, EREG_TM_COEF_30_V, EREG_TM_COEF_31_V, -+ EREG_TM_COEF_32_V -+ }; -+ const u16 regss[] = -+ { -+ EREG_TM_COEF_00_S, EREG_TM_COEF_01_S, EREG_TM_COEF_02_S, EREG_TM_COEF_03_S, -+ EREG_TM_COEF_04_S, EREG_TM_COEF_05_S, EREG_TM_COEF_06_S, EREG_TM_COEF_07_S, -+ EREG_TM_COEF_08_S, EREG_TM_COEF_09_S, EREG_TM_COEF_10_S, EREG_TM_COEF_11_S, -+ EREG_TM_COEF_12_S, EREG_TM_COEF_13_S, EREG_TM_COEF_14_S, EREG_TM_COEF_15_S, -+ EREG_TM_COEF_16_S, EREG_TM_COEF_17_S, EREG_TM_COEF_18_S, EREG_TM_COEF_19_S, -+ EREG_TM_COEF_20_S, EREG_TM_COEF_21_S, EREG_TM_COEF_22_S, EREG_TM_COEF_23_S, -+ EREG_TM_COEF_24_S, EREG_TM_COEF_25_S, EREG_TM_COEF_26_S, EREG_TM_COEF_27_S, -+ EREG_TM_COEF_28_S, EREG_TM_COEF_29_S, EREG_TM_COEF_30_S, EREG_TM_COEF_31_S, -+ EREG_TM_COEF_32_S -+ }; -+ -+ const u16 value[][33] = -+ { -+ //default -+ 0x0000, 0x003c, 0x0052, 0x0063, 0x0070, 0x007c, 0x0087, 0x0091, 0x0094, 0x00ab, 0x00b9, -+ 0x00c7, 0x00d3, 0x00ea, 0x00fe, 0x0111, 0x0122, 0x0141, 0x015d, 0x0176, 0x018d, 0x01b8, -+ 0x01de, 0x0201, 0x0221, 0x025b, 0x028f, 0x02bf, 0x02eb, 0x033b, 0x0382, 0x03c3, 0x0400, -+ /* -+ 0x0000, 0x004C, 0x0065, 0x0078, 0x0087, 0x0094, 0x00A0, 0x00ab, 0x00b5, 0x00c6, 0x00d6, -+ 0x00e4, 0x00f1, 0x0109, 0x011E, 0x0131, 0x0142, 0x0161, 0x017D, 0x0197, 0x01AE, 0x01d8, -+ 0x01fd, 0x021F, 0x023E, 0x0276, 0x02a8, 0x02d5, 0x02ff, 0x0349, 0x038C, 0x03C8, 0x0400, -+ */ -+ -+ -+ //solarize -+ 0x0400, 0x03e9, 0x03a9, 0x0344, 0x02c3, 0x0232, 0x019c, 0x010e, 0x0095, 0x003c, 0x0009, -+ 0x0002, 0x0026, 0x0074, 0x00e3, 0x016b, 0x01ff, 0x0294, 0x031c, 0x038b, 0x03d9, 0x03fd, -+ 0x03f6, 0x03c3, 0x036a, 0x02f1, 0x0263, 0x01cd, 0x013c, 0x00bb, 0x0056, 0x0016, 0x0000, -+ -+ //neg.art -+ 0x03ff, 0x03e8, 0x03cd, 0x03b9, 0x03a9, 0x039b, 0x038e, 0x0383, 0x0379, 0x0366, 0x0356, -+ 0x0347, 0x0339, 0x0320, 0x030a, 0x02f6, 0x02e4, 0x02c2, 0x02a5, 0x028a, 0x0272, 0x0245, -+ 0x021e, 0x01fa, 0x01da, 0x019e, 0x016a, 0x013a, 0x010e, 0x00c0, 0x007a, 0x003a, 0x0000, -+ -+ -+ /* -+ //2.6 -+ 0x0000, 0x005C, 0x0079, 0x008d, 0x009e, 0x00ac, 0x00b9, 0x00c4, 0x00ce, 0x00e1, 0x00f1, -+ 0x0100, 0x010e, 0x0126, 0x013b, 0x014e, 0x0160, 0x0180, 0x019c, 0x01b5, 0x01cc, 0x01f5, -+ 0x0219, 0x023a, 0x0258, 0x028e, 0x02be, 0x02e9, 0x0310, 0x0356, 0x0394, 0x03cc, 0x0400, -+ -+ //2.4 -+ 0x0000, 0x004C, 0x0065, 0x0078, 0x0087, 0x0094, 0x00A0, 0x00ab, 0x00b5, 0x00c6, 0x00d6, -+ 0x00e4, 0x00f1, 0x0109, 0x011E, 0x0131, 0x0142, 0x0161, 0x017D, 0x0197, 0x01AE, 0x01d8, -+ 0x01fd, 0x021F, 0x023E, 0x0276, 0x02a8, 0x02d5, 0x02ff, 0x0349, 0x038C, 0x03C8, 0x0400, -+ -+ //2.3 -+ 0x0000, 0x0043, 0x005b, 0x006d, 0x007c, 0x0088, 0x0094, 0x009e, 0x00a7, 0x00b8, 0x00c8, -+ 0x00d6, 0x00e2, 0x00fa, 0x010e, 0x0121, 0x0132, 0x0151, 0x016d, 0x0187, 0x019e, 0x01c8, -+ 0x01ee, 0x0210, 0x0230, 0x0269, 0x029c, 0x02ca, 0x02f5, 0x0342, 0x0387, 0x03c6, 0x0400, -+ */ -+ //2.2 -+ 0x0000, 0x003c, 0x0052, 0x0063, 0x0070, 0x007c, 0x0087, 0x0091, 0x0094, 0x00ab, 0x00b9, -+ 0x00c7, 0x00d3, 0x00ea, 0x00fe, 0x0111, 0x0122, 0x0141, 0x015d, 0x0176, 0x018d, 0x01b8, -+ 0x01de, 0x0201, 0x0221, 0x025b, 0x028f, 0x02bf, 0x02eb, 0x033b, 0x0382, 0x03c3, 0x0400, -+ -+ //2.1 -+ 0x0000, 0x0034, 0x0049, 0x0058, 0x0065, 0x0070, 0x007b, 0x0084, 0x008d, 0x009d, 0x00ab, -+ 0x00b8, 0x00c4, 0x00da, 0x00ee, 0x0100, 0x0111, 0x0130, 0x014b, 0x0164, 0x017c, 0x01a7, -+ 0x01cd, 0x01f0, 0x0211, 0x024c, 0x0281, 0x02b2, 0x02e0, 0x0332, 0x037c, 0x03c0, 0x0400, -+ -+ //2.0 -+ 0x0000, 0x002d, 0x0040, 0x004e, 0x005a, 0x0065, 0x006e, 0x0077, 0x0080, 0x008f, 0x009c, -+ 0x00a9, 0x00b5, 0x00ca, 0x00dd, 0x00ef, 0x0100, 0x011e, 0x0139, 0x0152, 0x016a, 0x0194, -+ 0x01bb, 0x01de, 0x0200, 0x023c, 0x0273, 0x02a5, 0x02d4, 0x0329, 0x0376, 0x03bd, 0x0400, -+ -+ //1.9 -+ 0x0000, 0x0026, 0x0037, 0x0044, 0x004f, 0x0059, 0x0062, 0x006a, 0x0072, 0x0081, 0x008e, -+ 0x009a, 0x00a5, 0x00b9, 0x00cc, 0x00dd, 0x00ed, 0x010b, 0x0126, 0x013f, 0x0156, 0x0181, -+ 0x01a8, 0x01cc, 0x01ed, 0x022b, 0x0263, 0x0296, 0x02c6, 0x031f, 0x0370, 0x03ba, 0x0400, -+ -+ //1.8 ap30 -+ 0x0000, 0x0020, 0x002f, 0x003a, 0x0045, 0x004e, 0x0056, 0x005e, 0x0065, 0x0073, 0x007f, -+ 0x008a, 0x0095, 0x00a9, 0x00bb, 0x00cb, 0x00db, 0x00f8, 0x0112, 0x012b, 0x0142, 0x016d, -+ 0x0194, 0x01b8, 0x01da, 0x0218, 0x0251, 0x0286, 0x02b8, 0x0314, 0x0368, 0x03b6, 0x0400, -+ //default -+ -+ 0x0000, 0x0017, 0x0032, 0x0046, 0x0056, 0x0064, 0x0071, 0x007c, 0x0086, 0x0099, 0x00a9, -+ 0x00b8, 0x00c6, 0x00df, 0x00f5, 0x0109, 0x011b, 0x013d, 0x015a, 0x0175, 0x018d, 0x01ba, -+ 0x01e1, 0x0205, 0x0225, 0x0261, 0x0295, 0x02c5, 0x02f1, 0x033f, 0x0385, 0x03c5, 0x0400 -+ -+ }; -+ -+ int i, ret; -+ /* -+ for(i = 0; i < 33; i++) -+ { -+ ret = adcm2700_write(regss[i], value[table][i]); -+ if(ret < 0) -+ { -+ dbg_print("adcm2700 write error!"); -+ return -1; -+ } -+ } -+ */ -+ -+ for(i = 0; i < 33; i++) -+ { -+ ret = adcm2700_write(regsv[i], value[table][i]); -+ if(ret < 0) -+ { -+ dbg_print("adcm2700 write error!"); -+ return -1; -+ } -+ } -+ -+ for(i = 0; i < 33; i++) -+ { -+ ret = adcm2700_write(regs[i], value[table][i]); -+ if(ret < 0) -+ { -+ dbg_print("adcm2700 write error!"); -+ return -1; -+ } -+ } -+ return ADCM_ERR_NONE; -+} -+/*set picture style(normal/black white/sepia/solarize/neg.art)*/ -+int adcm2700_set_style(V4l_PIC_STYLE style) -+{ -+ const u16 regs1[] = {EREG_CC_COEF_00, EREG_CC_COEF_01, EREG_CC_COEF_02, -+ EREG_CC_COEF_10, EREG_CC_COEF_11, EREG_CC_COEF_12, -+ EREG_CC_COEF_20, EREG_CC_COEF_21, EREG_CC_COEF_22}; -+ -+ // 0 - normal 1 - black white 2 - sepia -+ const u16 value1[][9] = -+ { -+ //{0x02f9, 0x0f03, 0x0f02, 0x0f4f, 0x025c, 0x0f54, 0x0fe0, 0x0e4a, 0x02d5}, //normal settings -+ -+ {0x01f0, 0x0f88, 0x0f88, -+ 0x0f88, 0x01f0, 0x0f88, -+ 0x0f88, 0x0f88, 0x01f0}, -+ -+ {0x003b, 0x00c8, 0x0fcf, 0x003b, 0x00c8, 0x0fcf, 0x003b, 0x00c8, 0x0fcf}, //black white -+ {0x005c, 0x0131, 0x0fb6, 0x0030, 0x00a2, 0x0fd9, 0x001a, 0x0058, 0x0feb}, //sepia -+ }; -+ -+ -+ u16 * reg_value; -+ u16 reg_count; -+ int i; -+ -+ switch(style) -+ { -+ case V4l_STYLE_BLACK_WHITE: -+ adcm2700_set_gamma(0); -+ reg_value = value1[1]; -+ reg_count = 9; -+ break; -+ case V4l_STYLE_SEPIA: -+ adcm2700_set_gamma(0); -+ reg_value = value1[2]; -+ reg_count = 9; -+ break; -+ case V4l_STYLE_SOLARIZE: -+ adcm2700_set_gamma(1); -+ return ADCM_ERR_NONE; -+ case V4l_STYLE_NEG_ART: -+ adcm2700_set_gamma(2); -+ return ADCM_ERR_NONE; -+ default: -+ adcm2700_set_gamma(0); -+ // adcm2700_reg_write(SREG_ILLUM, illum); -+ return ADCM_ERR_NONE; -+ } -+ -+ for(i = 0; i < reg_count; i++) -+ { -+ adcm2700_write(regs1[i], reg_value[i]); -+ } -+ return ADCM_ERR_NONE; -+} -+ -+/*set picture light(auto/direct sun/incandescent/fluorescent)*/ -+u16 adcm2700_get_light_v(V4l_PIC_WB light) -+{ /* -+ const u16 regs1[] = {EREG_CC_COEF_00, EREG_CC_COEF_01, EREG_CC_COEF_02, -+ EREG_CC_COEF_10, EREG_CC_COEF_11, EREG_CC_COEF_12, -+ EREG_CC_COEF_20, EREG_CC_COEF_21, EREG_CC_COEF_22}; -+ -+ const u16 value1[][9] = -+ { -+ {0x02f9, 0x0f03, 0x0f02, 0x0f4f, 0x025c, 0x0f54, 0x0fe0, 0x0e4a, 0x02d5}, //default -+ {0x0235, 0x0f8f, 0x0f3b, 0x0f63, 0x01f0, 0x0fad, 0x000d, 0x0eb2, 0x0241}, //day -+ {0x0235, 0x0f46, 0x0f85, 0x0f64, 0x01fc, 0x0f9f, 0x0008, 0x0e8d, 0x026b}, //fluorescent -+ {0x023a, 0x0f34, 0x0f92, 0x0f5a, 0x0218, 0x0f8e, 0x0ffa, 0x0deb, 0x031b}, //tungsten -+ }; -+ int i, index; -+ switch(light) -+ { -+ case V4l_WB_DIRECT_SUN: -+ index = 1; -+ break; -+ case V4l_WB_INCANDESCENT: -+ index = 3; -+ break; -+ case V4l_WB_FLUORESCENT: -+ index = 2; -+ break; -+ default: -+ index = 0; -+ break; -+ } -+ for(i = 0; i< 9; i++) -+ { -+ adcm2700_write(regs1[i], value1[index][i]); -+ } -+ -+ */ -+ -+ u16 value = adcm2700_reg_read(SREG_ILLUM); -+ value &= ~0x0007; -+ switch(light) -+ { -+ case V4l_WB_DIRECT_SUN: -+ value |= 0x0002; -+ break; -+ case V4l_WB_INCANDESCENT: -+ value |= 0x0006; -+ break; -+ case V4l_WB_FLUORESCENT: -+ value |= 0x0004; -+ break; -+ default: -+ break; -+ } -+ return value; -+} -+/* Sunny - 5500K daylight */ -+const u16 agilent_sunny_color[] = -+{0x0214, 0x0F6E, 0x0F7C, -+ 0x0F58, 0x022D, 0x0F79, -+ 0x0FF4, 0x0EB3, 0x0257}; -+ -+/* Cloudy - 7500K daylight */ -+const u16 agilent_cloudy_color[] = -+{0x021B, 0x0F8D, 0x0F56, -+ 0x0F5C, 0x0226, 0x0F7D, -+ 0x0FF5, 0x0EE7, 0x0223}; -+ -+/* Indoor - home tungsten */ -+const u16 agilent_home_tungsten_color[] = -+{0x0243, 0x0EDD, 0x0FDF, -+ 0x0F3B, 0x0273, 0x0F50, -+ 0x0FA4, 0x0D9F, 0x03BB}; -+ -+/* Indoor - office cool white fluorescent */ -+const u16 agilent_office_cool_white_fluorescent_color[] = -+{0x01CF, 0x0F6E, 0x0FC1, -+ 0x0F72, 0x020D, 0x0F7F, -+ 0x0FEF, 0x0E5A, 0x02B6}; -+ -+/* Night tungsten */ -+const u16 agilent_night_tungsten_color[] = -+{0x0243, 0x0EDD, 0x0FDF, -+ 0x0F3B, 0x0273, 0x0F50, -+ 0x0FA4, 0x0D9F, 0x03BB}; -+ -+/* Automatic (generic default setting) 6500K daylight */ -+const u16 agilent_automatic_color[] = -+{0x02F4, 0x0F27, 0x0F30, -+ 0x0F0C, 0x02F2, 0x0F4E, -+ 0x0FE8, 0x0E2E, 0x0335}; -+ -+int adcm2700_set_light(V4l_PIC_WB light) -+{ -+ // u16 value = adcm2700_get_light_v(light); -+ // adcm2700_reg_write(SREG_ILLUM, value); -+ -+ const u16 regs1[] = {EREG_CC_COEF_00, EREG_CC_COEF_01, EREG_CC_COEF_02, -+ EREG_CC_COEF_10, EREG_CC_COEF_11, EREG_CC_COEF_12, -+ EREG_CC_COEF_20, EREG_CC_COEF_21, EREG_CC_COEF_22}; -+ const u16 agilent_default[] = {0x02f9, 0x0f03, 0x0f02, 0x0f4f, 0x025c, 0x0f54, 0x0fe0, 0x0e4a, 0x02d5}; -+ /* -+ const u16 value1[][9] = -+ { -+ {0x02f9, 0x0f03, 0x0f02, 0x0f4f, 0x025c, 0x0f54, 0x0fe0, 0x0e4a, 0x02d5}, //default -+ {0x0235, 0x0f8f, 0x0f3b, 0x0f63, 0x01f0, 0x0fad, 0x000d, 0x0eb2, 0x0241}, //day -+ {0x0235, 0x0f46, 0x0f85, 0x0f64, 0x01fc, 0x0f9f, 0x0008, 0x0e8d, 0x026b}, //fluorescent -+ {0x023a, 0x0f34, 0x0f92, 0x0f5a, 0x0218, 0x0f8e, 0x0ffa, 0x0deb, 0x031b}, //tungsten -+ }; -+ */ -+ int i; -+ const u16 * values = NULL; -+ u16 v = adcm2700_reg_read(EREG_AF_CTRL1); -+ switch(light) -+ { -+ case V4l_WB_DIRECT_SUN: -+ values = agilent_sunny_color; -+ adcm2700_write(EREG_AF_CTRL1, v&(~0x0002)); -+ break; -+ case V4l_WB_INCANDESCENT: -+ values = agilent_night_tungsten_color; -+ adcm2700_write(EREG_AF_CTRL1, v&(~0x0002)); -+ break; -+ case V4l_WB_FLUORESCENT: -+ values = agilent_office_cool_white_fluorescent_color; -+ adcm2700_write(EREG_AF_CTRL1, v&(~0x0002)); -+ break; -+ default: -+ values = agilent_automatic_color; -+ adcm2700_write(EREG_AF_CTRL1, v|0x0002); -+ break; -+ } -+ if(values != agilent_automatic_color) -+ { -+ for(i = 0; i < 9; i++) -+ { -+ adcm2700_write(regs1[i], values[i]); -+ } -+ } -+ return 0; -+} -+ -+/*set picture brightness*/ -+int adcm2700_set_bright(int bright) -+{ -+ const u16 target[] = -+ { -+ 0x0010, // -2.0 EV -+ 0x0015, // -1.5 EV -+ 0x0020, // -1.0 EV -+ 0x0030, // -0.5 EV -+ 0x0040, // 0.0 EV -+ 0x0060, // +0.5 EV -+ 0x0080, // +1.0 EV -+ 0x00C0, // +1.5 EV -+ 0x00FF // +2.0 EV -+ }; -+ -+ if(bright < -4 || bright > 4) -+ { -+ return ADCM_ERR_PARAMETER; -+ } -+ adcm2700_write(EREG_AE_TARGET, target[bright+4]); -+ return ADCM_ERR_NONE; -+} -+ -+#define ADCM2700_PROC_CTRL_V_REG 0x0112 -+#define ADCM2700_PROC_CTRL_S_REG 0x0132 -+ -+#define ADCM2700_AV_CENTER_COL_REG 0x106e -+#define ADCM2700_AV_CENTER_ROW_REG 0x1070 -+#define ADCM2700_AV_OVAL_FACT_REG 0x1094 -+ -+ -+#define ADCM2700_PROC_CTRL_V_REG 0x0112 -+#define ADCM2700_PROC_CTRL_S_REG 0x0132 -+ -+#define ADCM2700_AV_LEFT_TOP_REG 0x106a -+#define ADCM2700_AV_RIGHT_BOT_REG 0x106c -+#define ADCM2700_AV_CENTER_COL_REG 0x106e -+#define ADCM2700_AV_CENTER_ROW_REG 0x1070 -+#define ADCM2700_AV_OVAL_FACT_REG 0x1094 -+ -+#define ADCM2700_AV_RED_RAM_REG 0x1800 -+#define ADCM2700_AV_GREEN_RAM_REG 0x1840 -+#define ADCM2700_AV_BLUE_RAM_REG 0x1880 -+ -+unsigned short AV_BLUE_2700[32] = -+{ -+ 0x47, 0x49, 0x4b, 0x4d, 0x50, 0x52, 0x55, 0x58, -+ 0x5a, 0x5d, 0x60, 0x63, 0x66, 0x69, 0x6d, 0x71, -+ 0x75, 0x79, 0x7d, 0x82, 0x87, 0x8d, 0x93, 0x9a, -+ 0xa1, 0xa9, 0xb2, 0xbd, 0xc8, 0xd6, 0xe5, 0xf7 -+}; -+ -+unsigned short AV_GREEN_2700[32] = -+{ -+ 0x44, 0x48, 0x4b, 0x4f, 0x52, 0x56, 0x5a, 0x5e, -+ 0x63, 0x67, 0x6c, 0x70, 0x75, 0x7b, 0x80, 0x86, -+ 0x8c, 0x92, 0x98, 0x9f, 0xa6, 0xae, 0xb5, 0xbd, -+ 0xc6, 0xcf, 0xd8, 0xe2, 0xed, 0xf8, 0x103, 0x10f -+}; -+ -+unsigned short AV_RED_2700[32] = -+{ -+ 0x43, 0x47, 0x4b, 0x50, 0x54, 0x59, 0x5e, 0x63, -+ 0x69, 0x6f, 0x75, 0x7b, 0x82, 0x89, 0x90, 0x97, -+ 0x9e, 0xa6, 0xae, 0xb6, 0xbe, 0xc6, 0xce, 0xd6, -+ 0xde, 0xe6, 0xee, 0xf6, 0xfe, 0x103, 0x104, 0x103 -+}; -+ -+ -+void adcm2700_color_init(void) -+{ -+ u16 regdata; -+ int count; -+ -+ adcm2700_reg_write(ADCM2700_AV_CENTER_COL_REG, 0x0146); -+ adcm2700_reg_write(ADCM2700_AV_CENTER_ROW_REG, 0x00fc); -+ adcm2700_reg_write(ADCM2700_AV_OVAL_FACT_REG, 0x10e); -+ -+ for(count = 0; count < 32; count++) -+ { -+ adcm2700_reg_write(ADCM2700_AV_RED_RAM_REG+count*2, AV_RED_2700[count]); -+ } -+ -+ for(count = 0; count < 32; count++) -+ { -+ adcm2700_reg_write(ADCM2700_AV_GREEN_RAM_REG+count*2, AV_GREEN_2700[count]); -+ } -+ -+ for(count = 0; count < 32; count++) -+ { -+ adcm2700_reg_write(ADCM2700_AV_BLUE_RAM_REG+count*2, AV_BLUE_2700[count]); -+ } -+ -+ -+ /* video mode sharpening enable*/ -+ regdata = adcm2700_reg_read(ADCM2700_PROC_CTRL_V_REG); -+ adcm2700_reg_write(ADCM2700_PROC_CTRL_V_REG, regdata|0x4800); -+ -+ /* still mode sharpening enable*/ -+ regdata = adcm2700_reg_read(ADCM2700_PROC_CTRL_S_REG); -+ adcm2700_reg_write(ADCM2700_PROC_CTRL_S_REG, regdata|0x4800); -+ -+ -+ /* disable automatic dark*/ -+ regdata = 0x64; -+ adcm2700_reg_write(0x081C, regdata); -+} -+ -+int adcm2700_set_flicker(int flicker) -+{ -+ -+ u16 old = adcm2700_reg_read(EREG_AF_CTRL2); -+ u16 old1 = adcm2700_reg_read(SREG_ILLUM); -+ old1 &= ~(0x18); -+ dbg_print("set flicker to %d", flicker); -+ if(flicker == 50) -+ { -+ adcm2700_reg_write(SREG_ILLUM, old1|0x08); -+ adcm2700_write(EREG_AF_CTRL2, old&(~0x02)); -+ //1000 = 100000/50/2 -+ adcm2700_write(EREG_AE_ETIME_DFLT, 1000); -+ } -+ else if(flicker == 60) -+ { -+ adcm2700_reg_write(SREG_ILLUM, old1|0x10); -+ adcm2700_write(EREG_AF_CTRL2, old|0x02); -+ // 833 = 100000/60/2 -+ adcm2700_write(EREG_AE_ETIME_DFLT, 833); -+ } -+ else -+ { -+ return ADCM_ERR_PARAMETER; -+ } -+ return 0; -+} -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/adcm2700_hw.h linux-2.6.16.5-exz/drivers/media/video/adcm2700_hw.h ---- linux-2.6.16.5/drivers/media/video/adcm2700_hw.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/adcm2700_hw.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,533 @@ -+/*================================================================================ -+ -+ Header Name: adcm2700_hw.h -+ -+General Description: Camera module adcm2700 interface header file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+wangfei(w20239) 02/05/2004 LIBdd74309 Set frame rate in video mode -+wangfei(w20239) 02/26/2004 LIBdd81055 New chip id support -+wangfei(w20239) 03/08/2004 LIBdd84578 Photo effects setting -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+ -+#ifndef _PXA_ADCM_2700_HW_H__ -+#define _PXA_ADCM_2700_HW_H__ -+ -+#include "camera.h" -+/*********************************************************************** -+ * -+ * Constants & Structures -+ * -+ ***********************************************************************/ -+ -+/* ADCM_WINDOWSIZE */ -+typedef struct { -+ u16 width; -+ u16 height; -+} adcm_window_size; -+ -+ -+// Revision constants -+#define PIPE_REV 0x60 -+#define PIPE_REV_NEW 0x61 -+#define SENSOR_REV 0x60 -+ -+// Calculating the Module Block Number -+#define BLOCK(a) (u8)((a) >> 7) // register's module block address. -+#define OFFSET(a) (u8)((a) & 0x7F ) // register's offset to this block. -+ -+// Return codes -+#define ADCM_ERR_NONE 0x00 -+#define ADCM_ERR_TIMEOUT -1 -+#define ADCM_ERR_PARAMETER -2 -+ -+// Auto Exposure Frequency -+#define AEF_50HZ 0x20 -+#define AEF_60HZ 0x40 -+ -+// Non JEPG Output Format -+#define O_FORMAT_888RGB 0 //0b0000 // 888 RGB (1 pixel in 3 bytes ) -+#define O_FORMAT_666_A_RGB 1 //0b0001 // 666 A RGB (tight pack, 4 pixels in 9 bytes) -+#define O_FORMAT_666_B_RGB 2 //0b0010 // 666 B RGB (loose pack, 1 pixel in 3 bytes,left or right justified) -+#define O_FORMAT_565_RGB 3 //0b0011 // 565 RGB (1 pixel in 2 bytes) -+#define O_FORMAT_444_A_RGB 4 //0b0100 // 444 A RGB (tight pack, 2 pixels per 3 bytes, RG BR GB) -+#define O_FORMAT_444_B_RGB 5 //0b0101 // 444 B RGB (loose pack, 1 pixel per 2 bytes,RG B0 or 0R GB) -+#define O_FORMAT_444_C_RGV 6 //0b0110 // 444 C RGB (sparse pack, 1 pixel per three bytes,R0 G0 B0 or 0R 0G 0B) -+#define O_FORMAT_332_RGB 7 //0b0111 // 332 RGB (1 pixel in 1 byte) -+#define O_FORMAT_422_A_YCbYCr 8 //0b1000 // 4:2:2 A YCbYCr (Y1 Cb12 Y2 CRL2 order) -+#define O_FORMAT_422_B_YCbYCr 9 //0b1001 // 4:2:2 B YCbYCr (Cb12 Y1 CRL2 Y2 order) -+#define O_FORMAT_422_C_YCbYCr 10 //0b1010 // 4:2:2 C YCbYCr (Y1 CRL2 Y2 Cb12 order) -+#define O_FORMAT_422_D_YCbYCr 11 //0b1011 // 4:2:2 D YCbYCr (CRL2 Y1 Cb12 Y2 order) -+#define O_FORMAT_444_YCbYCr 12 //0b1100 // 4:4:4 YCbCr (1 pixels per 3 bytes) -+#define O_FORMAT_400_B_YCbYCr 13 //0b1101 // 4:0:0 YCbCr (Greyscale, 1 pixel per 1 byte) -+#define O_FORMAT_RAWBPA 14 //0b1110 // RAWBPA (with AWB and BPA) -+#define O_FORMAT_RAW 15 //0b1111 // RAW (without AWB and BPA) -+ -+// Camera Mode -+#define VIEWFINDER_MODE 0x10 -+#define STILLFRAME_MODE 0x20 -+ -+// Others -+#define adcm2700__TIMEOUT 100 // ms to timeout. -+#define BLOCK_SWITCH_CMD ((u8)0xFE) // Block Switch Code: 0x7F, CMD = Code << 1 -+#define VOLTS_28 0x28 -+ -+ -+/************************************************************************************* -+ * -+ * Simple Control Registers Address -+ * -+ *************************************************************************************/ -+// name addr description default page -+#define SREG_ID 0x0000 //Chip ID 0x0060 139 -+#define SREG_CONTROL 0x0002 //Camera control 0x0001 140 -+#define SREG_STATUS 0x0004 //Camera status 0x0004 142 -+#define SREG_CLK_FREQ 0x0006 //Input clock frequency 0x32c8 144 -+#define SREG_SIZE 0x0008 //Image size and orientation 0x0605 145 -+#define SREG_OUTPUT_FORMAT 0x000a //Output format 0x0909 147 -+#define SREG_EXPOSURE 0x000c //Exposure 0x03e8 149 -+#define SREG_EXP_ADJ 0x000e //Exposure adjustment 0x0000 150 -+#define SREG_ILLUM 0x0010 //Illumination 0x0000 151 -+#define SREG_FRAME_RATE 0x0012 //Requested frame rate 0x0096 152 -+#define SREG_A_FRAME_RATE 0x0016 //Actual frame rate 0x0096 154 -+#define SREG_SENSOR_WID_V 0x0018 //Sensor window width, video mode 0x0000 155 -+#define SREG_SENSOR_HGT_V 0x001a //Sensor window height, video mode 0x0000 156 -+#define SREG_OUTPUT_WID_V 0x001c //Output window width, video mode 0x0000 157 -+#define SREG_OUTPUT_HGT_V 0x001e //Output window height, video mode 0x0000 158 -+#define SREG_SENSOR_WID_S 0x0020 //Sensor window width, still mode 0x0000 159 -+#define SREG_SENSOR_HGT_S 0x0022 //Sensor window height, still mode 0x0000 160 -+#define SREG_OUTPUT_WID_S 0x0024 //Output window width, still mode 0x0000 161 -+#define SREG_OUTPUT_HGT_S 0x0026 //Output window height, still mode 0x0000 162 -+ -+/************************************************************************************* -+ * -+ * Expert Hardware Registers -+ * -+ *************************************************************************************/ -+// name addr description default page -+#define EREG_I_CLK_DIV 0x0080 //Initial clock divider 0x0001 166 -+#define EREG_CTL_CLK_DIV 0x0082 //Clock dividers for control -+ //and serial interfaces 0x4000 167 -+#define EREG_SEN_CLK_DIV 0x0084 //Sensor clock dividers 0x0000 168 -+#define EREG_IP_CLK_DIV 0x0086 //Clock dividers for image pipeline 0x0000 169 -+#define EREG_TST_MODE 0x0088 //Latched test mode 0x0000 170 -+#define EREG_SER_ADDR 0x008a //Serial interface device address 0x0053 171 -+#define EREG_SER_PARM 0x008c //Serial Interface parameters 0x0000 172 -+#define EREG_OUT_CTRL 0x008e //Output control 0x0000 173 -+#define EREG_PLL_CTRL 0x0090 //PLL control 0x0024 174 -+#define EREG_PLL_DIV_L 0x0092 //PLL divisors, large values 0x1d09 175 -+#define EREG_PLL_DIV_S 0x0094 //PLL divisors, small values 0x0200 176 -+ -+/************************************************************************************* -+ * -+ * Expert Control Registers -+ * -+ *************************************************************************************/ -+// name addr description default page -+#define EREG_SZR_IN_WID_V 0x0100 //Sizer input width, video mode 0x0280 184 -+#define EREG_SZR_IN_HGT_V 0x0102 //Sizer input height, video mode 0x01e0 185 -+#define EREG_SZR_OUT_WID_V 0x0104 //Sizer output width, video mode 0x0140 186 -+#define EREG_SZR_OUT_HGT_V 0x0106 //Sizer output height, video mode 0x00f0 187 -+#define EREG_CPP_V 0x0108 //Clocks per pixel, video mode 0x0002 188 -+#define EREG_HBLANK_V 0x010a //Horizontal blanking period, video mode 0x0000 189 -+#define EREG_VBLANK_V 0x010c //Vertical blanking period, video mode 0x0000 190 -+#define EREG_MIN_MAX_F_V 0x010e //Frame convergence rates, video mode 0x0000 191 -+#define EREG_OUTPUT_CTRL_V 0x0110 //Output control, video mode 0x9019 192 -+#define EREG_PROC_CTRL_V 0x0112 //Processing control, video mode 0x0280 194 -+#define EREG_RPT_V 0x0114 //Row processing time, video mode 0x0546 196 -+#define EREG_HYSNC_PER_V 0x0116 //HSYNC period, video mode 0x0a8b 197 -+#define EREG_CLK_DIV_V 0x0118 //Clock divisors, video mode 0x0000 198 -+#define EREG_PARALLEL_CTRL_V 0x011a //Parallel output control, video mode 0x0003 199 -+#define EREG_SEN_CTRL_V 0x011c //Sensor control, video mode 0x0000 200 -+ -+#define EREG_SZR_IN_WID_S 0x0120 //Sizer input width, still mode 0x0280 202 -+#define EREG_SZR_IN_HGT_S 0x0122 //Sizer input height, still mode 0x01e0 203 -+#define EREG_SZR_OUT_WID_S 0x0124 //Sizer output width, still mode 0x0280 204 -+#define EREG_SZR_OUT_HGT_S 0x0126 //Sizer output height, still mode 0x01e0 205 -+#define EREG_CPP_S 0x0128 //Clocks per pixel, still mode 0x0002 206 -+#define EREG_HBLANK_S 0x012a //Horizontal blanking period, still mode 0x0000 207 -+#define EREG_VBLANK_S 0x012c //Vertical blanking period, still mode 0x0000 208 -+#define EREG_MIN_MAX_F_S 0x012e //Frame convergence rates, still mode 0x0002 209 -+#define EREG_OUTPUT_CTRL_S 0x0130 //Output control, still mode 0x8019 210 -+#define EREG_PROC_CTRL_S 0x0132 //Processing control, still mode 0x0280 212 -+#define EREG_RPT_S 0x0134 //Row processing time, still mode 0x0546 214 -+#define EREG_HYSNC_PER_S 0x0136 //HSYNC period, still mode 0x0545 215 -+#define EREG_CLK_DIV_S 0x0138 //Clock divisors, still mode 0x0000 216 -+#define EREG_PARALLEL_CTRL_S 0x013a //Parallel output control, still mode 0x0000 217 -+#define EREG_SEN_CTRL_S 0x013c //Sensor control, still mode 0x0000 218 -+ -+#define EREG_AF_CTRL1 0x0140 //Auto functions control 1 0x0013 220 -+#define EREG_AF_CTRL2 0x0142 //Auto functions control 2 0x0001 221 -+#define EREG_AF_STATUS 0x0144 //Auto functions status 0x0000 222 -+#define EREG_SOF_CODES 0x0146 //Start of frame codes 0xfeff 223 -+#define EREG_EOF_CODES 0x0148 //End of frame codes 0x0100 224 -+#define EREG_ABL_TARGET 0x014a //Auto black level target 0x0005 225 -+#define EREG_ABL_MAX_BIN 0x014c //Auto black level maximum bin 0x0003 226 -+#define EREG_ABL_MAX_BLACK 0x014e //Auto black level maximum black 0x0010 227 -+#define EREG_AE_GAIN_MIN 0x0150 //Auto exposure gain minimum 0x01c0 228 -+#define EREG_AE_GAIN_MIN_P 0x0152 //Auto exposure gain minimum, preferred 0x0200 229 -+#define EREG_AE_GAIN_MAX 0x0154 //Auto exposure gain maximum 0x0500 230 -+#define EREG_AE_GAIN_DFLT 0x0156 //Auto exposure gain default 0x0200 231 -+#define EREG_AE_ETIME_MIN 0x0158 //Auto exposure time minimum 0x0005 232 -+#define EREG_AE_ETIME_MAX 0x015a //Auto exposure time maximum 0x4e20 233 -+#define EREG_AE_ETIME_DFLT 0x015c //Auto exposure time default 0x03e8 234 -+#define EREG_AE_TARGET 0x015e //Auto exposure target 0x0040 235 -+#define EREG_AE_TOL_ACQ 0x0160 //Auto exposure tolerance acquire 0x0118 236 -+#define EREG_AE_TOL_MON 0x0162 //Auto exposure tolerance monitor 0x0118 237 -+#define EREG_AE_MARGIN 0x0164 //Auto exposure margin 0x0120 238 -+#define EREG_AE_DOE_FACTOR 0x0166 //AE deliberate overexposure factor 0x014e 239 -+#define EREG_AE_DOE_MARGIN 0x0168 //AE deliberate overexposure margin 0x0140 240 -+ -+#define EREG_AWB_RED_MIN 0x0170 //AWB minimum red/green ratio 0x00c0 242 -+#define EREG_AWB_RED_MAX 0x0172 //AWB maximum red/green ratio 0x01a6 243 -+#define EREG_AWB_RED_DFLT 0x0174 //AWB default red/green ratio 0x0134 244 -+#define EREG_AWB_BLUE_MIN 0x0176 //AWB minimum blue/green ratio 0x00c0 245 -+#define EREG_AWB_BLUE_MAX 0x0178 //AWB maximum blue/green ratio 0x02a4 246 -+#define EREG_AWB_BLUE_DFLT 0x017a //AWB default blue/green ratio 0x01e4 247 -+#define EREG_AWB_TOL_ACQ 0x017c //Auto white balance tolerance acquire 0x0110 248 -+#define EREG_AWB_TOL_MON 0x017e //Auto white balance tolerance monitor 0x0120 249 -+#define EREG_FIRMWARE_REV 0x0180 //Current firmware revision 0x0152 250 -+#define EREG_FLICK_CFG_1 0x0182 //Flicker configuration 1 0x2aeb 251 -+#define EREG_FLICK_CFG_2 0x0184 //Flicker configuration 2 0x0005 252 -+ -+#define EREG_MAX_SCLK 0x018a //Maximum sensor clock 0x1964 254 -+ -+#define EREG_CSC_00_V 0x0190 //Color conversion coefficient 00, video 0x0026 256 -+#define EREG_CSC_01_V 0x0192 //Color conversion coefficient 01, video 0x004b 256 -+#define EREG_CSC_02_V 0x0194 //Color conversion coefficient 02, video 0x000f 256 -+#define EREG_CSC_10_V 0x0196 //Color conversion coefficient 10, video 0x01ed 256 -+#define EREG_CSC_11_V 0x0198 //Color conversion coefficient 11, video 0x01db 256 -+#define EREG_CSC_12_V 0x019a //Color conversion coefficient 12, video 0x0038 256 -+#define EREG_CSC_20_V 0x019c //Color conversion coefficient 20, video 0x004f 256 -+#define EREG_CSC_21_V 0x019e //Color conversion coefficient 21, video 0x01be 256 -+#define EREG_CSC_22_V 0x01a0 //Color conversion coefficient 22, video 0x01f3 256 -+ -+#define EREG_CSC_OS0_V 0x01a2 //Color space conversion offset 0, video 0x0000 257 -+#define EREG_CSC_OS1_V 0x01a4 //Color space conversion offset 1, video 0x0080 257 -+#define EREG_CSC_OS2_V 0x01a6 //Color space conversion offset 2, video 0x0080 257 -+ -+#define EREG_CSC_00_S 0x01a8 //Color conversion coefficient 00, still 0x0026 258 -+#define EREG_CSC_01_S 0x01aa //Color conversion coefficient 01, still 0x004b 258 -+#define EREG_CSC_02_S 0x01ac //Color conversion coefficient 02, still 0x000f 258 -+#define EREG_CSC_10_S 0x01ae //Color conversion coefficient 10, still 0x01ed 258 -+#define EREG_CSC_11_S 0x01b0 //Color conversion coefficient 11, still 0x01db 258 -+#define EREG_CSC_12_S 0x01b2 //Color conversion coefficient 12, still 0x0038 258 -+#define EREG_CSC_20_S 0x01b4 //Color conversion coefficient 20, still 0x004f 258 -+#define EREG_CSC_21_S 0x01b6 //Color conversion coefficient 21, still 0x01be 258 -+#define EREG_CSC_22_S 0x01b8 //Color conversion coefficient 22, still 0x01f3 258 -+ -+#define EREG_CSC_OS0_S 0x01ba //Color space conversion offset 0, still 0x0000 259 -+#define EREG_CSC_OS1_S 0x01bc //Color space conversion offset 1, still 0x0080 259 -+#define EREG_CSC_OS2_S 0x01be //Color space conversion offset 2, still 0x0080 259 -+ -+ -+#define EREG_TM_COEF_00_V 0x01c0 //Tonemap coefficient 00, video 0x0000 261 -+#define EREG_TM_COEF_01_V 0x01c2 //Tonemap coefficient 01, video 0x0017 261 -+#define EREG_TM_COEF_02_V 0x01c4 //Tonemap coefficient 02, video 0x0032 261 -+#define EREG_TM_COEF_03_V 0x01c6 //Tonemap coefficient 03, video 0x0046 261 -+#define EREG_TM_COEF_04_V 0x01c8 //Tonemap coefficient 04, video 0x0056 261 -+#define EREG_TM_COEF_05_V 0x01ca //Tonemap coefficient 05, video 0x0064 261 -+#define EREG_TM_COEF_06_V 0x01cc //Tonemap coefficient 06, video 0x0071 261 -+#define EREG_TM_COEF_07_V 0x01ce //Tonemap coefficient 07, video 0x007c 261 -+#define EREG_TM_COEF_08_V 0x01d0 //Tonemap coefficient 08, video 0x0086 261 -+#define EREG_TM_COEF_09_V 0x01d2 //Tonemap coefficient 09, video 0x0099 261 -+#define EREG_TM_COEF_10_V 0x01d4 //Tonemap coefficient 10, video 0x00a9 261 -+#define EREG_TM_COEF_11_V 0x01d6 //Tonemap coefficient 11, video 0x00b8 261 -+#define EREG_TM_COEF_12_V 0x01d8 //Tonemap coefficient 12, video 0x00c6 261 -+#define EREG_TM_COEF_13_V 0x01da //Tonemap coefficient 13, video 0x00df 261 -+#define EREG_TM_COEF_14_V 0x01dc //Tonemap coefficient 14, video 0x00f5 261 -+#define EREG_TM_COEF_15_V 0x01de //Tonemap coefficient 15, video 0x0109 261 -+#define EREG_TM_COEF_16_V 0x01e0 //Tonemap coefficient 16, video 0x011b 261 -+#define EREG_TM_COEF_17_V 0x01e2 //Tonemap coefficient 17, video 0x013d 261 -+#define EREG_TM_COEF_18_V 0x01e4 //Tonemap coefficient 18, video 0x015a 261 -+#define EREG_TM_COEF_19_V 0x01e6 //Tonemap coefficient 19, video 0x0175 261 -+#define EREG_TM_COEF_20_V 0x01e8 //Tonemap coefficient 20, video 0x018d 261 -+#define EREG_TM_COEF_21_V 0x01ea //Tonemap coefficient 21, video 0x01ba 261 -+#define EREG_TM_COEF_22_V 0x01ec //Tonemap coefficient 22, video 0x01e1 261 -+#define EREG_TM_COEF_23_V 0x01ee //Tonemap coefficient 23, video 0x0205 261 -+#define EREG_TM_COEF_24_V 0x01f0 //Tonemap coefficient 24, video 0x0225 261 -+#define EREG_TM_COEF_25_V 0x01f2 //Tonemap coefficient 25, video 0x0261 261 -+#define EREG_TM_COEF_26_V 0x01f4 //Tonemap coefficient 26, video 0x0295 261 -+#define EREG_TM_COEF_27_V 0x01f6 //Tonemap coefficient 27, video 0x02c5 261 -+#define EREG_TM_COEF_28_V 0x01f8 //Tonemap coefficient 28, video 0x02f1 261 -+#define EREG_TM_COEF_29_V 0x01fa //Tonemap coefficient 29, video 0x033f 261 -+#define EREG_TM_COEF_30_V 0x01fc //Tonemap coefficient 30, video 0x0385 261 -+#define EREG_TM_COEF_31_V 0x01fe //Tonemap coefficient 31, video 0x03c5 261 -+#define EREG_TM_COEF_32_V 0x0200 //Tonemap coefficient 32, video 0x0400 261 -+ -+#define EREG_TM_COEF_00_S 0x0202 //Tonemap coefficient 00, still 0x0000 262 -+#define EREG_TM_COEF_01_S 0x0204 //Tonemap coefficient 01, still 0x0017 262 -+#define EREG_TM_COEF_02_S 0x0206 //Tonemap coefficient 02, still 0x0032 262 -+#define EREG_TM_COEF_03_S 0x0208 //Tonemap coefficient 03, still 0x0046 262 -+#define EREG_TM_COEF_04_S 0x020a //Tonemap coefficient 04, still 0x0056 262 -+#define EREG_TM_COEF_05_S 0x020c //Tonemap coefficient 05, still 0x0064 262 -+#define EREG_TM_COEF_06_S 0x020e //Tonemap coefficient 06, still 0x0071 262 -+#define EREG_TM_COEF_07_S 0x0210 //Tonemap coefficient 07, still 0x007c 262 -+#define EREG_TM_COEF_08_S 0x0212 //Tonemap coefficient 08, still 0x0086 262 -+#define EREG_TM_COEF_09_S 0x0214 //Tonemap coefficient 09, still 0x0099 262 -+#define EREG_TM_COEF_10_S 0x0216 //Tonemap coefficient 10, still 0x00a9 262 -+#define EREG_TM_COEF_11_S 0x0218 //Tonemap coefficient 11, still 0x00b8 262 -+#define EREG_TM_COEF_12_S 0x021a //Tonemap coefficient 12, still 0x00c6 262 -+#define EREG_TM_COEF_13_S 0x021c //Tonemap coefficient 13, still 0x00df 262 -+#define EREG_TM_COEF_14_S 0x021e //Tonemap coefficient 14, still 0x00f5 262 -+#define EREG_TM_COEF_15_S 0x0220 //Tonemap coefficient 15, still 0x0109 262 -+#define EREG_TM_COEF_16_S 0x0222 //Tonemap coefficient 16, still 0x011b 262 -+#define EREG_TM_COEF_17_S 0x0224 //Tonemap coefficient 17, still 0x013d 262 -+#define EREG_TM_COEF_18_S 0x0226 //Tonemap coefficient 18, still 0x015a 262 -+#define EREG_TM_COEF_19_S 0x0228 //Tonemap coefficient 19, still 0x0175 262 -+#define EREG_TM_COEF_20_S 0x022a //Tonemap coefficient 20, still 0x018d 262 -+#define EREG_TM_COEF_21_S 0x022c //Tonemap coefficient 21, still 0x01ba 262 -+#define EREG_TM_COEF_22_S 0x022e //Tonemap coefficient 22, still 0x01e1 262 -+#define EREG_TM_COEF_23_S 0x0230 //Tonemap coefficient 23, still 0x0205 262 -+#define EREG_TM_COEF_24_S 0x0232 //Tonemap coefficient 24, still 0x0225 262 -+#define EREG_TM_COEF_25_S 0x0234 //Tonemap coefficient 25, still 0x0261 262 -+#define EREG_TM_COEF_26_S 0x0236 //Tonemap coefficient 26, still 0x0295 262 -+#define EREG_TM_COEF_27_S 0x0238 //Tonemap coefficient 27, still 0x02c5 262 -+#define EREG_TM_COEF_28_S 0x023a //Tonemap coefficient 28, still 0x02f1 262 -+#define EREG_TM_COEF_29_S 0x023c //Tonemap coefficient 29, still 0x033f 262 -+#define EREG_TM_COEF_30_S 0x023e //Tonemap coefficient 30, still 0x0385 262 -+#define EREG_TM_COEF_31_S 0x0240 //Tonemap coefficient 31, still 0x03c5 262 -+#define EREG_TM_COEF_32_S 0x0242 //Tonemap coefficient 32, still 0x0400 262 -+ -+#define EREG_NACC_EGP_1 0x0250 //NACC EGP 1 0x05dc 265 -+#define EREG_NACC_SAT_1 0x0252 //NACC saturation 1 0x0000 265 -+#define EREG_NACC_EGP_2 0x0254 //NACC EGP 2 0x0465 265 -+#define EREG_NACC_SAT_2 0x0256 //NACC saturation 2 0x0040 265 -+#define EREG_NACC_EGP_3 0x0258 //NACC EGP 3 0x02ee 265 -+#define EREG_NACC_SAT_3 0x025a //NACC saturation 3 0x0080 265 -+#define EREG_NACC_EGP_4 0x025c //NACC EGP 4 0x0177 265 -+#define EREG_NACC_SAT_4 0x025e //NACC saturation 4 0x00c0 265 -+#define EREG_NACC_EGP_5 0x0260 //NACC EGP 5 0x0000 265 -+#define EREG_NACC_SAT_5 0x0262 //NACC saturation 5 0x0100 265 -+#define EREG_NACC_EGP_6 0x0264 //NACC EGP 6 0x0000 265 -+#define EREG_NACC_SAT_6 0x0266 //NACC saturation 6 0x0000 265 -+#define EREG_NACC_EGP_7 0x0268 //NACC EGP 7 0x0000 265 -+#define EREG_NACC_SAT_7 0x026a //NACC saturation 7 0x0000 265 -+#define EREG_NACC_EGP_8 0x026c //NACC EGP 8 0x0000 265 -+#define EREG_NACC_SAT_8 0x026e //NACC saturation 8 0x0000 265 -+#define EREG_NACC_BC_00 0x0270 //NACC NACC bright coefficients 00 0x0235 266 -+#define EREG_NACC_BC_01 0x0272 //NACC NACC bright coefficients 01 0xff46 266 -+#define EREG_NACC_BC_02 0x0274 //NACC bright coefficients 02 0xff85 266 -+#define EREG_NACC_BC_10 0x0276 //NACC bright coefficients 10 0xff64 266 -+#define EREG_NACC_BC_11 0x0278 //NACC bright coefficients 11 0x01fc 266 -+#define EREG_NACC_BC_12 0x027a //NACC bright coefficients 12 0xff9f 266 -+#define EREG_NACC_BC_20 0x027c //NACC bright coefficients 20 0x0008 266 -+#define EREG_NACC_BC_21 0x027e //NACC bright coefficients 21 0xfe8d 266 -+#define EREG_NACC_BC_22 0x0280 //NACC bright coefficients 22 0x026b 266 -+#define EREG_NACC_DC_00 0x0282 //NACC dark coefficients 00 0x0048 266 -+#define EREG_NACC_DC_01 0x0284 //NACC dark coefficients 01 0x010b 266 -+#define EREG_NACC_DC_02 0x0286 //NACC dark coefficients 02 0xffaa 266 -+#define EREG_NACC_DC_10 0x0288 //NACC dark coefficients 10 0x0048 266 -+#define EREG_NACC_DC_11 0x028a //NACC dark coefficients 11 0x010b 266 -+#define EREG_NACC_DC_12 0x028c //NACC dark coefficients 12 0xffaa 266 -+#define EREG_NACC_DC_20 0x028e //NACC dark coefficients 20 0x0048 266 -+#define EREG_NACC_DC_21 0x0290 //NACC dark coefficients 21 0x010b 266 -+#define EREG_NACC_DC_22 0x0292 //NACC dark coefficients 22 0xffaa 266 -+ -+/************************************************************************************* -+ * -+ * Expert Sensor Registers -+ * -+ *************************************************************************************/ -+// name addr description default page -+#define EREG_IDENT 0x0800 //Image sensor identification 0x60 272 -+#define EREG_IS_STATUS 0x0801 //Image sensor status 0x00 273 -+#define EREG_ICTRL 0x0805 //Interface control 0x00 275 -+ -+#define EREG_ADC_CTRL 0x0809 //ADC control 0x01 277 -+#define EREG_FWROW 0x080a //Window first row address 0x01 278 -+#define EREG_FWCOL 0x080b //Window first column address 0x01 279 -+#define EREG_LWROW 0x080c //Window last row address 0x7a 280 -+#define EREG_LWCOL 0x080d //Window last column address 0xa2 281 -+#define EREG_CLK_PIXEL 0x080e //Clocks per pixel 0x02 282 -+#define EREG_EREC_PGA 0x080f //Even row, even column(green 1)PGA gain 0x00 283 -+#define EREG_EROC_PGA 0x0810 //Even row, odd column (red) PGA gain 0x00 284 -+#define EREG_OREC_PGA 0x0811 //Odd row, even column (blue) PGA gain 0x00 285 -+#define EREG_OROC_PGA 0x0812 //Odd row, odd column (green 2) PGA gain 0x00 286 -+#define EREG_ROWEXP_L 0x0813 //Row exposure low 0x54 287 -+#define EREG_ROWEXP_H 0x0814 //Row exposure high 0x00 288 -+#define EREG_SROWEXP 0x0815 //Sub row exposure 0x31 289 -+#define EREG_ERROR 0x0816 //Error control 0x00 290 -+ -+#define EREG_HBLANK 0x0819 //Horizontal blank 0x00 292 -+#define EREG_VBLANK 0x081a //Vertical blank 0x00 293 -+#define EREG_CONFIG_1 0x081b //Image sensor configuration 1 0x0e 294 -+#define EREG_CONTROL_1 0x081c //Image sensor control 1 0x24 295 -+ -+#define EREG_CONFIG_2 0x0827 //Image sensor configuration 2 0x00 298 -+#define EREG_GRR_CTRL 0x0828 //Ground reset reference control 0x00 299 -+ -+#define EREG_BIAS_TRM 0x0837 //Bias trim 0x00 301 -+#define EREG_SMP_GR_E2 0x08d7 //Sample ground reference edge 2 0x00 303 -+#define EREG_SMP_GR_E1 0x08d8 //Sample ground reference edge 1 0x10 304 -+#define EREG_SMP_GR_E0 0x08d9 //Sample ground reference edge 0 0x0a 305 -+ -+#define EREG_EXP_GR_E1 0x08dc //Exposure, ground reference edge 1 0x10 307 -+#define EREG_EXP_GR_E0 0x08dd //Exposure, ground reference edge 0 0x06 308 -+#define EREG_GR_POL 0x08df //Ground reference polarity 0xd3 310 -+ -+#define EREG_SMP_RST_E2 0x08eb //Sample, reset edge 2 0x04 312 -+#define EREG_SMP_RST_E1 0x08ec //Sample, reset edge 1 0x10 313 -+#define EREG_SMP_RST_E0 0x08ed //Sample, reset edge 0 0x07 314 -+ -+#define EREG_EXP_RST_E1 0x08f0 //Exposure, reset edge 1 0x10 316 -+#define EREG_EXP_RST_E0 0x08f1 //Exposure, reset edge 1 0x03 317 -+#define EREG_RESET_POL 0x08f3 //Reset polarity enable 0xd3 319 -+ -+#define EREG_SMP_PRST_E2 0x08f5 //Sample, preset edge 2 0x00 321 -+#define EREG_SMP_PRST_E1 0x08f6 //Sample, preset edge 1 0x02 322 -+#define EREG_SMP_PRST_E0 0x08f7 //Sample, preset edge 0 0x0a 323 -+ -+#define EREG_EXP_PRST_E1 0x08fa //Exposure, preset edge 1 0x02 325 -+#define EREG_EXP_PRST_E0 0x08fb //Exposure, preset edge 1 0x06 326 -+#define EREG_PRESET_POL 0x08fd //Preset polarity enable 0xd3 328 -+ -+/************************************************************************************* -+ * -+ * Expert Image Pipeline Registers -+ * -+ *************************************************************************************/ -+// name addr description default page -+ -+#define EREG_CMD_1 0x1002 //Main command 1 0x0000 335 -+#define EREG_CMD_2 0x1004 //Main command 2 (write 1¡¯s only) 0x0002 336 -+#define EREG_OUTPUT_CTRL 0x1008 //Output control, working 0x9019 338 -+#define EREG_PARALLEL_CTRL 0x100a //Parallel output control working copy 0x0000 340 -+#define EREG_SOF_CODE_W 0x100c //Start of frame code working copy 0x00ff 341 -+#define EREG_PEOF_CODES 0x100e //End of frame codes working copy 0x0100 342 -+#define EREG_CCIR_TIMING 0x1010 //CCIR interface timing 0x0000 343 -+#define EREG_R_Y_MAX_MIN 0x1012 //Luminance, Y (or red) maximum/minimum 0xff00 344 -+#define EREG_G_CB_MAX_MIN 0x1014 //Chrominance,Cb(or green)maximum/minimum 0xff00 345 -+#define EREG_B_CR_MAX_MIN 0x1016 //Chrominance,Cr(or blue)maximum/minimum 0xff00 346 -+#define EREG_PROCESS_CTRL 0x1018 //Processing control working copy 0x0280 347 -+#define EREG_BPA_SF_GTHRESH 0x101a //BPA scale factor,green filter threshold 0x0220 349 -+#define EREG_BPA_OUTL_PED 0x101c //BPA outlier, pedestal 0x4008 350 -+#define EREG_BPA_BADPIX_CNT 0x101e //BPA bad pixel count (read only) 0x0000 351 -+#define EREG_SZR_IN_W 0x1020 //Sizer input width 0x0280 352 -+#define EREG_SZR_IN_H 0x1022 //Sizer input height 0x01e0 353 -+#define EREG_SZR_OUT_W 0x1024 //Sizer output width 0x0140 354 -+#define EREG_SZR_OUT_H 0x1026 //Sizer output height 0x00f0 355 -+ -+ -+#define EREG_CC_COEF_00 0x1028 //Color correction coefficient 00 0x02f9 358 -+#define EREG_CC_COEF_01 0x102a //Color correction coefficient 01 0x0f03 358 -+#define EREG_CC_COEF_02 0x102c //Color correction coefficient 02 0x0f02 358 -+#define EREG_CC_COEF_10 0x102e //Color correction coefficient 10 0x0f4f 358 -+#define EREG_CC_COEF_11 0x1030 //Color correction coefficient 11 0x025c 358 -+#define EREG_CC_COEF_12 0x1032 //Color correction coefficient 12 0x0f54 358 -+#define EREG_CC_COEF_20 0x1034 //Color correction coefficient 20 0x0fe0 358 -+#define EREG_CC_COEF_21 0x1036 //Color correction coefficient 21 0x0e4a 358 -+#define EREG_CC_COEF_22 0x1038 //Color correction coefficient 22 0x02d5 358 -+ -+#define EREG_CC_PRE_OS_0 0x103a //Color correction pre-offset 0 0x01f8 360 -+#define EREG_CC_PRE_OS_1 0x103c //Color correction pre-offset 1 0x01f8 360 -+#define EREG_CC_PRE_OS_2 0x103e //Color correction pre-offset 2 0x01f8 360 -+#define EREG_CC_POST_OS_0 0x1040 //Color correction post-offset 0 0x0000 360 -+#define EREG_CC_POST_OS_1 0x1042 //Color correction post-offset 1 0x0000 360 -+#define EREG_CC_POST_OS_2 0x1044 //Color correction post-offset 2 0x0000 360 -+ -+#define EREG_CSC_COEF_00 0x1046 //Color space conversion coefficient 00 0x0026 363 -+#define EREG_CSC_COEF_01 0x1048 //Color space conversion coefficient 01 0x004b 363 -+#define EREG_CSC_COEF_02 0x104a //Color space conversion coefficient 02 0x000f 363 -+#define EREG_CSC_COEF_10 0x104c //Color space conversion coefficient 10 0x01ed 363 -+#define EREG_CSC_COEF_11 0x104e //Color space conversion coefficient 11 0x01db 363 -+#define EREG_CSC_COEF_12 0x1050 //Color space conversion coefficient 12 0x0038 363 -+#define EREG_CSC_COEF_20 0x1052 //Color space conversion coefficient 20 0x004f 363 -+#define EREG_CSC_COEF_21 0x1054 //Color space conversion coefficient 21 0x01be 363 -+#define EREG_CSC_COEF_22 0x1056 //Color space conversion coefficient 22 0x01f3 363 -+#define EREG_CSC_OS_0 0x1058 //Color space conversion offset 0 0x0000 364 -+#define EREG_CSC_OS_1 0x105a //Color space conversion offset 1 0x0080 364 -+#define EREG_CSC_OS_2 0x105c //Color space conversion offset 2 0x0080 364 -+#define EREG_DATA_GEN 0x105e //Test data generator 0x0000 365 -+#define EREG_HSYNC_PER 0x1060 //Horizontal synchronization period 0x0a8b 366 -+#define EREG_APS_COEF_GRN1 0x1062 //Green 1 AWB gain 0x0080 368 -+#define EREG_APS_COEF_RED 0x1064 //Red AWB gain 0x0080 368 -+ -+ -+#define EREG_APS_COEF_BLUE 0x1066 //Blue AWB gain 0x0080 368 -+#define EREG_APS_COEF_GRN2 0x1068 //Green 2 AWB gain 0x0080 368 -+#define EREG_AV_LEFT_TOP 0x106a //Anti-v,sensor first row and column 0x0101 369 -+#define EREG_AV_RIGHT_BOT 0x106c //Anti-v, sensor last row and column 0xa27a 370 -+#define EREG_AV_CENTER_COL 0x106e //Anti-v, sensor center column 0x0148 371 -+#define EREG_AV_CENTER_ROW 0x1070 //Anti-v, sensor center row 0x00f8 372 -+#define EREG_STAT_CAP_CTRL 0x1072 //Image statistics capture control 0x0021 373 -+#define EREG_STAT_MODE_CTRL 0x1074 //Image statistics mode control 0x0000 374 -+#define EREG_GREEN_1_SUM 0x1076 //Green 1 pixel sum 0x0000 375 -+#define EREG_RED_SUM 0x1078 //Red pixel sum 0x0000 375 -+#define EREG_BLUE_SUM 0x107a //Blue pixel sum 0x0000 375 -+#define EREG_GREEN_2_SUM 0x107c //Green 2 pixel sum 0x0000 375 -+#define EREG_I_WIDTH 0x107e //Current image width 0x0000 376 -+#define EREG_I_HEIGHT 0x1080 //Current image height 0x0000 377 -+#define EREG_STATUS_FLAGS 0x1082 //Status flags (read only) 0x0000 378 -+#define EREG_CLK_GATE_DIS 0x1084 //Clock gate disable 0x0000 379 -+#define EREG_CCIR_TIMING2 0x1086 //CCIR interface timing 2 0x0000 381 -+#define EREG_CCIR_TIMING3 0x1088 //CCIR interface timing 3 0x0010 382 -+#define EREG_G1G2_DIAG_THRESH 0x108a //Green 1/green 2 diagonal threshold 0x0040 383 -+#define EREG_BPA_D2_THRESH 0x108c //BPA second derivative threshold 0x0100 384 -+#define EREG_SERIAL_CTRL 0x108e //Serial control 0x0000 385 -+#define EREG_INTP_CTRL_1 0x1090 //Interpolation control 1(demosaic) 0x0188 387 -+#define EREG_INTP_CTRL_2 0x1092 //Interpolation control 2(demosaic) 0x00c8 388 -+#define EREG_AV_OVAL_FACT 0x1094 //Anti-vignetting oval factor 0x0100 389 -+#define EREG_AV_OS_GREEN1 0x1096 //Anti-vignetting green 1 offset 0x0000 391 -+#define EREG_AV_OS_RED 0x1098 //Anti-vignetting red offset 0x0000 391 -+#define EREG_AV_OS_BLUE 0x109a //Anti-vignetting blue offset 0x0000 391 -+#define EREG_AV_OS_GREEN2 0x109c //Anti-vignetting green 2 offset 0x0000 391 -+ -+ -+ -+/*********************************************************************** -+ * -+ * Function Prototype -+ * -+ ***********************************************************************/ -+ -+u16 adcm2700_reg_read(u16 reg_addr); -+void adcm2700_reg_write(u16 reg_addr, u16 reg_value); -+ -+ -+// Configuration Procedures -+int adcm2700_power_on(u8); -+int adcm2700_power_off(void ); -+int adcm2700_change_viewfinder_mode(adcm_window_size * input_win, adcm_window_size *vf_output_win, adcm_window_size *sf_output_win ); -+int adcm2700_firmware_upgrade( void ); -+int adcm2700_version_revision(u16 * cm_revision, u16 *sensor_revision); -+int adcm2700_viewfinder_on( void ); -+int adcm2700_viewfinder_off( void ); -+int adcm2700_master_clock(u8 clk); -+int adcm2700_viewfinder_input_size(adcm_window_size * win ); -+int adcm2700_stillframe_input_size(adcm_window_size * win ); -+int adcm2700_viewfinder_output_size(adcm_window_size * win); -+int adcm2700_stillframe_output_size(adcm_window_size * win); -+int adcm2700_stillframe_cfg_output(u16 format); -+int adcm2700_viewfinder_cfg_output(u16 format); -+int adcm2700_gamma_correction(void); -+int adcm2700_get_output_frame_rate(u16 * fps); -+int adcm2700_detect_camera_mode(u16 *mode); -+ -+int adcm2700_set_fps(u16 fps, u16 minfps); -+ -+int adcm2700_input_size(adcm_window_size * win); -+int adcm2700_output_size(adcm_window_size * win); -+int adcm2700_get_input_size(adcm_window_size * win); -+/*set picture style(normal/black white/sepia/solarize/neg.art)*/ -+int adcm2700_set_style(V4l_PIC_STYLE style); -+/*set picture light(direct sun/incandescent/fluorescent)*/ -+int adcm2700_set_light(V4l_PIC_WB light); -+/*set picture brightness*/ -+int adcm2700_set_bright(int bright); -+ -+int adcm2700_restore_property(p_camera_context_t cam_ctx, int frames); -+ -+#endif /* _PXA_ADCM_2700_HW_H__ */ -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/adcm3800.c linux-2.6.16.5-exz/drivers/media/video/adcm3800.c ---- linux-2.6.16.5/drivers/media/video/adcm3800.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/adcm3800.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,619 @@ -+ -+/*================================================================================ -+ -+ Header Name: adcm3800.c -+ -+General Description: Camera module adcm3800 interface source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+wangfei(w20239) 02/05/2004 LIBdd74309 Set frame rate in video mode -+wangfei(w20239) 02/26/2004 LIBdd81055 New chip id support -+ Update algorithm for DMA transfer -+ Update strategy for memory management -+ Fix still picture capture failed sometime -+ New Agilent sensor chip ID support -+ Make output height in an even multiple of 8 -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+#include <linux/types.h> -+#include <linux/config.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+ -+#include <asm/irq.h> -+#include <asm/hardware.h> -+ -+#include <asm/arch/pxa-regs.h> -+ -+#include "camera.h" -+#include "adcm3800.h" -+#include "adcm3800_hw.h" -+ -+ -+/*********************************************************************** -+ * -+ * ADCM3800 common functions -+ * -+ ***********************************************************************/ -+#define MAX_WIDTH 1280 -+#define MAX_HEIGHT 1024 -+#define MIN_WIDTH 64 -+#define MIN_HEIGHT 56 -+#define WIDTH_DEFT 320 -+#define HEIGHT_DEFT 240 -+#define S_WIDTH_DEFT 1280 -+#define S_HEIGHT_DEFT 960 -+#define FRAMERATE_DEFT 15 -+#define MCLK_DEFT 48 /* Default Master clock*/ -+#define BUF_SIZE_DEFT ((PAGE_ALIGN(MAX_WIDTH * MAX_HEIGHT) + (PAGE_ALIGN(MAX_WIDTH*MAX_HEIGHT/2)*2))) -+ -+extern int i2c_adcm3800_init(void); -+extern int i2c_adcm3800_cleanup(void); -+ -+////////////////////////////////////////////////////////////////////////////////////// -+//adcm3800 functions -+// -+static int camera_func_adcm3800_init(p_camera_context_t); -+static int camera_func_adcm3800_deinit(p_camera_context_t); -+static int camera_func_adcm3800_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param); -+static int camera_func_adcm3800_set_capture_format(p_camera_context_t); -+static int camera_func_adcm3800_start_capture(p_camera_context_t, unsigned int frames); -+static int camera_func_adcm3800_stop_capture(p_camera_context_t); -+ -+static int camera_func_adcm3800_pm_management(p_camera_context_t, int); -+ -+static int adcm3800_sensor_init(p_camera_context_t cam_ctx); -+ -+ -+camera_function_t camera_adcm3800_func = -+{ -+ init: camera_func_adcm3800_init, -+ deinit: camera_func_adcm3800_deinit, -+ command: camera_func_adcm3800_docommand, -+ set_capture_format: camera_func_adcm3800_set_capture_format, -+ start_capture: camera_func_adcm3800_start_capture, -+ stop_capture: camera_func_adcm3800_stop_capture, -+ pm_management: camera_func_adcm3800_pm_management -+}; -+ -+static int camera_func_adcm3800_init(p_camera_context_t cam_ctx) -+{ -+ int ret = 0; -+ // init context status -+ cam_ctx->dma_channels[0] = 0xFF; -+ cam_ctx->dma_channels[1] = 0xFF; -+ cam_ctx->dma_channels[2] = 0xFF; -+ -+ cam_ctx->capture_width = WIDTH_DEFT; -+ cam_ctx->capture_height = HEIGHT_DEFT; -+ cam_ctx->sensor_width = S_WIDTH_DEFT; -+ cam_ctx->sensor_height = S_HEIGHT_DEFT; -+ -+ cam_ctx->capture_input_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ cam_ctx->capture_output_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ -+ cam_ctx->frame_rate = cam_ctx->fps = FRAMERATE_DEFT; -+ -+ cam_ctx->mini_fps = FRAMERATE_DEFT-5; -+ -+ cam_ctx->mclk = MCLK_DEFT; -+ cam_ctx->flicker_freq = 50; -+ -+ cam_ctx->buf_size = BUF_SIZE_DEFT; -+ cam_ctx->dma_descriptors_size = (cam_ctx->buf_size/PAGE_SIZE + 10); -+ cam_ctx->vc.maxwidth = MAX_WIDTH; -+ cam_ctx->vc.maxheight = MAX_HEIGHT; -+ cam_ctx->vc.minwidth = MIN_WIDTH; -+ cam_ctx->vc.minheight = MIN_HEIGHT; -+ -+ camera_gpio_init(); -+ ci_init(); -+ -+ // Configure CI according to hardware -+ // master parallel with 8 data pins -+ ci_set_mode(CI_MODE_MP, CI_DATA_WIDTH8); -+ -+ // enable pixel clock(sensor will provide pclock) -+ ci_set_clock(cam_ctx->clk_reg_base, 1, 1, cam_ctx->mclk); -+ -+ // data sample on rising and h,vsync active high -+ ci_set_polarity(0, 0, 0); -+ -+ // fifo control -+ ci_set_fifo(0, CI_FIFO_THL_32, 1, 1); // quality -+ -+ // Turn on M_CLK using xx MHz and wait for 150 ms. -+ ci_enable(1); -+ -+ mdelay(10); // TODO: reduce it -+ -+ if(i2c_adcm3800_init() == 0) -+ { -+ cam_ctx->sensor_type = CAMERA_TYPE_ADCM3800; -+ -+ //mdelay(100); -+ -+ if((ret = adcm3800_sensor_init(cam_ctx)) < 0) -+ { -+ dbg_print("adcm3800 hardware init error!"); -+ return -1; -+ } -+ ddbg_print("Agilent ADCM3800 camera module detected!"); -+ } -+ else -+ return -1; -+ -+ return 0; -+} -+ -+/*********************************************************************** -+ * -+ * ADCM3800 Functions -+ * -+ ***********************************************************************/ -+static int adcm3800_sensor_init( p_camera_context_t camera_context ) -+{ -+ //u32 adcm_mclk = camera_context->mclk * 195000 / 192; // SYS_CLK is 195Mhz -+ u32 adcm_mclk = camera_context->mclk * 1000; -+ adcm3800_power_on(adcm_mclk); -+ return 0; -+} -+ -+static int camera_func_adcm3800_deinit( p_camera_context_t camera_context ) -+{ -+ dbg_print("adcm3800 off!"); -+ -+ /* power off the external module */ -+ camera_func_adcm3800_stop_capture(camera_context); -+ -+ adcm3800_power_off(); -+ i2c_adcm3800_cleanup(); -+ -+ /* disable CI */ -+ ci_disable(1); -+ -+ camera_gpio_deinit(); -+ return 0; -+} -+ -+static int camera_func_adcm3800_set_capture_format(p_camera_context_t camera_context) -+{ -+ u16 adcm_format; -+ window_size size; -+ -+ //set sensor format -+ switch(camera_context->capture_input_format) -+ { -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ adcm_format = O_FORMAT_422_B_YCbYCr; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ adcm_format = O_FORMAT_565_RGB; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB888_PACKED: -+ case CAMERA_IMAGE_FORMAT_RGB888_PLANAR: -+ adcm_format = O_FORMAT_888RGB; -+ break; -+ default: -+ adcm_format = O_FORMAT_422_B_YCbYCr; -+ break; -+ } -+ adcm3800_set_output_format(adcm_format); -+ -+ size.width = camera_context->capture_width; -+ size.height = camera_context->capture_height; -+ adcm3800_set_output_size(size.width, size.height); -+ -+ return 0; -+} -+ -+static int camera_func_adcm3800_start_capture(p_camera_context_t cam_ctx, unsigned int frames) -+{ -+ int ret; -+ int cisr; -+ int wait_count; -+ static int error_times = 0; -+ unsigned int start_time; -+ -+ // frames=0 means video mode capture -+ if(frames == 0) -+ { -+ // ddbg_print("video capture!"); -+ wait_count = 1; -+ } -+ else -+ { -+ // ddbg_print("still capture"); -+ wait_count = 1; -+ } -+ ret = adcm3800_reconfigure(cam_ctx, frames); -+ if(ret<0) -+ return ret; -+ adcm3800_viewfinder_on(); -+ -+ ci_disable(1); -+ ci_enable(1); -+ -+ dbg_print("wait for SOF %d time", wait_count); -+ start_time = 0xFFFFF * 20 * wait_count; -+ -+ CISR |= CI_CISR_SOF; -+ CISR |= CI_CISR_EOF; -+ cisr=CISR; -+ while(wait_count) -+ { -+ if(cisr & CI_CISR_EOF) -+ { -+ dbg_print("get EOF %d:%d", wait_count, start_time); -+ CISR |= CI_CISR_EOF; -+ } -+ if(cisr & CI_CISR_SOF) -+ { -+ dbg_print("get SOF %d:%d", wait_count, start_time); -+ wait_count -- ; -+ CISR |= CI_CISR_SOF; -+ } -+ cisr=CISR; -+ if(!(--start_time)) -+ { -+ goto wait_SOF_error; -+ } -+ -+ } -+ //mdelay(1); -+ ci_disable(1); -+ ci_enable(1); -+ ci_reset_fifo(); -+ //ci_clear_int_status(0xFFFFFFFF); -+ start_dma_transfer(cam_ctx, cam_ctx->block_header); -+ dbg_print("wait ok..%d", start_time); -+ return 0; -+ -+wait_SOF_error: -+ error_times++; -+ dbg_print("wait SOF error! error_times = %d", error_times); -+ return -EIO; -+} -+ -+static int camera_func_adcm3800_stop_capture(p_camera_context_t cam_ctx) -+{ -+ adcm3800_viewfinder_off(); -+ stop_dma_transfer(cam_ctx); -+ return 0; -+} -+ -+static int camera_func_adcm3800_pm_management(p_camera_context_t cam_ctx, int suspend) -+{ -+ static int resume_dma = 0; -+ if(suspend) -+ { -+ if(cam_ctx != NULL ) -+ { -+ if(cam_ctx->dma_started) -+ { -+ ddbg_print("camera running, suspended"); -+ stop_dma_transfer(cam_ctx); -+ resume_dma = 1; -+ } -+ } -+ -+ disable_irq(IRQ_CAMERA); -+ pxa_set_cken(CKEN24_CAMERA, 0); -+ } -+ else -+ { -+ pxa_set_cken(CKEN24_CAMERA, 1); -+ enable_irq(IRQ_CAMERA); -+ -+ if(cam_ctx != NULL) -+ { -+ ddbg_print("camera running, resumed"); -+ camera_init(cam_ctx); -+ if(resume_dma == 1) -+ { -+ camera_start_video_capture(cam_ctx, 0); -+ resume_dma = 0; -+ } -+ } -+ } -+ return 0; -+} -+ -+/*set picture brightness*/ -+static int pxa_cam_WCAM_VIDIOCSBRIGHT(p_camera_context_t cam_ctx, void * param) -+{ -+ int ret = 0; -+ int bright; -+ bright = (int)param; -+ ddbg_print("WCAM_VIDIOCSBRIGHT %d", bright); -+ -+ cam_ctx->capture_bright = bright; -+ ret = adcm3800_set_bright(bright); -+ -+ if(cam_ctx->dma_started == 1 && ret>0) -+ { -+ camera_func_adcm3800_stop_capture(cam_ctx); -+ ret = camera_func_adcm3800_start_capture(cam_ctx, 0); -+ return ret; -+ } -+ return 0; -+} -+ -+/*set picture style*/ -+static int pxa_cam_WCAM_VIDIOCSSTYLE(p_camera_context_t cam_ctx, void * param) -+{ -+ int ret = 0; -+ V4l_PIC_STYLE style; -+ style = (V4l_PIC_STYLE)param; -+ ddbg_print("WCAM_VIDIOCSSTYLE %d", style); -+ -+ cam_ctx->capture_style = style; -+ ret = adcm3800_set_style(style); -+ if(cam_ctx->dma_started == 1 && ret>0) -+ { -+ camera_func_adcm3800_stop_capture(cam_ctx); -+ ret = camera_func_adcm3800_start_capture(cam_ctx, 0); -+ return ret; -+ } -+ return 0; -+} -+ -+ -+/*set picture light*/ -+static int pxa_cam_WCAM_VIDIOCSLIGHT(p_camera_context_t cam_ctx, void * param) -+{ -+ int ret = 0; -+ V4l_PIC_WB light; -+ light = (V4l_PIC_WB)param; -+ dbg_print("WCAM_VIDIOCSLIGHT %d", light); -+ -+ cam_ctx->capture_light = light; -+ ret = adcm3800_set_light(light); -+ if(cam_ctx->dma_started == 1) -+ { -+ camera_func_adcm3800_stop_capture(cam_ctx); -+ ret = camera_func_adcm3800_start_capture(cam_ctx, 0); -+ return ret; -+ } -+ return 0; -+} -+ -+ -+//set output size -+static int pxa_cam_WCAM_VIDIOCSOSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ //ddbg_print("WCAM_VIDIOCSOSIZE"); -+ -+ window_size size; -+ -+ if(copy_from_user(&size, param, sizeof(window_size))) -+ { -+ return -EFAULT; -+ } -+ if(cam_ctx->dma_started == 1) -+ { -+ return -EFAULT; -+ } -+ -+ //make it in an even of multiple of 8 -+ size.width = (size.width +7)/8 * 8; -+ size.height = (size.height+7)/8 * 8; -+ -+ dbg_print("w=%d h=%d", size.width, size.height); -+ -+ if(cam_ctx->capture_width != size.width || cam_ctx->capture_height != size.height) -+ { -+ dbg_print("error: the camera output size should match CSWIN size"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/*Set sensor size*/ -+static int pxa_cam_WCAM_VIDIOCSSSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ //ddbg_print("WCAM_VIDIOCSSSIZE"); -+ window_size size; -+ int ret; -+ -+ if(copy_from_user(&size, param, sizeof(window_size))) -+ { -+ return -EFAULT; -+ } -+ if(cam_ctx->dma_started == 1) -+ { -+ return -EFAULT; -+ } -+ -+ //make it in an even of multiple of 8 -+ size.width = (size.width +7)/8 * 8; -+ size.height = (size.height+7)/8 * 8; -+ -+ cam_ctx->sensor_width = size.width; -+ cam_ctx->sensor_height = size.height; -+ dbg_print("w = %d h = %d", size.width, size.height); -+ -+ ret = adcm3800_set_sensor_size(size.width, size.height); -+ if(ret<0) -+ return ret; -+ -+ return 0; -+} -+ -+static int pxa_cam_WCAM_VIDIOCSFPS(p_camera_context_t cam_ctx, void * param) -+{ -+ //ddbg_print("WCAM_VIDIOCSFPS"); -+ -+ struct {int fps, minfps;} cam_fps; -+ int ret = 0; -+ -+ if(copy_from_user(&cam_fps, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ if(cam_fps.fps < 5) -+ { -+ cam_fps.fps = 5; -+ } -+ -+ ddbg_print("WCAM_VIDIOCSFPS %d:%d", cam_ctx->fps, cam_fps.fps); -+ if(cam_ctx->fps != cam_fps.fps || cam_ctx->mini_fps != cam_fps.minfps) -+ { -+ cam_ctx->fps = cam_fps.fps; -+ cam_ctx->mini_fps = cam_fps.minfps; -+ -+ ret = adcm3800_set_fps(cam_ctx->fps * 10); -+ if(ret<0) -+ return ret; -+ -+ if(cam_ctx->dma_started == 1 && ret>1) -+ { -+ camera_func_adcm3800_stop_capture(cam_ctx); -+ ret = camera_func_adcm3800_start_capture(cam_ctx, 0); -+ return ret; -+ } -+ } -+ return 0; -+} -+ -+static int pxa_cam_WCAM_VIDIOCSNIGHTMODE(p_camera_context_t cam_ctx, void * param) -+{ -+ int ret; -+ struct { -+ V4l_NM mode; -+ int maxtime; -+ } expo_mode; -+ if (copy_from_user(&expo_mode, param, sizeof(expo_mode))) { -+ return -EFAULT; -+ } -+ ddbg_print("WCAM_VIDIOCSNIGHTMODE %d:%d", expo_mode.mode, expo_mode.maxtime); -+ -+ ret = adcm3800_set_exposure_mode(expo_mode.mode, expo_mode.maxtime); -+ if(cam_ctx->dma_started == 1 && ret>0) -+ { -+ camera_func_adcm3800_stop_capture(cam_ctx); -+ ret = camera_func_adcm3800_start_capture(cam_ctx, 0); -+ return ret; -+ } -+ return 0; -+} -+ -+/*set flicker frequency*/ -+static int pxa_cam_WCAM_VIDIOCSFLICKER(p_camera_context_t cam_ctx, void * param) -+{ -+ int ret; -+ dbg_print("WCAM_VIDIOCSFLICKER"); -+ cam_ctx->flicker_freq = (int)param; -+ -+ if(cam_ctx->dma_started == 1) -+ return -EPERM; -+ -+ ret = adcm3800_set_flicker(cam_ctx->flicker_freq); -+ if(ret<0) -+ return ret; -+ -+ return 0; -+} -+ -+static int pxa_camera_WCAM_VIDIOCGCAMREG(p_camera_context_t cam_ctx, void * param) -+{ -+ int ret, offset; -+ u16 value; -+ //ddbg_print("WCAM_VIDIOCGCAMREG"); -+ if(copy_from_user(&offset, param, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ ret = i2c_adcm3800_read((u16)offset, &value); -+ if(ret<0) -+ return ret; -+ -+ if(copy_to_user(param, &value, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+static int pxa_camera_WCAM_VIDIOCSCAMREG(p_camera_context_t cam_ctx, void * param) -+{ -+ struct reg_set_s{int val1, val2;} reg_s; -+ //ddbg_print("WCAM_VIDIOCSCAMREG"); -+ -+ if(copy_from_user(®_s, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ i2c_adcm3800_write((u16)reg_s.val1, (u16)reg_s.val2); -+ return 0; -+} -+ -+static int camera_func_adcm3800_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param) -+{ -+ switch(cmd) -+ { -+ /*read adcm3800 registers*/ -+ case WCAM_VIDIOCGCAMREG: -+ return pxa_camera_WCAM_VIDIOCGCAMREG(cam_ctx, param); -+ -+ /*write adcm3800 registers*/ -+ case WCAM_VIDIOCSCAMREG: -+ return pxa_camera_WCAM_VIDIOCSCAMREG(cam_ctx, param); -+ -+ /*set sensor size */ -+ case WCAM_VIDIOCSSSIZE: -+ return pxa_cam_WCAM_VIDIOCSSSIZE(cam_ctx, param); -+ -+ /*set output size*/ -+ case WCAM_VIDIOCSOSIZE: -+ return pxa_cam_WCAM_VIDIOCSOSIZE(cam_ctx, param); -+ -+ -+ /*set video mode fps*/ -+ case WCAM_VIDIOCSFPS: -+ return pxa_cam_WCAM_VIDIOCSFPS(cam_ctx, param); -+ -+ case WCAM_VIDIOCSNIGHTMODE: -+ return pxa_cam_WCAM_VIDIOCSNIGHTMODE(cam_ctx, param); -+ -+ /*set picture style*/ -+ case WCAM_VIDIOCSSTYLE: -+ return pxa_cam_WCAM_VIDIOCSSTYLE(cam_ctx, param); -+ -+ /*set picture light*/ -+ case WCAM_VIDIOCSLIGHT: -+ return pxa_cam_WCAM_VIDIOCSLIGHT(cam_ctx, param); -+ -+ /*set picture brightness*/ -+ case WCAM_VIDIOCSBRIGHT: -+ return pxa_cam_WCAM_VIDIOCSBRIGHT(cam_ctx, param); -+ -+ /*set flicker frequency*/ -+ case WCAM_VIDIOCSFLICKER: -+ return pxa_cam_WCAM_VIDIOCSFLICKER(cam_ctx, param); -+ -+ default: -+ { -+ dbg_print("Error cmd=0x%x", cmd); -+ return -1; -+ } -+ } -+ return 0; -+ -+} -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/adcm3800.h linux-2.6.16.5-exz/drivers/media/video/adcm3800.h ---- linux-2.6.16.5/drivers/media/video/adcm3800.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/adcm3800.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,41 @@ -+ -+/*================================================================================ -+ -+ Header Name: adcm3800.h -+ -+General Description: Camera module adcm3800 interface head file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+ -+#ifndef _ADCM3800_H_ -+#define _ADCM3800_H_ -+ -+#include "camera.h" -+ -+////////////////////////////////////////////////////////////////////////////////////// -+// -+// Prototypes -+// -+////////////////////////////////////////////////////////////////////////////////////// -+ -+/* WINDOW SIZE */ -+typedef struct { -+ u16 width; -+ u16 height; -+} window_size; -+ -+#endif /* _ADCM3800_H_ */ -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/adcm3800_hw.c linux-2.6.16.5-exz/drivers/media/video/adcm3800_hw.c ---- linux-2.6.16.5/drivers/media/video/adcm3800_hw.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/adcm3800_hw.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,1828 @@ -+/*================================================================================ -+ -+ Header Name: adcm3800_hw.c -+ -+General Description: Camera module adcm3800 interface source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+ -+wangfei(w20239) 02/05/2004 LIBdd74309 Set frame rate in video mode -+ -+wangfei(w20239) 02/26/2004 LIBdd81055 New chip id support -+ Update algorithm for DMA transfer -+ Update strategy for memory management -+ Fix still picture capture failed sometime -+ New Agilent sensor chip ID support -+ Make output height in an even multiple of 8 -+ -+wangfei(w20239) 03/08/2004 LIBdd84578 Photo effects setting -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+#include <linux/types.h> -+#include <linux/delay.h> -+ -+#include "camera.h" -+#include "adcm3800_hw.h" -+ -+#define MAX_FPS 300 // 30 fps -+ -+static adcm3800_context_t adcm3800_context; -+ -+#define adcm3800_read(addr, pvalue) \ -+ i2c_adcm3800_read(addr, pvalue); \ -+ ddbg_print("i2c read: a(0x%04x) v(0x%04x)", addr, *(pvalue)); -+ -+#define adcm3800_write(addr, value) \ -+ i2c_adcm3800_write(addr, value); \ -+ ddbg_print("i2c write: a(0x%04x) v(0x%04x)", addr, value); -+ -+#define adcm3800_read_byte(addr, pvalue) \ -+ i2c_adcm3800_read_byte(addr, pvalue); \ -+ ddbg_print("i2c read b: a(0x%04x) v(0x%02x)", addr, *(pvalue)); -+ -+#define adcm3800_write_byte(addr, value) \ -+ i2c_adcm3800_write_byte(addr, value); \ -+ ddbg_print("i2c write b: a(0x%04x) v(0x%02x)", addr, value); -+ -+static int adcm3800_reg_read(u16 reg_addr) -+{ -+ u16 value; -+ int ret = adcm3800_read(reg_addr, &value); -+ if(ret < 0) -+ { -+ return ret; -+ } -+ return value; -+} -+ -+// These routine writes to consectutive 16 bit registers -+// with addresses that increment by 2. -+static int adcm3800_write_regs (u16 regAddr, u16 *regData, u16 nRegs) -+{ -+ int i, ret; -+ for(i = 0; i < nRegs; i++) -+ { -+ ret = adcm3800_write(regAddr+i*2, regData[i]); -+ if(ret < 0) -+ { -+ dbg_print("adcm3800 write error %d:%04x!", i, regAddr+i*2); -+ return -1; -+ } -+ } -+ return i; -+} -+ -+static int adcm3800_writeb_regs (u16 regAddr, u8 *regData, u16 nRegs) -+{ -+ int i, ret; -+ for(i = 0; i < nRegs; i++) -+ { -+ ret = adcm3800_write_byte(regAddr+i, regData[i]); -+ if(ret < 0) -+ { -+ dbg_print("adcm3800 write error %d:%04x!", i, regAddr+i*2); -+ return -1; -+ } -+ } -+ return i; -+} -+ -+void adcm3800_dump_awb_regs(void) -+{ -+#ifdef DEBUG -+ int i; -+ unsigned short value; -+ unsigned char valueb; -+ -+ // read some PI/AWB registers -+ adcm3800_read(0x003e, &value); // current CC matrix for PI -+ dbg_print("003e: %04x (PI index)", value); -+ adcm3800_read(0x1064, &value); // current red gains -+ dbg_print("1064: %04x (red gain)", value); -+ adcm3800_read(0x1066, &value); // current blue gains -+ dbg_print("1066: %04x (blue gain)", value); -+ -+ // read only current registers -+ adcm3800_read(0x0244, &value); // C_GAIN, current gain -+ dbg_print("0244: %04x (current gain)", value); -+ adcm3800_read(0x0246, &value); // C_ETIME, current exposure time -+ dbg_print("0246: %04x (current exposure time)", value); -+ adcm3800_read(0x024a, &value); // C_RG_RATIO, current red/green ratio -+ dbg_print("024a: %04x (current red/green ratio)", value); -+ adcm3800_read(0x024c, &value); // C_BG_RATIO, current blue/green ratio -+ dbg_print("024c: %04x (current blue/green ratio)", value); -+#endif -+} -+ -+static int adcm3800_print_status(void) -+{ -+ adcm3800_dump_awb_regs(); -+ -+#if DEBUG > 1 -+ int i; -+ unsigned short value; -+ unsigned char valueb; -+ -+ adcm3800_read(0x0002, &value); -+ ddbg_print("control: %04x", value); -+ adcm3800_read(0x0004, &value); -+ ddbg_print("status: %04x", value); -+ adcm3800_read(0x000c, &value); -+ ddbg_print("exposure time: %d ms", value/100); -+ adcm3800_read(0x0016, &value); -+ ddbg_print("frame rate: %d/10 fps", value); -+ -+ // read only current registers -+ adcm3800_read(0x0248, &value); // C_BNF_TIME, current flicker time -+ -+ // PLL & clock registers -+ adcm3800_read(0x100a, &value); -+ adcm3800_read(0x3000, &value); -+ adcm3800_read(0x3004, &value); -+ adcm3800_read(0x3006, &value); -+ -+ adcm3800_read(0x114, &value); -+ -+ // Auto function registers -+ adcm3800_read(EREG_AE_TARGET, &value); -+ adcm3800_read(0x017c, &value); -+ adcm3800_read(0x017e, &value); -+ -+ adcm3800_read(EREG_AF_CTRL1, &value); -+ adcm3800_read(EREG_AF_CTRL2, &value); -+ adcm3800_read(EREG_APS_COEF_GRN1, &value); -+ adcm3800_read(EREG_APS_COEF_GRN2, &value); -+ adcm3800_read(EREG_APS_COEF_RED, &value); -+ adcm3800_read(EREG_APS_COEF_BLUE, &value); -+ -+ // statistics registers -+ //adcm3800_read(0x1076, &value); -+ //adcm3800_read(0x1074, &value); -+ -+ // Sensor exposure registers -+ adcm3800_read_byte(0x080F, &valueb); -+ adcm3800_read_byte(0x0810, &valueb); -+ adcm3800_read_byte(0x0811, &valueb); -+ adcm3800_read_byte(0x0812, &valueb); -+ -+ adcm3800_read_byte(0x0813, &valueb); -+ adcm3800_read_byte(0x0814, &valueb); -+ adcm3800_read_byte(0x0815, &valueb); -+ adcm3800_read_byte(0x080e, &valueb); -+ -+ // read CC_COEF -+ for(i=0; i<9; i++) -+ { adcm3800_read(0x1028+i*2, &value); } -+ // read NACC Bright CC -+ for(i=0; i<9; i++) -+ { adcm3800_read(0x0270+i*2, &value); } -+ // read gamma -+ for(i=0; i<33; i++) -+ { adcm3800_read(0x1400+i*2, &value); } -+ // read CSC -+ for(i=0; i<10; i++) -+ { adcm3800_read(0x0190+i*2, &value); } -+ for(i=0; i<10; i++) -+ { adcm3800_read(0x1046+i*2, &value); } -+#endif -+ return 0; -+} -+ -+static void adcm3800_wait(u32 ms) -+{ -+ if(ms > 10) -+ { -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(ms/10); -+ } -+} -+ -+static int wait_sreg_update(void) -+{ -+ dbg_print("wait for sensor update simple registers"); -+ adcm3800_write(SREG_CONTROL, 0x04); -+ adcm3800_wait(10); -+ int retry = adcm3800__TIMEOUT*4; -+ while(--retry) -+ { -+ u16 v; -+ int ret; -+ ret = adcm3800_read(SREG_CONTROL, &v); -+ if(ret<0) -+ return ret; -+ -+ if(!(v & 0x04)) -+ { -+ dbg_print("retry = %d", retry); -+ return 0; -+ } -+ adcm3800_wait(2); -+ } -+ dbg_print("error:timeout to SCL, retry = %d", retry); -+ return -EIO; -+} -+ -+static int adcm3800_firmware_upgrade(void); -+static int adcm3800_init_regs(void); -+ -+static void adcm3800_init_context(void) -+{ -+ memset(&adcm3800_context, 0, sizeof(adcm3800_context)); -+ -+ adcm3800_context.SCL_restart = 1; // force restart at first time -+ adcm3800_context.format = O_FORMAT_NONE; -+ adcm3800_context.max_expotime = 100000; // 100ms -+} -+ -+/////////////////////////////////////////////////////////////// -+// -+// Programming Guide Chapter 1: Basic Programming -+// -+/////////////////////////////////////////////////////////////// -+ -+int adcm3800_master_clock(u32 clk) -+{ -+#if 1 -+ int i; -+ unsigned short value; -+ unsigned int clock; -+ //0x5017 3.375X // 24M*3.375 = 81M -+ //0x502f 1.6875X // 48M*1.6875 = 81M -+ //0x4f2f // 48.75*80/48 = 81.25M -+ //u16 div = 0x4f2f; // 48.75*80/48 = 81.25M -+ u16 div = 0x502f; // 48.75*81/48 = 82.265625M -+ -+ clock = clk*((div>>8) + 1) / ((div&0xFF) + 1); -+ -+ adcm3800_read(EREG_PLL_CTRL, &value); -+ dbg_print("1 clk %d, clock %d, PLL CTRL : %04x", clk, clock, value); -+ /*enable pll*/ -+ adcm3800_write(0x300a, clock/4000-1); -+ adcm3800_write(EREG_PLL_DIV_L, div); -+ adcm3800_write(EREG_PLL_DIV_S, div); -+ adcm3800_write(EREG_PLL_CTRL, 0x0015); //0x002D -+ adcm3800_write(0x3040, 0x0100); -+ -+ adcm3800_write(0x010c, 0x0006); -+ adcm3800_write(SREG_CLK_FREQ, (u16)(clock / 10)); -+ -+ for(i=0; i<1000; i++) -+ { -+ adcm3800_read(EREG_PLL_CTRL, &value); -+ dbg_print("2 PLL CTRL : %04x", value); -+ if(value&0x80) -+ break; -+ mdelay(2); -+ } -+ dbg_print("3 wait %d ms : ", i*2); -+ -+#else -+ adcm3800_write(SREG_CLK_FREQ, (u16)(clk / 10)); -+#endif -+ -+ return 0; -+} -+ -+int adcm3800_power_on( u32 clk ) -+{ -+ adcm3800_init_context(); -+ -+ //read out version -+ //u16 sensor_rev, cm_rev; -+ //adcm3800_version_revision(&cm_rev, &sensor_rev); -+ -+ /*Follow these steps to correctly power on the ADCM-2700: -+ 1 Turn on VCC voltage (2.8 volts) and wait 20 milliseconds. -+ 2 Turn on MCLK (13 MHz is the default value) and wait 150 milliseconds. -+ 3 Read register 0x0004; if the return value equals 0x0001, power-up is complete. */ -+ int retry = adcm3800__TIMEOUT/2; -+ int timeout = 0; -+ while(--retry) -+ { -+ int ret; -+ u16 value; -+ ret = adcm3800_read(SREG_STATUS, &value); -+ if(value == 0x0001) -+ { -+ dbg_print("adcm3800 Power-up complete!! time %dms", timeout); -+ break; -+ } -+ adcm3800_wait(2); -+ timeout += 2; -+ } -+ if(retry==0) -+ { -+ dbg_print("error: timeout! Power-up failed!"); -+ return -EIO; -+ } -+ -+ // turn off camera -+ adcm3800_write(SREG_CONTROL, 0x0); -+ -+ // Load the firmware upgrade -+ adcm3800_firmware_upgrade(); -+ -+ // initialize registers -+ adcm3800_init_regs(); -+ -+ /* Program the mafster clock */ -+ adcm3800_master_clock(clk); -+ -+ return 0; -+} -+ -+ -+int adcm3800_power_off() -+{ -+ /*stop camera*/ -+ adcm3800_write(SREG_CONTROL, 0); -+ return 0; -+} -+ -+ -+///////////////////////////////////////////////////////////////////////////////////// -+// -+// Programming Guide Chapter 2: Configuration Methods -+// -+///////////////////////////////////////////////////////////////////////////////////// -+ -+ -+static int adcm3800_version_revision(u16 * cm_revision, u16 *sensor_revision) -+{ -+ u8 bvalue; -+ -+ //Camera module version is 0x060 -+ adcm3800_read(SREG_ID, cm_revision); -+ dbg_print("adcm3800 SREG_ID is 0x%x", *cm_revision); -+ -+ //Image sensor version is 0x60 -+ adcm3800_read_byte(EREG_IDENT, &bvalue); -+ *sensor_revision = bvalue; -+ dbg_print("adcm3800 EREG_IDENT is 0x%x", *sensor_revision); -+ -+ return 0; -+} -+ -+int adcm3800_viewfinder_on() -+{ -+ ddbg_print("camera video mode start!"); -+ adcm3800_print_status(); -+ return 0; -+} -+ -+int adcm3800_viewfinder_off() -+{ -+ adcm3800_print_status(); -+ -+ ddbg_print("camera video mode stop!"); -+ return 0; -+} -+ -+static int adcm3800_register_sensor_size(u16 width, u16 height) -+{ -+ adcm3800_write(SREG_SENSOR_WID_V, width); -+ adcm3800_write(SREG_SENSOR_HGT_V, height); -+ return 0; -+} -+ -+int adcm3800_set_sensor_size(u16 width, u16 height) -+{ -+ if( width!=adcm3800_context.sensor_w || -+ height!=adcm3800_context.sensor_h ) -+ { -+ adcm3800_context.sensor_w = width; -+ adcm3800_context.sensor_h = height; -+ adcm3800_context.SCL_partial = 1; -+ return 1; -+ } -+ return 0; -+} -+ -+static int adcm3800_register_output_size(u16 width, u16 height) -+{ -+ adcm3800_write(SREG_OUTPUT_WID_V, width); -+ adcm3800_write(SREG_OUTPUT_HGT_V, height); -+ -+ return 0; -+} -+ -+int adcm3800_set_output_size(u16 width, u16 height) -+{ -+ if( width!=adcm3800_context.output_w || -+ height!=adcm3800_context.output_h ) -+ { -+ adcm3800_context.output_w = width; -+ adcm3800_context.output_h = height; -+ adcm3800_context.SCL_partial = 1; -+ return 1; -+ } -+ return 0; -+} -+ -+ -+static int adcm3800_register_output_format(u16 format) -+{ -+ u16 newcfg; -+ u16 oldcfg; -+ adcm3800_read(SREG_OUTPUT_FORMAT, &oldcfg); -+ -+ newcfg = (oldcfg & 0xFFF0) | (format & 0x000F); -+ if(newcfg!=oldcfg) -+ { -+ adcm3800_write( SREG_OUTPUT_FORMAT, newcfg ); -+ } -+ -+ return 0; -+} -+ -+int adcm3800_set_output_format(u16 format) -+{ -+ if( format!=adcm3800_context.format ) -+ { -+ adcm3800_context.format = format; -+ adcm3800_context.SCL_partial = 1; // TODO: not confirmed -+ return 1; -+ } -+ return 0; -+} -+ -+static int adcm3800_register_fps(p_adcm3800_context_t adcm_ctx) -+{ -+ if( (adcm_ctx->fps>70) && (adcm_ctx->output_w > 640 || adcm_ctx->output_h > 480) ) -+ { -+ //if capture size > VGA, the frame rate shall be low -+ // this is limit of CIF PCLK < 24.25Mhz -+ adcm3800_write(SREG_FRAME_RATE, 75); // 7.5 fps -+ } -+ else -+ { -+ //normal fps -+ adcm3800_write(SREG_FRAME_RATE, adcm_ctx->fps); -+ } -+ return 0; -+} -+ -+int adcm3800_set_fps(u16 fps) -+{ -+ if(fps > MAX_FPS) -+ { -+ return -EINVAL; -+ } -+ -+ if( fps!=adcm3800_context.fps ) -+ { -+ adcm3800_context.fps = fps; -+ adcm3800_context.SCL_partial = 1; // TODO: not confirmed -+ return 1; -+ } -+ return 0; -+} -+ -+static int adcm3800_register_gamma(int table) -+{ -+ dbg_print("set gamma table %d", table); -+ -+ const u16 value[][33] = -+ { -+ //0 default sRGB -+ { -+ 0x0000, 0x0017, 0x0032, 0x0046, 0x0056, 0x0064, 0x0071, 0x007c, 0x0086, 0x0099, 0x00a9, -+ 0x00b8, 0x00c6, 0x00df, 0x00f5, 0x0109, 0x011b, 0x013d, 0x015a, 0x0175, 0x018d, 0x01ba, -+ 0x01e1, 0x0205, 0x0225, 0x0261, 0x0295, 0x02c5, 0x02f1, 0x033f, 0x0385, 0x03c5, 0x0400}, -+ -+ //1 2.6 -+ { -+ 0x0000, 0x005c, 0x0079, 0x008d, 0x009e, 0x00ac, 0x00b9, 0x00c4, 0x00ce, 0x00e1, 0x00f1, -+ 0x0100, 0x010e, 0x0126, 0x013b, 0x014e, 0x0160, 0x0180, 0x019c, 0x01b5, 0x01cc, 0x01f5, -+ 0x0219, 0x023a, 0x0258, 0x028e, 0x02be, 0x02e9, 0x0310, 0x0356, 0x0394, 0x03cc, 0x0400}, -+ -+ //2 2.5 -+ { -+ 0x0000, 0x0054, 0x006f, 0x0083, 0x0093, 0x00a0, 0x00ac, 0x00b7, 0x00c2, 0x00d4, 0x00e4, -+ 0x00f2, 0x00ff, 0x0117, 0x012d, 0x0140, 0x0151, 0x0171, 0x018d, 0x01a6, 0x01bd, 0x01e7, -+ 0x020c, 0x022d, 0x024c, 0x0283, 0x02b3, 0x02df, 0x0308, 0x0350, 0x0390, 0x03ca, 0x0400}, -+ -+ //3 2.4 -+ { -+ 0x0000, 0x004C, 0x0065, 0x0078, 0x0087, 0x0094, 0x00A0, 0x00ab, 0x00b5, 0x00c6, 0x00d6, -+ 0x00e4, 0x00f1, 0x0109, 0x011E, 0x0131, 0x0142, 0x0161, 0x017D, 0x0197, 0x01AE, 0x01d8, -+ 0x01fd, 0x021F, 0x023E, 0x0276, 0x02a8, 0x02d5, 0x02ff, 0x0349, 0x038C, 0x03C8, 0x0400}, -+ -+ //4 2.3 -+ { -+ 0x0000, 0x0043, 0x005b, 0x006d, 0x007c, 0x0088, 0x0094, 0x009e, 0x00a7, 0x00b8, 0x00c8, -+ 0x00d6, 0x00e2, 0x00fa, 0x010e, 0x0121, 0x0132, 0x0151, 0x016d, 0x0187, 0x019e, 0x01c8, -+ 0x01ee, 0x0210, 0x0230, 0x0269, 0x029c, 0x02ca, 0x02f5, 0x0342, 0x0387, 0x03c6, 0x0400}, -+ -+ //5 2.2 -+ { -+ 0x0000, 0x003c, 0x0052, 0x0063, 0x0070, 0x007c, 0x0087, 0x0091, 0x0094, 0x00ab, 0x00b9, -+ 0x00c7, 0x00d3, 0x00ea, 0x00fe, 0x0111, 0x0122, 0x0141, 0x015d, 0x0176, 0x018d, 0x01b8, -+ 0x01de, 0x0201, 0x0221, 0x025b, 0x028f, 0x02bf, 0x02eb, 0x033b, 0x0382, 0x03c3, 0x0400}, -+ -+ //6 2.1 -+ { -+ 0x0000, 0x0034, 0x0049, 0x0058, 0x0065, 0x0070, 0x007b, 0x0084, 0x008d, 0x009d, 0x00ab, -+ 0x00b8, 0x00c4, 0x00da, 0x00ee, 0x0100, 0x0111, 0x0130, 0x014b, 0x0164, 0x017c, 0x01a7, -+ 0x01cd, 0x01f0, 0x0211, 0x024c, 0x0281, 0x02b2, 0x02e0, 0x0332, 0x037c, 0x03c0, 0x0400}, -+ -+ //7 2.0 -+ { -+ 0x0000, 0x002d, 0x0040, 0x004e, 0x005a, 0x0065, 0x006e, 0x0077, 0x0080, 0x008f, 0x009c, -+ 0x00a9, 0x00b5, 0x00ca, 0x00dd, 0x00ef, 0x0100, 0x011e, 0x0139, 0x0152, 0x016a, 0x0194, -+ 0x01bb, 0x01de, 0x0200, 0x023c, 0x0273, 0x02a5, 0x02d4, 0x0329, 0x0376, 0x03bd, 0x0400}, -+ -+ //8 1.9 -+ { -+ 0x0000, 0x0026, 0x0037, 0x0044, 0x004f, 0x0059, 0x0062, 0x006a, 0x0072, 0x0081, 0x008e, -+ 0x009a, 0x00a5, 0x00b9, 0x00cc, 0x00dd, 0x00ed, 0x010b, 0x0126, 0x013f, 0x0156, 0x0181, -+ 0x01a8, 0x01cc, 0x01ed, 0x022b, 0x0263, 0x0296, 0x02c6, 0x031f, 0x0370, 0x03ba, 0x0400}, -+ -+ //9 1.8 -+ { -+ 0x0000, 0x0020, 0x002f, 0x003a, 0x0045, 0x004e, 0x0056, 0x005e, 0x0065, 0x0073, 0x007f, -+ 0x008a, 0x0095, 0x00a9, 0x00bb, 0x00cb, 0x00db, 0x00f8, 0x0112, 0x012b, 0x0142, 0x016d, -+ 0x0194, 0x01b8, 0x01da, 0x0218, 0x0251, 0x0286, 0x02b8, 0x0314, 0x0368, 0x03b6, 0x0400}, -+ -+ //10 1.6 -+ { -+ 0x0000, 0x0014, 0x0020, 0x0029, 0x0031, 0x0038, 0x003f, 0x0046, 0x004c, 0x0057, 0x0062, -+ 0x006b, 0x0075, 0x0086, 0x0097, 0x00a6, 0x00b5, 0x00d0, 0x00e9, 0x0100, 0x0117, 0x0140, -+ 0x0167, 0x018c, 0x01ae, 0x01ee, 0x022a, 0x0262, 0x0297, 0x02fb, 0x0357, 0x03ae, 0x0400} -+ -+ }; -+ -+ int i, ret; -+ /* -+ for(i = 0; i < 33; i++) -+ { -+ adcm3800_write(0x1400+i*2, value[table][i]); -+ } -+ */ -+ -+ for(i = 0; i < 33; i++) -+ { -+ ret = adcm3800_write(EREG_TM_COEF_00_V+i*2, value[table][i]); -+ } -+ -+ return 0; -+} -+ -+static int adcm3800_register_gamma_solarize(void) -+{ -+ const u16 value[33] = -+ { -+ //solarize -+ 0x0400, 0x03e9, 0x03a9, 0x0344, 0x02c3, 0x0232, 0x019c, 0x010e, 0x0095, 0x003c, 0x0009, -+ 0x0002, 0x0026, 0x0074, 0x00e3, 0x016b, 0x01ff, 0x0294, 0x031c, 0x038b, 0x03d9, 0x03fd, -+ 0x03f6, 0x03c3, 0x036a, 0x02f1, 0x0263, 0x01cd, 0x013c, 0x00bb, 0x0056, 0x0016, 0x0000 -+ }; -+ -+ int i, ret; -+ /* -+ for(i = 0; i < 33; i++) -+ { -+ adcm3800_write(0x1400+i*2, value[i]); -+ } -+ */ -+ -+ for(i = 0; i < 33; i++) -+ { -+ ret = adcm3800_write(EREG_TM_COEF_00_V+i*2, value[i]); -+ } -+ -+ return 0; -+} -+ -+/***************** Image Styles ************************/ -+/* No special effect */ -+static const u16 agilent_adcm3800_normal_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x01ED, 0x01DB, 0x0038, -+ 0x004F, 0x01BE, 0x01F3, -+ 0x0000}; -+ -+/* Antique effect */ -+static const u16 agilent_adcm3800_antique_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x01F8, 0x01F8, 0x01F8, -+ 0x0008, 0x0008, 0x0008, -+ 0x0000}; -+ -+/* Black and White effect */ -+static const u16 agilent_adcm3800_black_and_white_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, -+ 0x0000}; -+ -+/* Color Negative effect */ -+static const u16 agilent_adcm3800_color_negative_effect[] = -+{0x01da, 0x01bf, 0x01f1, -+ 0x0013, 0x0025, 0x01c8, -+ 0x01b1, 0x0042, 0x000d, -+ 0x00ff}; -+ -+#if 0 -+/* saturation 50% effect */ -+static const u16 agilent_adcm3800_saturation_50_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x01e4, 0x01c9, 0x0054, -+ 0x0076, 0x019d, 0x01ed, -+ 0x0000}; -+ -+/* saturation 100% effect */ -+static const u16 agilent_adcm3800_saturation_100_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x01da, 0x01b6, 0x0070, -+ 0x009d, 0x017c, 0x01e6, -+ 0x0000}; -+ -+/* Reddish effect */ -+static const u16 agilent_adcm3800_red_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x01e4, 0x01db, 0x0038, -+ 0x0076, 0x01be, 0x01f3, -+ 0x0000}; -+ -+/* Greenish effect */ -+static const u16 agilent_adcm3800_green_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x01ed, 0x01c9, 0x0038, -+ 0x004f, 0x019d, 0x01F3, -+ 0x0000}; -+ -+/* Bluish effect */ -+static const u16 agilent_adcm3800_blue_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x01ed, 0x01db, 0x0054, -+ 0x004f, 0x01be, 0x01ed, -+ 0x0000}; -+ -+/* Cyan effect */ -+static const u16 agilent_adcm3800_cyan_effect[] = -+{0x0026, 0x004B, 0x000F, -+ 0x01f7, 0x01db, 0x0038, -+ 0x0027, 0x01be, 0x01f3, -+ 0x0000}; -+#endif -+ -+/* End additional matrices */ -+/*******************************************************/ -+ -+ -+/*set picture style(normal/black white/sepia/solarize/neg.art)*/ -+static int adcm3800_register_style(V4l_PIC_STYLE style) -+{ -+ u16 * reg_value; -+ u16 reg_count = 10; -+ reg_value = (u16 *)agilent_adcm3800_normal_effect; -+ switch(style) -+ { -+ case V4l_STYLE_BLACK_WHITE: -+ reg_value = (u16 *)agilent_adcm3800_black_and_white_effect; -+ break; -+ case V4l_STYLE_SEPIA: -+ reg_value = (u16 *)agilent_adcm3800_antique_effect; -+ break; -+ case V4l_STYLE_SOLARIZE: -+ break; -+ case V4l_STYLE_NEG_ART: -+ reg_value = (u16 *)agilent_adcm3800_color_negative_effect; -+ break; -+ default: -+ break; -+ } -+ -+ int i; -+ for(i = 0; i < reg_count; i++) -+ { -+ adcm3800_write(EREG_CSC_00_V+i*2, reg_value[i]); -+ } -+ return 0; -+} -+ -+/*set picture style(normal/black white/sepia/solarize/neg.art)*/ -+int adcm3800_set_style(V4l_PIC_STYLE style) -+{ -+ if( style!=adcm3800_context.style ) -+ { -+ adcm3800_context.style = style; -+ adcm3800_context.SCL_restart = 1; -+ return 1; -+ } -+ return 0; -+} -+ -+/******* Agilent Color Matrices ***************************/ -+ -+/* -+White Balance gains are located in registers 0x1064 (Red Gain) and 0x1066 (Blue Gains) -+ -+Color Correction Coeffecients are located in registers 0x1028-0x1038 -+ -+* To force write White Balance coeffecients, make sure AWB is off (bit 1 in 0x140) -+ -+* To force write Color Correction coeffiecients, make sure NACC is off (bit 3 in 0x140) -+ -+ -+The following are the register writes for various iluminants: -+ -+************************************************* -+Illuminant D50 -+************************************************* -+w 1064 12B -+w 1066 143 -+w 1028 23E EDF FE3 F3E 2A8 F1A FBC E23 321 -+------------------------ -+************************************************* -+Illuminant D55 -+************************************************* -+w 1064 134 -+w 1066 13B -+w 1028 233 EF7 FD7 F3F 29B F26 FC1 E40 2FF -+------------------------ -+************************************************* -+Illuminant D65 -+************************************************* -+w 1064 141 -+w 1066 12D -+w 1028 223 F17 FC6 F41 289 F36 FC6 E6A 2D0 -+------------------------ -+************************************************* -+Illuminant D75 -+************************************************* -+w 1064 14B -+w 1066 123 -+w 1028 21A F2C FBA F42 27D F40 FC7 E86 2B3 -+------------------------ -+************************************************* -+Illuminant D90 -+************************************************* -+w 1064 155 -+w 1066 118 -+w 1028 212 F40 FAF F44 272 F4A FC7 EA2 298 -+------------------------ -+************************************************* -+Illuminant FluorTriphosphor_4000K -+************************************************* -+w 1064 111 -+w 1066 16A -+w 1028 251 E44 06B F63 281 F1B FB7 E12 338 -+------------------------ -+************************************************* -+Illuminant Fluor_PhilipsUltraLume -+************************************************* -+w 1064 F3 -+w 1066 190 -+w 1028 212 DCA 125 F81 23D F42 F8E D81 3F1 -+------------------------ -+************************************************* -+Illuminant blackbody2600 -+************************************************* -+w 1064 E4 -+w 1066 176 -+w 1028 240 DDC 0E4 F49 2BC EFC F44 D57 465 -+------------------------ -+************************************************* -+Illuminant blackbody3200 -+************************************************* -+w 1064 FA -+w 1066 166 -+w 1028 217 E74 075 F50 27D F33 F8C DEA 38A -+------------------------ -+************************************************* -+Illuminant blackbody3500 -+************************************************* -+w 1064 104 -+w 1066 15E -+w 1028 20A EA2 055 F53 26C F41 F9E E19 349 -+------------------------ -+************************************************* -+Illuminant blackbody3800 -+************************************************* -+w 1064 10E -+w 1066 157 -+w 1028 1FF EC5 03D F55 25F F4C FAB E3D 318 -+------------------------ -+************************************************* -+Illuminant blackbody4200 -+************************************************* -+w 1064 118 -+w 1066 14E -+w 1028 1F4 EE7 025 F57 252 F56 FB7 E63 2E7 -+------------------------ -+************************************************* -+Illuminant blackbody4600 -+************************************************* -+w 1064 121 -+w 1066 146 -+w 1028 1EB F02 013 F59 249 F5E FBE E80 2C2 -+------------------------ -+************************************************* -+Illuminant boothCool_4070K -+************************************************* -+w 1064 126 -+w 1066 16C -+w 1028 201 ED8 027 F6D 274 F1F FAE E0F 343 -+------------------------ -+************************************************* -+Illuminant boothHorizon -+************************************************* -+w 1064 D5 -+w 1066 17D -+w 1028 264 D43 159 F47 313 EA6 EF5 CD9 531 -+------------------------ -+************************************************* -+Illuminant boothInca -+************************************************* -+w 1064 ED -+w 1066 170 -+w 1028 22C E29 0AB F4C 29A F1A F69 DA0 3F7 -+------------------------ -+************************************************* -+Illuminant fluorescent_3335K -+************************************************* -+w 1064 109 -+w 1066 186 -+w 1028 1DB E6A 0BB F83 229 F54 FA2 DE4 37A -+------------------------ -+************************************************* -+Illuminant halogen_2250K -+************************************************* -+w 1064 D5 -+w 1066 184 -+w 1028 213 D7F 16E F5C 2C2 EE2 F01 D43 4BC -+------------------------ -+*/ -+ -+/* Sunlight -+************************************************* -+Illuminant D65 -+************************************************* -+w 1064 141 -+w 1066 12D -+w 1028 223 F17 FC6 F41 289 F36 FC6 E6A 2D0 -+*/ -+static const u16 agilent_adcm3800_sunny_color_gain[] = -+{0x0141, 0x012D}; -+static const u16 agilent_adcm3800_sunny_color[] = -+{0x0223, 0x0F17, 0x0FC6, -+ 0x0F41, 0x0289, 0x0F36, -+ 0x0FC6, 0x0E6A, 0x02D0}; -+ -+/* Cloudy -+************************************************* -+Illuminant D75 -+************************************************* -+w 1064 14B -+w 1066 123 -+w 1028 21A F2C FBA F42 27D F40 FC7 E86 2B3 -+*/ -+static const u16 agilent_adcm3800_cloudy_color_gain[] = -+{0x014B, 0x0123}; -+static const u16 agilent_adcm3800_cloudy_color[] = -+{0x021A, 0x0F2C, 0x0FBA, -+ 0x0F42, 0x027D, 0x0F40, -+ 0x0FC7, 0x0E86, 0x02B3}; -+ -+ -+/* Indoor - home tungsten -+************************************************* -+Illuminant blackbody3200 -+************************************************* -+w 1064 FA -+w 1066 166 -+w 1028 217 E74 075 F50 27D F33 F8C DEA 38A -+*/ -+static const u16 agilent_adcm3800_home_tungsten_color_gain[] = -+{0x0FA, 0x0166}; -+static const u16 agilent_adcm3800_home_tungsten_color[] = -+{0x0217, 0x0E74, 0x0075, -+ 0x0F50, 0x027D, 0x0F33, -+ 0x0F8C, 0x0DEA, 0x038A}; -+ -+ -+/* Indoor - office cool white fluorescent -+************************************************* -+Illuminant fluorescent_3335K -+************************************************* -+w 1064 109 -+w 1066 186 -+w 1028 1DB E6A 0BB F83 229 F54 FA2 DE4 37A -+ * */ -+static const u16 agilent_adcm3800_office_fluorescent_color_gain[] = -+{0x0109, 0x0186}; -+static const u16 agilent_adcm3800_office_fluorescent_color[] = -+{0x01DB, 0x0E6A, 0x00BB, -+ 0x0F83, 0x0229, 0x0F54, -+ 0x0FA2, 0x0DE4, 0x037A}; -+ -+/* Night tungsten -+static const u16 agilent_adcm3800_night_tungsten_color[] = -+{0x034f, 0x0cdd, 0x00d3, -+ 0x0f47, 0x033c, 0x0e73, -+ 0x0f31, 0x0b2a, 0x06a3}; -+*/ -+ -+/* Automatic (generic default setting) 5500K sun-light -+************************************************* -+Illuminant D55 -+************************************************* -+w 1064 134 -+w 1066 13B -+w 1028 233 EF7 FD7 F3F 29B F26 FC1 E40 2FF -+*/ -+static const u16 agilent_adcm3800_automatic_color_gain[] = -+{0x0134, 0x013B}; -+static const u16 agilent_adcm3800_automatic_color[] = -+{0x0233, 0x0EF7, 0x0FD7, -+ 0x0F3F, 0x029B, 0x0F26, -+ 0x0FC1, 0x0E40, 0x02FF}; -+/*******************************************************/ -+ -+ -+static int adcm3800_register_light(V4l_PIC_WB light) -+{ -+ int i; -+ int awb = 0; -+ u16* color_cc; -+ u16* color_gain; -+ switch(light) -+ { -+ case V4l_WB_DIRECT_SUN: -+ awb = 0; -+ color_cc = (u16 *)agilent_adcm3800_sunny_color; -+ color_gain = (u16 *)agilent_adcm3800_sunny_color_gain; -+ break; -+ case V4l_WB_INCANDESCENT: -+ awb = 0; -+ color_cc = (u16 *)agilent_adcm3800_home_tungsten_color; -+ color_gain = (u16 *)agilent_adcm3800_home_tungsten_color_gain; -+ break; -+ case V4l_WB_FLUORESCENT: -+ awb = 1; -+ color_cc = (u16 *)agilent_adcm3800_office_fluorescent_color; -+ color_gain = (u16 *)agilent_adcm3800_office_fluorescent_color_gain; -+ break; -+ default: -+ awb = 1; -+ color_cc = (u16 *)agilent_adcm3800_automatic_color; -+ color_gain = (u16 *)agilent_adcm3800_automatic_color_gain; -+ break; -+ } -+ -+ u16 value_r140; -+ adcm3800_read(EREG_AF_CTRL1, &value_r140); -+ // disable AWB NACC -+ adcm3800_write(EREG_AF_CTRL1, value_r140&(~0x02)&(~0x08)); -+ -+ for(i = 0; i< 9; i++) -+ { -+ adcm3800_write(EREG_CC_COEF_00+i*2, color_cc[i]); -+ } -+#if 1 -+ for(i = 0; i< 9; i++) -+ { -+ u16 value; -+ adcm3800_read(0x0270+i*2, &value); -+ adcm3800_write(0x0270+i*2, (value&0xf000)|color_cc[i]); -+ } -+#endif -+ -+ for(i = 0; i< 2; i++) -+ { -+ adcm3800_write(0x1064+i*2, color_gain[i]); -+ } -+ -+ // tighter awb tolerances ??? -+ // w 17c 108 110 -+ //adcm3800_write(EREG_AWB_TOL_ACQ, 0x0108); -+ //adcm3800_write(EREG_AWB_TOL_MON, 0x0110); -+ -+ if(awb) { -+ adcm3800_write(EREG_AF_CTRL1, value_r140|0x02); // enable AWB -+ } -+ else { -+ adcm3800_write(EREG_AF_CTRL1, value_r140&(~0x02)); // disable AWB -+ } -+ return 0; -+} -+ -+int adcm3800_set_light(V4l_PIC_WB light) -+{ -+ if( light!=adcm3800_context.light ) -+ { -+ adcm3800_context.light = light; -+ adcm3800_context.SCL_restart = 1; -+ return 1; -+ } -+ return 0; -+} -+ -+/*set exposure compensation */ -+static int adcm3800_register_exp_comp(int bright) -+{ -+ const u16 exp_adj[] = -+ { -+ 0x0108, // -2.0 EV -+ 0x0106, // -1.5 EV -+ 0x0104, // -1.0 EV -+ 0x0102, // -0.5 EV -+ 0x0000, // 0.0 EV -+ 0x0002, // +0.5 EV -+ 0x0004, // +1.0 EV -+ 0x0006, // +1.5 EV -+ 0x0008 // +2.0 EV -+ }; -+ -+ if(bright < -4 || bright > 4) -+ { -+ return -EINVAL; -+ } -+ -+ int value = exp_adj[bright+4]; -+ value |= 0x0200; // set center zone exposure -+ adcm3800_write(SREG_EXP_ADJ, value); -+ return 0; -+} -+ -+/*set picture brightness*/ -+static int adcm3800_register_bright(int bright) -+{ -+ const u16 target[] = -+ { -+ 16, //0x0010, // -2.0 EV -+ 23, //0x0017, // -1.5 EV -+ 32, //0x0020, // -1.0 EV -+ 45, //0x002d, // -0.5 EV -+ 64, //0x0040, // 0.0 EV -+ 90, //0x005a, // +0.5 EV -+ 128, //0x0080, // +1.0 EV -+ 181, //0x00b5, // +1.5 EV -+ 240 //0x00f0 // +2.0 EV -+ }; -+ -+ if(bright < -4 || bright > 4) -+ { -+ return -EINVAL; -+ } -+ adcm3800_write(EREG_AE_TARGET, target[bright+4]); -+ return 0; -+} -+ -+/*set picture brightness*/ -+int adcm3800_set_bright(int bright) -+{ -+ adcm3800_context.bright = bright; -+ adcm3800_register_bright(bright); -+ return 0; -+} -+ -+static int adcm3800_register_exposure_mode(V4l_NM mode, int maxexpotime) -+{ -+ adcm3800_write(EREG_AE_ETIME_MAX, maxexpotime/10); -+ return 0; -+} -+ -+/*set exposure mode: normal/night */ -+int adcm3800_set_exposure_mode(V4l_NM mode, int maxexpotime) -+{ -+ if(maxexpotime<10 && maxexpotime>500000) // 500ms > time > 10us -+ return -EINVAL; -+ -+ if(adcm3800_context.max_expotime != maxexpotime) -+ { -+ adcm3800_context.max_expotime = maxexpotime; -+ adcm3800_context.SCL_restart = 1; -+ return 1; -+ } -+ return 0; -+} -+ -+int adcm3800_set_flicker(int flicker) -+{ -+ adcm3800_context.flicker_freq = flicker; -+ u16 old; -+ u16 old1; -+ adcm3800_read(EREG_AF_CTRL2, &old); -+ adcm3800_read(SREG_ILLUM, &old1); -+ old1 &= ~(0x18); -+ dbg_print("set flicker to %d", flicker); -+ if(flicker == 50) -+ { -+ adcm3800_write(SREG_ILLUM, old1|0x08); -+ adcm3800_write(EREG_AF_CTRL2, old&(~0x02)); -+ //1000 = 100000/50/2 -+ adcm3800_write(EREG_AE_ETIME_DFLT, 1000); -+ } -+ else if(flicker == 60) -+ { -+ adcm3800_write(SREG_ILLUM, old1|0x10); -+ adcm3800_write(EREG_AF_CTRL2, old|0x02); -+ // 833 = 100000/60/2 -+ adcm3800_write(EREG_AE_ETIME_DFLT, 833); -+ } -+ else -+ { -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+// SCL restart -+static int adcm3800_SCL_restart(p_camera_context_t cam_ctx, int frames) -+{ -+ int ret; -+ -+ /*stop camera*/ -+ adcm3800_write(SREG_CONTROL, 0); -+ -+ //update simple registers -+ adcm3800_register_fps(&adcm3800_context); -+ -+ adcm3800_register_output_format(adcm3800_context.format); -+ -+ adcm3800_write(SREG_SIZE, 0x0f0f); // perfer image quality, disallow subsampling -+ //sensor width and sensor height -+ adcm3800_register_sensor_size(adcm3800_context.sensor_w, adcm3800_context.sensor_h); -+ //output width and output height -+ adcm3800_register_output_size(adcm3800_context.output_w, adcm3800_context.output_h); -+ -+ if(adcm3800_context.style == V4l_STYLE_SOLARIZE ) { -+ adcm3800_register_gamma_solarize(); -+ } -+ else if(frames == 1) { -+ adcm3800_register_gamma(0); // gamma sRGB, still mode -+ } -+ else { -+ adcm3800_register_gamma(5); // gamma 2.0, video mode -+ } -+ -+ //adcm3800_print_status(); -+ -+ // SCL -+ ret = wait_sreg_update(); -+ if(ret<0) -+ return ret; -+ -+ //adcm3800_print_status(); -+ -+ // set AE_GAIN to improve pink at center issue -+ // w 150 240 280 500 280 -+#if 1 -+ adcm3800_write(EREG_AE_GAIN_MIN, 0x0240); -+ adcm3800_write(EREG_AE_GAIN_MIN_P, 0x0280); -+ adcm3800_write(EREG_AE_GAIN_MAX, 0x0500); -+ adcm3800_write(EREG_AE_GAIN_DFLT, 0x0280); -+#endif -+ -+ adcm3800_register_style(adcm3800_context.style); -+ -+ // re-initialize auto functions -+ u16 v_ctrl2; -+ adcm3800_read(EREG_AF_CTRL2, &v_ctrl2); -+ adcm3800_write(EREG_AF_CTRL2, v_ctrl2|0x0040); -+ -+ //adcm3800_print_status(); -+ -+ // set max exposure time -+ adcm3800_register_exposure_mode(adcm3800_context.expo_mode, -+ adcm3800_context.max_expotime); -+ -+ // set brightness -+ adcm3800_register_bright(adcm3800_context.bright); -+ -+ // set white balance -+ adcm3800_register_light(adcm3800_context.light); -+ -+ // start video mode -+ adcm3800_write(SREG_CONTROL, 0x01); -+ -+ //adcm3800_print_status(); -+ -+ adcm3800_write(EREG_AF_CTRL2, v_ctrl2); -+ -+ return 0; -+} -+ -+// SCL partial -+int adcm3800_SCL_partial(p_camera_context_t cam_ctx, int frames) -+{ -+ //update simple registers -+ adcm3800_register_fps(&adcm3800_context); -+ -+ adcm3800_write(SREG_SIZE, 0x0f0f); // perfer image quality, disallow subsampling -+ //sensor width and sensor height -+ adcm3800_register_sensor_size(adcm3800_context.sensor_w, adcm3800_context.sensor_h); -+ -+ //output width and output height -+ adcm3800_register_output_size(adcm3800_context.output_w, adcm3800_context.output_h); -+ -+ if(adcm3800_context.style == V4l_STYLE_SOLARIZE ) { -+ adcm3800_register_gamma_solarize(); -+ } -+ else if(frames == 1) { -+ adcm3800_register_gamma(0); // gamma sRGB, still mode -+ } -+ else { -+ adcm3800_register_gamma(5); // gamma 2.0, video mode -+ } -+ -+ // partial simple control -+ // still mode -+ -+ //adcm3800_print_status(); -+ -+ // partial config -+ adcm3800_write(SREG_CONTROL, 0x21); -+ -+ //adcm3800_print_status(); -+ -+ return 0; -+} -+ -+int adcm3800_reconfigure(p_camera_context_t cam_ctx, int frames) -+{ -+ dbg_print("sensor width %d", cam_ctx->sensor_width); -+ dbg_print("sensor height %d", cam_ctx->sensor_height); -+ dbg_print("capture_width %d", cam_ctx->capture_width); -+ dbg_print("capture_height %d", cam_ctx->capture_height); -+ ddbg_print("fps %d", cam_ctx->fps); -+ ddbg_print("light %d", cam_ctx->capture_light); -+ ddbg_print("capture_bright %d", cam_ctx->capture_bright); -+ ddbg_print("capture_style %d", cam_ctx->capture_style); -+ -+ int ret = 0; -+ if(adcm3800_context.SCL_restart != 0) -+ { -+ ret = adcm3800_SCL_restart(cam_ctx, frames); -+ adcm3800_context.SCL_restart = 0; -+ } -+ else if(adcm3800_context.SCL_partial != 0) -+ { -+ ret = adcm3800_SCL_partial(cam_ctx, frames); -+ adcm3800_context.SCL_partial = 0; -+ } -+ -+ return ret; -+} -+ -+// -+// This is an example of how to implement a firmware patch table. -+// The patch data contained here is the ADCM-3800 patch version 3. -+// -+// The first array is the starting register address of each contiguous block -+// of data to write. The second array is the number of words to write for -+// each block. These arrays are terminated with a zero entry. Some other -+// method could also be used to know how many patch blocks there are, -+// such as using the sizeof() operator, or a separate defined constant. -+// -+// The third array contains the patch data to be written, formatted according -+// to the length of each block. The length of the third array should equal -+// the sum of the entries in the second array. -+// -+ -+// patch code ver.7, 10/20/2004 -+static unsigned short patch3800addr[] = { -+ 0x0186, 0x484c, 0x488c, 0x4838, 0x4818, 0x4898, -+ 0x4980, 0x002c, 0x0034, 0x4820, 0x486C, -+ 0x4860, 0x4804, 0x4854, 0x487C, 0x4894, 0x482C, 0x4834, 0x4800, -+ 0x4868, 0x4C80, 0x0062, 0x006A, 0x0186, -+ 0}; -+static unsigned short patch3800len [] = { -+ 3, 2, 2, 2, 2, 2, -+ 352, 4, 4, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 1104, 4, 2, 2, -+ 0}; -+static unsigned short patch3800data[] = -+{ -+ // #Load patch -+ // 0x0186, 3 -+ 0x0000, 0x0000, 0x0000, -+ // 484C, 2 -+ 0x0002, 0x0012, -+ // 488C, 2 -+ 0x0002, 0x437e, -+ // 4838, 2 -+ 0x0002, 0x4385, -+ // 4818, 2 -+ 0x0002, 0x0564, -+ // 4898, 2 -+ 0x0002, 0x43a0, -+ -+ // #PI patch -+ // 0x4980, 352 -+ 0x0000, 0x00C0, 0x0000, 0x00EA, 0x0000, 0x0212, 0x0000, 0xFF40, -+ 0x0000, 0xFFAF, 0x0000, 0xFF44, 0x0000, 0x0272, 0x0000, 0xFF4A, -+ 0x0000, 0xFFC7, 0x0000, 0xFEA2, 0x0000, 0x0298, 0x0000, 0x00C6, -+ 0x0000, 0x00E1, 0x0000, 0x021A, 0x0000, 0xFF2C, 0x0000, 0xFFBA, -+ 0x0000, 0xFF42, 0x0000, 0x027D, 0x0000, 0xFF40, 0x0000, 0xFFC7, -+ 0x0000, 0xFE86, 0x0000, 0x02B3, 0x0000, 0x00CC, 0x0000, 0x00DA, -+ 0x0000, 0x0223, 0x0000, 0xFF17, 0x0000, 0xFFC6, 0x0000, 0xFF41, -+ 0x0000, 0x0289, 0x0000, 0xFF36, 0x0000, 0xFFC6, 0x0000, 0xFE6A, -+ 0x0000, 0x02D0, 0x0000, 0x00D5, 0x0000, 0x00D0, 0x0000, 0x0233, -+ 0x0000, 0xFEF7, 0x0000, 0xFFD7, 0x0000, 0xFF3F, 0x0000, 0x029B, -+ 0x0000, 0xFF26, 0x0000, 0xFFC1, 0x0000, 0xFE40, 0x0000, 0x02FF, -+ 0x0000, 0x00DB, 0x0000, 0x00CB, 0x0000, 0x023E, 0x0000, 0xFEDF, -+ 0x0000, 0xFFE3, 0x0000, 0xFF3E, 0x0000, 0x02A8, 0x0000, 0xFF1A, -+ 0x0000, 0xFFBC, 0x0000, 0xFE23, 0x0000, 0x0321, 0x0000, 0x00E3, -+ 0x0000, 0x00C9, 0x0000, 0x01EB, 0x0000, 0xFF02, 0x0000, 0x0013, -+ 0x0000, 0xFF59, 0x0000, 0x0249, 0x0000, 0xFF5E, 0x0000, 0xFFBE, -+ 0x0000, 0xFE80, 0x0000, 0x02C2, 0x0000, 0x00EA, 0x0000, 0x00C4, -+ 0x0000, 0x01F4, 0x0000, 0xFEE7, 0x0000, 0x0025, 0x0000, 0xFF57, -+ 0x0000, 0x0252, 0x0000, 0xFF56, 0x0000, 0xFFB7, 0x0000, 0xFE63, -+ 0x0000, 0x02E7, 0x0000, 0x00F3, 0x0000, 0x00BF, 0x0000, 0x01FF, -+ 0x0000, 0xFEC5, 0x0000, 0x003D, 0x0000, 0xFF55, 0x0000, 0x025F, -+ 0x0000, 0xFF4C, 0x0000, 0xFFAB, 0x0000, 0xFE3D, 0x0000, 0x0318, -+ 0x0000, 0x00DF, 0x0000, 0x00B4, 0x0000, 0x0201, 0x0000, 0xFED8, -+ 0x0000, 0x0027, 0x0000, 0xFF6D, 0x0000, 0x0274, 0x0000, 0xFF1F, -+ 0x0000, 0xFFAE, 0x0000, 0xFE0F, 0x0000, 0x0343, 0x0000, 0x00FC, -+ 0x0000, 0x00BB, 0x0000, 0x020A, 0x0000, 0xFEA2, 0x0000, 0x0055, -+ 0x0000, 0xFF53, 0x0000, 0x026C, 0x0000, 0xFF41, 0x0000, 0xFF9E, -+ 0x0000, 0xFE19, 0x0000, 0x0349, 0x0000, 0x0106, 0x0000, 0x00B7, -+ 0x0000, 0x0217, 0x0000, 0xFE74, 0x0000, 0x0075, 0x0000, 0xFF50, -+ 0x0000, 0x027D, 0x0000, 0xFF33, 0x0000, 0xFF8C, 0x0000, 0xFDEA, -+ 0x0000, 0x038A, 0x0000, 0x00F7, 0x0000, 0x00A8, 0x0000, 0x01DB, -+ 0x0000, 0xFE6A, 0x0000, 0x00BB, 0x0000, 0xFF83, 0x0000, 0x0229, -+ 0x0000, 0xFF54, 0x0000, 0xFFA2, 0x0000, 0xFDE4, 0x0000, 0x037A, -+ 0x0000, 0x0114, 0x0000, 0x00B2, 0x0000, 0x022C, 0x0000, 0xFE29, -+ 0x0000, 0x00AB, 0x0000, 0xFF4C, 0x0000, 0x029A, 0x0000, 0xFF1A, -+ 0x0000, 0xFF69, 0x0000, 0xFDA0, 0x0000, 0x03F7, 0x0000, 0x010E, -+ 0x0000, 0x00A4, 0x0000, 0x0212, 0x0000, 0xFDCA, 0x0000, 0x0125, -+ 0x0000, 0xFF81, 0x0000, 0x023D, 0x0000, 0xFF42, 0x0000, 0xFF8E, -+ 0x0000, 0xFD81, 0x0000, 0x03F1, 0x0000, 0x0120, 0x0000, 0x00AF, -+ 0x0000, 0x0240, 0x0000, 0xFDDC, 0x0000, 0x00E4, 0x0000, 0xFF49, -+ 0x0000, 0x02BC, 0x0000, 0xFEFC, 0x0000, 0xFF44, 0x0000, 0xFD57, -+ 0x0000, 0x0465, 0x0000, 0x0134, 0x0000, 0x00AC, 0x0000, 0x0264, -+ 0x0000, 0xFD43, 0x0000, 0x0159, 0x0000, 0xFF47, 0x0000, 0x0313, -+ 0x0000, 0xFEA6, 0x0000, 0xFEF5, 0x0000, 0xFCD9, 0x0000, 0x0531, -+ // 002c, 4 -+ 0x0080, 0x001A, 0x0034, 0x1388, -+ // 0034, 4 -+ 0x03E8, 0x0000, 0x07D0, 0x0001, -+ // 4820, 2, -+ 0x0002, 0x4320, -+ // 486C, 2 -+ 0x0002, 0x432F, -+ // 4860, 2 -+ 0x0002, 0x44C0, -+ // 4804, 2 -+ 0x0002, 0x44DF, -+ // 4854, 2 -+ 0x0002, 0x1D8B, -+ // 487C, 2 -+ 0x0002, 0x4510, -+ // 4894, 2 -+ 0x0002, 0x4516, -+ // 482C, 2 -+ 0x0002, 0x451E, -+ // 4834, 2 -+ 0x0002, 0x4522, -+ // 4800, 2 -+ 0x0002, 0x4536, -+ // 4868, 2 -+ 0x0002, 0x4538, -+ // 4C80, 1104 -+ 0x0003, 0x1DB3, 0x0000, 0x0632, 0x0009, 0x0006, 0x0000, 0x661F, -+ 0x0009, 0x0004, 0x0000, 0x6620, 0x0009, 0x0118, 0x0000, 0x6725, -+ 0x0009, 0x014e, 0x0000, 0x6726, 0x0009, 0x0118, 0x0000, 0x6532, -+ 0x0009, 0x014e, 0x0000, 0x6533, 0x0000, 0x01FF, 0x0000, 0x0958, -+ 0x0000, 0x0960, 0x0000, 0x0968, 0x0000, 0x0970, 0x0000, 0x0978, -+ 0x0000, 0x4F23, 0x0000, 0x4722, 0x0000, 0x024B, 0x0000, 0x01A3, -+ 0x0000, 0x091E, 0x000B, 0xFE26, 0x0009, 0x8480, 0x0000, 0x08CB, -+ 0x000B, 0xFE27, 0x0009, 0x001E, 0x0000, 0x08CB, 0x0009, 0xFE26, -+ // 4D00 -+ 0x0000, 0x6621, 0x0000, 0x7A22, 0x0009, 0xFE26, 0x0000, 0x6623, -+ 0x0003, 0x449B, 0x000B, 0xFE27, 0x0000, 0x085B, 0x000A, 0x0000, -+ 0x0000, 0x0153, 0x0006, 0x434B, 0x0002, 0x434E, 0x000B, 0xFE26, -+ 0x0009, 0xFFFF, 0x0000, 0x08CB, 0x0009, 0x0010, 0x0000, 0x662A, -+ 0x000B, 0xFE26, 0x0000, 0x0873, 0x0000, 0x5620, 0x000B, 0x0000, -+ 0x0000, 0x4A19, 0x0000, 0x0156, 0x0007, 0x435B, 0x000A, 0x0001, -+ 0x0000, 0x0155, 0x0004, 0x435B, 0x0002, 0x4363, 0x0000, 0x5219, -+ 0x0000, 0x042C, 0x0000, 0x4A19, 0x0000, 0x0054, 0x0000, 0x0166, -+ 0x0007, 0x4362, 0x0002, 0x4363, 0x0002, 0x4364, 0x0000, 0x0183, -+ 0x0000, 0x031B, 0x0005, 0x436A, 0x0009, 0x0205, 0x0000, 0x662A, -+ 0x000D, 0x0001, 0x0002, 0x43AE, 0x000B, 0x0000, 0x0000, 0x4A1A, -+ 0x0000, 0x0156, 0x0007, 0x4372, 0x000A, 0x0002, 0x0000, 0x0155, -+ 0x0004, 0x4372, 0x0002, 0x437A, 0x0000, 0x521A, 0x0000, 0x042C, -+ 0x0000, 0x4A1A, 0x0000, 0x0054, 0x0000, 0x0166, 0x0007, 0x4379, -+ 0x0002, 0x437A, 0x0002, 0x437B, 0x0000, 0x0183, 0x0000, 0x031B, -+ 0x0005, 0x4381, 0x0009, 0x0003, 0x0000, 0x662A, 0x000D, 0x0002, -+ // 4E00 -+ 0x0002, 0x43AE, 0x000B, 0x0000, 0x0000, 0x4A1B, 0x0000, 0x0156, -+ 0x0007, 0x4389, 0x000A, 0x0003, 0x0000, 0x0155, 0x0004, 0x4389, -+ 0x0002, 0x4391, 0x0000, 0x521B, 0x0000, 0x042C, 0x0000, 0x4A1B, -+ 0x0000, 0x0054, 0x0000, 0x0166, 0x0007, 0x4390, 0x0002, 0x4391, -+ 0x0002, 0x4392, 0x0000, 0x0183, 0x0000, 0x031B, 0x0005, 0x4396, -+ 0x000D, 0x0003, 0x0002, 0x43AE, 0x000B, 0x0000, 0x0000, 0x4A1C, -+ 0x0000, 0x0156, 0x0007, 0x439E, 0x000A, 0x0004, 0x0000, 0x0155, -+ 0x0004, 0x439E, 0x0002, 0x43A6, 0x0000, 0x521C, 0x0000, 0x042C, -+ 0x0000, 0x4A1C, 0x0000, 0x0054, 0x0000, 0x0166, 0x0007, 0x43A5, -+ 0x0002, 0x43A6, 0x0002, 0x43A7, 0x0000, 0x0183, 0x0000, 0x031B, -+ 0x0005, 0x43AD, 0x000D, 0x0004, 0x0009, 0x0010, 0x0000, 0x662A, -+ 0x0002, 0x43AE, 0x000D, 0x0005, 0x0000, 0x7620, 0x0000, 0x4F4D, -+ 0x0000, 0x474C, 0x0000, 0x028B, 0x0000, 0x4725, 0x0000, 0x028B, -+ 0x0000, 0x091F, 0x0000, 0x4F4E, 0x0000, 0x474C, 0x0000, 0x028B, -+ 0x0000, 0x4726, 0x0000, 0x028B, 0x0000, 0x6E25, 0x0000, 0x462A, -+ 0x0000, 0x0439, 0x0000, 0x6629, 0x0000, 0x4629, 0x000A, 0x000B, -+ // 4F00 -+ 0x0000, 0x0251, 0x0000, 0x01D3, 0x000A, 0x4260, 0x0000, 0x005A, -+ 0x0000, 0x6A2B, 0x0000, 0x4E2B, 0x0000, 0x0853, 0x0000, 0x6A21, -+ 0x0000, 0x7E22, 0x0000, 0x4E2B, 0x0000, 0x0183, 0x0000, 0x0853, -+ 0x0000, 0x6A23, 0x0000, 0x4625, 0x0000, 0x6624, 0x0003, 0x4485, -+ 0x0000, 0x6628, 0x0000, 0x5629, 0x0000, 0x0185, 0x0000, 0x4E2A, -+ 0x0000, 0x2CFF, 0x0000, 0x015D, 0x0007, 0x43D8, 0x0002, 0x43F0, -+ 0x0000, 0x462B, 0x000A, 0x000B, 0x0000, 0x0051, 0x0000, 0x662B, -+ 0x0000, 0x4E2B, 0x0000, 0x0853, 0x0000, 0x6A21, 0x0000, 0x7E22, -+ 0x0000, 0x4E2B, 0x0000, 0x0183, 0x0000, 0x0853, 0x0000, 0x6A23, -+ 0x0000, 0x4625, 0x0000, 0x6624, 0x0003, 0x4485, 0x0000, 0x090E, -+ 0x0000, 0x4A28, 0x0000, 0x0156, 0x0007, 0x43EC, 0x0002, 0x43EE, -+ 0x0000, 0x7A28, 0x0000, 0x7629, 0x0000, 0x0185, 0x0002, 0x43D3, -+ 0x0000, 0x461F, 0x000A, 0x000B, 0x0000, 0x0251, 0x0000, 0x01D3, -+ 0x000A, 0x4260, 0x0000, 0x005A, 0x0000, 0x6A2B, 0x0000, 0x4E2B, -+ 0x0000, 0x0853, 0x0000, 0x6A21, 0x0000, 0x7E22, 0x0000, 0x4E2B, -+ 0x0000, 0x0183, 0x0000, 0x0853, 0x0000, 0x6A23, 0x0000, 0x4625, -+ // 5000 -+ 0x0000, 0x6624, 0x0003, 0x4485, 0x0000, 0x090E, 0x0000, 0x4629, -+ 0x0000, 0x4A1F, 0x0000, 0x0151, 0x0004, 0x4409, 0x0000, 0x0602, -+ 0x0002, 0x4416, 0x0000, 0x4A28, 0x0000, 0x02B2, 0x0000, 0x0913, -+ 0x0000, 0x4A16, 0x0000, 0x0153, 0x0006, 0x4410, 0x0002, 0x4415, -+ 0x0000, 0x461F, 0x0000, 0x6629, 0x0000, 0x7A28, 0x0000, 0x0602, -+ 0x0002, 0x4416, 0x0000, 0x0622, 0x0000, 0x0652, 0x0005, 0x4422, -+ 0x0000, 0x4628, 0x0000, 0x4A17, 0x0000, 0x0151, 0x0007, 0x441D, -+ 0x0002, 0x4421, 0x0000, 0x0612, 0x0009, 0x0000, 0x0000, 0x661E, -+ 0x0000, 0x0622, 0x0002, 0x442B, 0x0000, 0x4628, 0x0000, 0x4A18, -+ 0x0000, 0x0151, 0x0006, 0x4427, 0x0002, 0x442B, 0x0000, 0x0632, -+ 0x0009, 0x0001, 0x0000, 0x661E, 0x0000, 0x0622, 0x000B, 0x0000, -+ 0x0000, 0x4629, 0x000A, 0x0005, 0x0000, 0x0151, 0x0007, 0x4435, -+ 0x0000, 0x4620, 0x000A, 0x0002, 0x0000, 0x0151, 0x0006, 0x4435, -+ 0x0000, 0x0183, 0x0000, 0x031B, 0x0005, 0x443B, 0x0000, 0x0632, -+ 0x0000, 0x0622, 0x0009, 0x0002, 0x0000, 0x6629, 0x0000, 0x0642, -+ 0x0005, 0x447B, 0x0000, 0x0605, 0x0000, 0x0606, 0x0000, 0x4629, -+ // 5100 -+ 0x000A, 0x000B, 0x0000, 0x0251, 0x0000, 0x01D3, 0x000A, 0x4260, -+ 0x0000, 0x0053, 0x000A, 0x000A, 0x0000, 0x0053, 0x0000, 0x6E2B, -+ 0x0000, 0x8EA0, 0x0005, 0x444D, 0x0009, 0xFF40, 0x0000, 0x662C, -+ 0x0002, 0x444F, 0x0009, 0xFD1C, 0x0000, 0x662C, 0x000D, 0x0001, -+ 0x000A, 0x000A, 0x0000, 0x0155, 0x0007, 0x4454, 0x0002, 0x4460, -+ 0x0000, 0x4E2C, 0x0000, 0x0193, 0x0000, 0x6E2C, 0x0000, 0x0183, -+ 0x0000, 0x522B, 0x0000, 0x0194, 0x0000, 0x722B, 0x0000, 0x0184, -+ 0x0000, 0x0864, 0x0000, 0x08E3, 0x0000, 0x0185, 0x0002, 0x4450, -+ 0x0000, 0x0652, 0x0005, 0x4472, 0x0000, 0x4E2B, 0x0000, 0x0193, -+ 0x0000, 0x6E2B, 0x0000, 0x0183, 0x0000, 0x085B, 0x000A, 0x0100, -+ 0x0000, 0x029A, 0x0000, 0x0913, 0x0000, 0x6F26, 0x0000, 0x4E2B, -+ 0x0000, 0x085B, 0x000A, 0x0100, 0x0000, 0x029A, 0x0000, 0x0913, -+ 0x0000, 0x6F25, 0x0002, 0x447A, 0x000A, 0x0100, 0x0000, 0x02BA, -+ 0x0000, 0x0913, 0x0000, 0x6F25, 0x000B, 0x0100, 0x0000, 0x4625, -+ 0x0000, 0x028B, 0x0000, 0x6F26, 0x0002, 0x447D, 0x0000, 0x0625, -+ 0x0000, 0x0626, 0x0000, 0x4629, 0x0000, 0x661F, 0x0000, 0x0838, -+ // 5200 -+ 0x0000, 0x0830, 0x0000, 0x0828, 0x0000, 0x0820, 0x0000, 0x0818, -+ 0x0000, 0x01FF, 0x0000, 0x0958, 0x0000, 0x4621, 0x0000, 0x4A22, -+ 0x0003, 0x4493, 0x0000, 0x090B, 0x0000, 0x4623, 0x0000, 0x4A24, -+ 0x0003, 0x4493, 0x0000, 0x0059, 0x0000, 0x01FB, 0x0005, 0x4491, -+ 0x0009, 0xFFFF, 0x0000, 0x0818, 0x0000, 0x01FF, 0x0000, 0x008A, -+ 0x0000, 0x0212, 0x0000, 0x01D1, 0x0000, 0x01C2, 0x0000, 0x0352, -+ 0x0005, 0x449A, 0x0009, 0xFFFF, 0x0000, 0x01FF, 0x0000, 0x0958, -+ 0x0000, 0x0960, 0x0000, 0x0978, 0x0000, 0x4A21, 0x0000, 0x080A, -+ 0x0000, 0x0852, 0x0000, 0x4E22, 0x000C, 0x0000, 0x000F, 0x0020, -+ 0x0000, 0x060A, 0x0000, 0x0404, 0x0000, 0x01FB, 0x0005, 0x44A9, -+ 0x0000, 0x062A, 0x0000, 0x05AF, 0x0005, 0x44AC, 0x0000, 0x0540, -+ 0x0000, 0x0402, 0x0000, 0x059F, 0x0005, 0x44B0, 0x0000, 0x0520, -+ 0x0000, 0x0401, 0x0000, 0x064A, 0x0004, 0x44B5, 0x0000, 0x015C, -+ 0x0007, 0x44B7, 0x0000, 0x00DC, 0x0000, 0x0510, 0x0000, 0x0197, -+ 0x0004, 0x44A4, 0x0000, 0x4E23, 0x0000, 0x088B, 0x0000, 0x08D3, -+ 0x0000, 0x0838, 0x0000, 0x0820, 0x0000, 0x0818, 0x0000, 0x01FF, -+ // 5300 -+ 0x0000, 0x060D, 0x0000, 0x513F, 0x000F, 0x0008, 0x0000, 0x00FC, -+ 0x0000, 0x5540, 0x0000, 0x00FD, 0x0000, 0x026C, 0x0000, 0x01A7, -+ 0x0000, 0x52A5, 0x0000, 0x0414, 0x0000, 0x0267, 0x0000, 0x01A7, -+ 0x0000, 0x7E50, 0x000F, 0x0000, 0x0000, 0x7E51, 0x0000, 0x7E53, -+ 0x0000, 0x7E55, 0x000B, 0x0000, 0x0002, 0x44D4, 0x0000, 0x0183, -+ 0x0000, 0x5EA6, 0x0000, 0x017B, 0x0006, 0x21A8, 0x000F, 0x4230, -+ 0x0000, 0x001F, 0x0000, 0x0877, 0x0000, 0x5253, 0x0000, 0x0074, -+ 0x0000, 0x7254, 0x000F, 0xFE31, 0x0002, 0x218D, 0x0000, 0x5E01, -+ 0x0000, 0x05F5, 0x0005, 0x004C, 0x0000, 0x04F5, 0x0000, 0x7E01, -+ 0x0003, 0x0213, 0x0000, 0x46AF, 0x0000, 0x0948, 0x0000, 0x4722, -+ 0x0000, 0x0948, 0x0000, 0x4723, 0x0000, 0x0948, 0x0000, 0x060A, -+ 0x0003, 0x05DC, 0x0000, 0x062A, 0x0003, 0x05DC, 0x0000, 0x060A, -+ 0x0003, 0x06EC, 0x0000, 0x675E, 0x0000, 0x062A, 0x0003, 0x06EC, -+ 0x0000, 0x675F, 0x0009, 0x44FA, 0x0000, 0x0948, 0x0009, 0xFFFB, -+ 0x0000, 0x0048, 0x0002, 0x0564, 0x0000, 0x0808, 0x0000, 0x6723, -+ 0x0000, 0x0808, 0x0000, 0x6722, 0x0000, 0x0808, 0x0000, 0x66AF, -+ // 5400 -+ 0x0003, 0x02BC, 0x0000, 0x7E67, 0x0000, 0x7A68, 0x0000, 0x7269, -+ 0x0003, 0x1C3B, 0x0000, 0x7E8A, 0x0003, 0x1C55, 0x0000, 0x7E8B, -+ 0x0000, 0x5EA4, 0x0000, 0x7D07, 0x0000, 0x5F23, 0x0003, 0x1CD1, -+ 0x0003, 0x01AF, 0x0003, 0x1B8A, 0x0003, 0x1B90, 0x0002, 0x004C, -+ 0x0000, 0x0640, 0x0004, 0x4514, 0x0000, 0x0641, 0x0005, 0x4515, -+ 0x0000, 0x0634, 0x0002, 0x225D, 0x0000, 0x0654, 0x0005, 0x451A, -+ 0x0000, 0x8EA2, 0x0004, 0x451C, 0x0000, 0x060D, 0x0000, 0x01FF, -+ 0x0000, 0x0614, 0x0002, 0x2163, 0x0003, 0x021E, 0x0000, 0x5E98, -+ 0x0000, 0x7D04, 0x0000, 0x01FF, 0x0000, 0x466E, 0x0000, 0x240F, -+ 0x000A, 0x0001, 0x0000, 0x014A, 0x0004, 0x010A, 0x0000, 0x4601, -+ 0x0000, 0x0591, 0x0004, 0x4531, 0x0000, 0x0590, 0x0004, 0x012C, -+ 0x0003, 0x0213, 0x0000, 0x4602, 0x0000, 0x0490, 0x0000, 0x6602, -+ 0x0002, 0x0017, 0x0000, 0xBAA1, 0x0004, 0x4535, 0x0000, 0x8EA2, -+ 0x0005, 0x012C, 0x0002, 0x0082, 0x0008, 0x4570, 0x0002, 0x001E, -+ 0x0000, 0x4723, 0x0000, 0x4AAD, 0x0000, 0x0151, 0x0007, 0x1E8F, -+ 0x0006, 0x4545, 0x0000, 0x4722, 0x0000, 0x4AAA, 0x0000, 0x0151, -+ // 5500 -+ 0x0007, 0x1E8F, 0x0009, 0x0100, 0x0000, 0x010C, 0x0007, 0x1E8F, -+ 0x0000, 0x01FF, 0x0000, 0x6B23, 0x0000, 0x0620, 0x0000, 0x01FF, -+ // 0062, 4 -+ 0x0200, 0x0600, 0x0C00, 0x1800, -+ // 006A, 2 -+ 0x2800, 0x3800, -+ // 0186, 2 -+ 0x2903, 0x8D20 -+}; -+ -+ -+static int adcm3800Patch(void) -+{ -+ int err; -+ int ipatch, idata; -+ for (ipatch = 0, idata = 0; patch3800addr[ipatch] != 0; ipatch++) -+ { -+ int addr = patch3800addr[ipatch]; -+ int len = patch3800len[ipatch]; -+ ddbg_print("write %d length to addr %x", len, addr); -+ err = adcm3800_write_regs (addr, &patch3800data[idata], len); -+ if (err < 0) -+ { -+ dbg_print("error: fail to upgrade patch code"); -+ return (err); -+ } -+ idata += len; -+ } -+ dbg_print("ok: write %d patch code", idata); -+ if(idata*2 != sizeof(patch3800data)) -+ { -+ dbg_print("error: patch len wrong! %d:%d", idata, sizeof(patch3800data)/2); -+ return -1; -+ } -+ return 0; -+} -+ -+ -+static int adcm3800_firmware_upgrade(void) -+{ -+ u8 valueb; -+ u16 valuew; -+ -+ //adcm3800_write(0x3040, 0x0100); -+ -+ int to = 200; -+ while(to>0) -+ { -+ adcm3800_read(0x0004, &valuew); -+ if(valuew==0x0000) -+ break; -+ mdelay(5); -+ to -= 1; -+ } -+ -+ dbg_print("start patch"); -+ adcm3800Patch(); -+ dbg_print("end patch"); -+ adcm3800_read_byte(0x084b, &valueb); -+ -+ return 0; -+} -+ -+static int adcm3800_init_regs(void) -+{ -+ u16 valuew; -+/* -+#Setting pixel ram and sensor registers -+#set block 14 -+w 0a04 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0005 0005 0805 0005 0007 0007 0007 0007 0107 0107 0187 0187 0187 0183 0183 0183 -+ -+#set block 15 -+w 0a80 0183 0183 0183 0183 0183 0183 0183 0183 -+w 0a90 0181 0001 0000 0000 0000 0000 0008 0008 -+w 0aa0 0008 0008 0079 0079 0079 0079 0079 0079 -+w 0ab0 0079 0079 0079 0079 0079 0079 0079 0079 -+ -+#set block 16 -+w 0b00 0079 0079 0079 0079 0079 0071 0035 0035 -+w 0b10 0035 0035 0037 0837 0037 0037 0137 0137 -+w 0b20 01b7 01b7 01b3 01b3 01b3 01b3 01b3 01b3 -+w 0b30 01b3 01b3 01b3 01b3 01b3 01b3 01b1 0071 -+ -+#set block 17 -+w 0b80 0071 0071 0071 0071 0071 0071 0061 0021 0020 0000 0000 0000 0000 0000 -+*/ -+ static u16 reg_0a04[] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0005, 0x0005, 0x0805, 0x0005, 0x0007, 0x0007, 0x0007, 0x0007, 0x0107, 0x0107, 0x0187, 0x0187, 0x0187, 0x0183, 0x0183, 0x0183}; -+ adcm3800_write_regs (0x0a04, reg_0a04, 30); -+ -+ static u16 reg_0a80[] = { -+ 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, -+ 0x0181, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, -+ 0x0008, 0x0008, 0x0079, 0x0079, 0x0079, 0x0079, 0x0079, 0x0079, -+ 0x0079, 0x0079, 0x0079, 0x0079, 0x0079, 0x0079, 0x0079, 0x0079}; -+ adcm3800_write_regs (0x0a80, reg_0a80, 32); -+ -+ static u16 reg_0b00[] = { -+ 0x0079, 0x0079, 0x0079, 0x0079, 0x0079, 0x0071, 0x0035, 0x0035, -+ 0x0035, 0x0035, 0x0037, 0x0837, 0x0037, 0x0037, 0x0137, 0x0137, -+ 0x01b7, 0x01b7, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, -+ 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b3, 0x01b1, 0x0071}; -+ adcm3800_write_regs (0x0b00, reg_0b00, 32); -+ -+ static u16 reg_0b80[] = { -+ 0x0071, 0x0071, 0x0071, 0x0071, 0x0071, 0x0071, 0x0061, 0x0021, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; -+ adcm3800_write_regs (0x0b80, reg_0b80, 14); -+ -+/* -+# Sensor settings -+w8 081e 00 -+w8 081f 00 -+w8 0820 00 -+w8 0821 00 -+w8 0822 00 -+w8 0823 00 -+w8 0824 00 -+w8 0825 00 -+w8 0828 02 -+w8 0845 b0 -+w8 0848 06 -+w8 0849 03 -+w8 084d 20 -+*/ -+ adcm3800_write_byte(0x081e, 0x00); -+ adcm3800_write_byte(0x081f, 0x00); -+ adcm3800_write_byte(0x0820, 0x00); -+ adcm3800_write_byte(0x0821, 0x00); -+ adcm3800_write_byte(0x0822, 0x00); -+ adcm3800_write_byte(0x0823, 0x00); -+ adcm3800_write_byte(0x0824, 0x00); -+ adcm3800_write_byte(0x0825, 0x00); -+ adcm3800_write_byte(0x0828, 0x02); -+ adcm3800_write_byte(0x0845, 0xb0); -+ adcm3800_write_byte(0x0848, 0x06); -+ adcm3800_write_byte(0x0849, 0x03); -+ adcm3800_write_byte(0x084D, 0x20); -+/* -+# Purple sky fix -+w8 84f F8 -+*/ -+ adcm3800_write_byte(0x084f, 0xF8); -+ -+/* -+#r 0112 1 # Return:8280 -+w 0112 c680 # PROC_CTRL_V -+#r 0132 1 # Return:0280 -+w 0132 4680 # PROC_CTRL_S -+w 014a 0015 # Auto Black Level Target -+#r 0008 1 # Return:0b84 -+// delete w 0008 0b04 # Image Size and Orientation, still: SXGA, Video: QQVGA -+*/ -+ // turn on AV -+ // sharpness -+ //adcm3800_write(0x0112, 0x4e80); // high sharpness -+ //adcm3800_write(0x0132, 0x4e80); -+ adcm3800_write(0x0112, 0x4a80); // medium sharpness -+ adcm3800_write(0x0132, 0x4a80); -+ //adcm3800_write(0x0112, 0x4680); // low sharpness -+ //adcm3800_write(0x0132, 0x4680); -+ //adcm3800_write(0x0112, 0x4280); // no sharpness -+ //adcm3800_write(0x0132, 0x4280); -+ adcm3800_write(0x014a, 0x0015); -+ -+/* -+# AWB setting -+w 0174 010d # AWB Default Red/Green Ratio -+w 017a 0185 # AWB Default Blue/Green Ratio -+w 017c 0108 # AWB Tolerance Acquire -+w 017e 0110 # AWB Tolerance Monitor -+*/ -+ // AWB -+ adcm3800_write(0x0174, 0x010d); -+ adcm3800_write(0x017a, 0x0185); -+ adcm3800_write(0x017c, 0x0108); -+ adcm3800_write(0x017e, 0x0110); -+ -+ // 0x00e0, 6 -+ static u16 reg_00e0[] = { -+ 0x003c, 0x00c8, 0x0200, 0x0130, 0x0180, 0x003c -+ }; -+ adcm3800_write_regs (0x00e0, reg_00e0, 6); -+ -+/* -+#set block 00, AWB setting -+w 0028 028f 0333 a3d7 001a 0021 c350 0bb8 01f4 0064 0001 0001 -+#set block 00 -+w 0062 0200 0600 0c00 1800 2800 3800 -+*/ -+#if 0 -+ static u16 reg_0028[] = { -+ 0x028f, 0x0333, 0xa3d7, 0x001a, 0x0021, 0xc350, 0x0bb8, 0x01f4, 0x0064, 0x0001, 0x0001}; -+ adcm3800_write_regs (0x0028, reg_0028, 11); -+ static u16 reg_0062[] = { -+ 0x0200, 0x0600, 0x0c00, 0x1800, 0x2800, 0x3800}; -+ adcm3800_write_regs (0x0062, reg_0062, 6); -+#endif -+ -+/* -+# 70% Vignetting Correction (7/27/04 - BB) -+w 10a6 248 1d0 248 1d0 260 160 0f6 0f6 0f2 -+ -+w 1800 0F1 102 111 120 12F 13F 14B 157 165 171 17E 18A 197 1A3 1AB 1B4 1BB 1C3 1C6 1CB 1CA 1C6 1C2 1BB 1B4 1AE 1A9 1A3 19E 198 193 18D -+w 1840 0E0 0EF 0FC 108 113 11F 12A 136 141 14D 158 161 16D 176 17E 186 18D 191 196 198 198 197 195 191 18A 183 17A 170 165 159 14C 13F -+w 1880 0F8 106 110 11A 124 12D 136 140 14B 154 15D 167 16F 178 180 188 18F 196 19C 1A0 1A4 1A6 1A8 1A7 1A6 1A4 1A0 19C 195 18E 186 17C -+*/ -+ static u16 reg_10a6[] = { -+ 0x0248, 0x01d0, 0x0248, 0x01d0, 0x0260, 0x0160, 0x00f6, 0x00f6, 0x00f2 -+ }; -+ adcm3800_write_regs (0x10a6, reg_10a6, 9); -+ // Red vignetting data -+ static u16 reg_1800[] = { -+ 0x00F1, 0x0102, 0x0111, 0x0120, 0x012F, 0x013F, 0x014B, 0x0157, -+ 0x0165, 0x0171, 0x017E, 0x018A, 0x0197, 0x01A3, 0x01AB, 0x01B4, -+ 0x01BB, 0x01C3, 0x01C6, 0x01CB, 0x01CA, 0x01C6, 0x01C2, 0x01BB, -+ 0x01B4, 0x01AE, 0x01A9, 0x01A3, 0x019E, 0x0198, 0x0193, 0x018D -+ }; -+ adcm3800_write_regs (0x1800, reg_1800, 32); -+ // Green vignetting data -+ static u16 reg_1840[] = { -+ 0x00E0, 0x00EF, 0x00FC, 0x0108, 0x0113, 0x011F, 0x012A, 0x0136, -+ 0x0141, 0x014D, 0x0158, 0x0161, 0x016D, 0x0176, 0x017E, 0x0186, -+ 0x018D, 0x0191, 0x0196, 0x0198, 0x0198, 0x0197, 0x0195, 0x0191, -+ 0x018A, 0x0183, 0x017A, 0x0170, 0x0165, 0x0159, 0x014C, 0x013F -+ }; -+ adcm3800_write_regs (0x1840, reg_1840, 32); -+ // Blue vignetting data -+ static u16 reg_1880[] = { -+ 0x00F8, 0x0106, 0x0110, 0x011A, 0x0124, 0x012D, 0x0136, 0x0140, -+ 0x014B, 0x0154, 0x015D, 0x0167, 0x016F, 0x0178, 0x0180, 0x0188, -+ 0x018F, 0x0196, 0x019C, 0x01A0, 0x01A4, 0x01A6, 0x01A8, 0x01A7, -+ 0x01A6, 0x01A4, 0x01A0, 0x019C, 0x0195, 0x018E, 0x0186, 0x017C -+ }; -+ adcm3800_write_regs (0x1880, reg_1880, 32); -+ -+ // BPA -+ // BPA 5 Line Threshold, default to 0x0020 -+ adcm3800_write(0x1094, 0x0010); -+ -+/* -+#G1/G2 Threshold -+w 101a 23f -+*/ -+ adcm3800_write(0x101a, 0x023f); -+/* -+#NACC Settings - Dark Table -+w 282 2B3 FE0B 41 FF69 2B1 FEE4 FF6D FC69 528 -+*/ -+ static u16 reg_0282[] = { -+ 0x2B3, 0xFE0B, 0x41, 0xFF69, 0x2B1, 0xFEE4, 0xFF6D, 0xFC69, 0x528 -+ }; -+ adcm3800_write_regs (0x0282, reg_0282, 9); -+/* -+#NACC Settings - NACC Table -+w 250 96 0 0 100 -+*/ -+ static u16 reg_0250[] = { -+ 0x0096, 0x0000, 0x0000, 0x0100, 0x0ea6, 0x0060, 0x09c4, 0x0080, -+ 0x04e2, 0x00a0, 0x0271, 0x00c0, 0x0000, 0x0100 -+ }; -+ adcm3800_write_regs (0x0250, reg_0250, 14); -+/* -+#PI control -+w 2e A4 EC -+*/ -+ adcm3800_write(0x002e, 0x00A4); -+ adcm3800_write(0x0030, 0x00EC); -+ -+/* -+#Sunlight oscillation -+#Set bit 4 of 0x142 -+# auto function control, select Xenon flash mode and enabled auto exposure deliberate overexposure -+w 142 1011 -+ -+#Turn NACC on -+w 140 1B -+*/ -+ //adcm3800_write(0x0142, 0x1011); -+ adcm3800_write(EREG_AF_CTRL2, 0x1011); -+ //adcm3800_write(0x0140, 0x001B); -+ adcm3800_write(EREG_AF_CTRL1, 0x001b); // enable AE AWB NACC ABL -+ -+ dbg_print("end"); -+ return 0; -+} -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/adcm3800_hw.h linux-2.6.16.5-exz/drivers/media/video/adcm3800_hw.h ---- linux-2.6.16.5/drivers/media/video/adcm3800_hw.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/adcm3800_hw.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,534 @@ -+/*================================================================================ -+ -+ Header Name: adcm3800_hw.h -+ -+General Description: Camera module adcm3800 interface header file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 12/15/2003 LIBdd35749 Created -+wangfei(w20239) 02/05/2004 LIBdd74309 Set frame rate in video mode -+wangfei(w20239) 02/26/2004 LIBdd81055 New chip id support -+wangfei(w20239) 03/08/2004 LIBdd84578 Photo effects setting -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+ -+#ifndef _PXA_ADCM3800_HW_H__ -+#define _PXA_ADCM3800_HW_H__ -+ -+#include "camera.h" -+ -+/*********************************************************************** -+ * -+ * Constants -+ * -+ ***********************************************************************/ -+ -+// Revision constants -+#define PIPE_REV 0x68 -+//#define PIPE_REV_NEW 0x68 -+#define SENSOR_REV 0x68 -+ -+// Others -+#define adcm3800__TIMEOUT 400 // times to timeout. -+ -+// Non JEPG Output Format -+#define O_FORMAT_888RGB 0 //0b0000 // 888 RGB (1 pixel in 3 bytes ) -+#define O_FORMAT_666_A_RGB 1 //0b0001 // 666 A RGB (tight pack, 4 pixels in 9 bytes) -+#define O_FORMAT_666_B_RGB 2 //0b0010 // 666 B RGB (loose pack, 1 pixel in 3 bytes,left or right justified) -+#define O_FORMAT_565_RGB 3 //0b0011 // 565 RGB (1 pixel in 2 bytes) -+#define O_FORMAT_444_A_RGB 4 //0b0100 // 444 A RGB (tight pack, 2 pixels per 3 bytes, RG BR GB) -+#define O_FORMAT_444_B_RGB 5 //0b0101 // 444 B RGB (loose pack, 1 pixel per 2 bytes,RG B0 or 0R GB) -+#define O_FORMAT_444_C_RGV 6 //0b0110 // 444 C RGB (sparse pack, 1 pixel per three bytes,R0 G0 B0 or 0R 0G 0B) -+#define O_FORMAT_332_RGB 7 //0b0111 // 332 RGB (1 pixel in 1 byte) -+#define O_FORMAT_422_A_YCbYCr 8 //0b1000 // 4:2:2 A YCbYCr (Y1 Cb12 Y2 CRL2 order) -+#define O_FORMAT_422_B_YCbYCr 9 //0b1001 // 4:2:2 B YCbYCr (Cb12 Y1 CRL2 Y2 order) -+#define O_FORMAT_422_C_YCbYCr 10 //0b1010 // 4:2:2 C YCbYCr (Y1 CRL2 Y2 Cb12 order) -+#define O_FORMAT_422_D_YCbYCr 11 //0b1011 // 4:2:2 D YCbYCr (CRL2 Y1 Cb12 Y2 order) -+#define O_FORMAT_444_YCbYCr 12 //0b1100 // 4:4:4 YCbCr (1 pixels per 3 bytes) -+#define O_FORMAT_400_B_YCbYCr 13 //0b1101 // 4:0:0 YCbCr (Greyscale, 1 pixel per 1 byte) -+#define O_FORMAT_RAWBPA 14 //0b1110 // RAWBPA (with AWB and BPA) -+#define O_FORMAT_RAW 15 //0b1111 // RAW (without AWB and BPA) -+ -+#define O_FORMAT_NONE 65535 // -+ -+/************************************************************************************* -+ * -+ * Simple Control Registers Address -+ * -+ *************************************************************************************/ -+// name addr description default page -+#define SREG_ID 0x0000 //Chip ID 0x0060 139 -+#define SREG_CONTROL 0x0002 //Camera control 0x0001 140 -+#define SREG_STATUS 0x0004 //Camera status 0x0004 142 -+#define SREG_CLK_FREQ 0x0006 //Input clock frequency 0x32c8 144 -+#define SREG_SIZE 0x0008 //Image size and orientation 0x0605 145 -+#define SREG_OUTPUT_FORMAT 0x000a //Output format 0x0909 147 -+#define SREG_EXPOSURE 0x000c //Exposure 0x03e8 149 -+#define SREG_EXP_ADJ 0x000e //Exposure adjustment 0x0000 150 -+#define SREG_ILLUM 0x0010 //Illumination 0x0000 151 -+#define SREG_FRAME_RATE 0x0012 //Requested frame rate 0x0096 152 -+#define SREG_A_FRAME_RATE 0x0016 //Actual frame rate 0x0096 154 -+#define SREG_SENSOR_WID_V 0x0018 //Sensor window width, video mode 0x0000 155 -+#define SREG_SENSOR_HGT_V 0x001a //Sensor window height, video mode 0x0000 156 -+#define SREG_OUTPUT_WID_V 0x001c //Output window width, video mode 0x0000 157 -+#define SREG_OUTPUT_HGT_V 0x001e //Output window height, video mode 0x0000 158 -+#define SREG_SENSOR_WID_S 0x0020 //Sensor window width, still mode 0x0000 159 -+#define SREG_SENSOR_HGT_S 0x0022 //Sensor window height, still mode 0x0000 160 -+#define SREG_OUTPUT_WID_S 0x0024 //Output window width, still mode 0x0000 161 -+#define SREG_OUTPUT_HGT_S 0x0026 //Output window height, still mode 0x0000 162 -+ -+/************************************************************************************* -+ * -+ * Expert Hardware Registers -+ * -+ *************************************************************************************/ -+// name addr description default page -+#define EREG_I_CLK_DIV 0x3000 //Initial clock divider 0x0001 166 -+#define EREG_CTL_CLK_DIV 0x3002 //Clock dividers for control -+ //and serial interfaces 0x4000 167 -+#define EREG_SEN_CLK_DIV 0x3004 //Sensor clock dividers 0x0000 168 -+#define EREG_IP_CLK_DIV 0x3006 //Clock dividers for image pipeline 0x0000 169 -+#define EREG_TST_MODE 0x3008 //Latched test mode 0x0000 170 -+#define EREG_SER_ADDR 0x300a //Serial interface device address 0x0053 171 -+#define EREG_SER_PARM 0x300c //Serial Interface parameters 0x0000 172 -+#define EREG_OUT_CTRL 0x300e //Output control 0x0000 173 -+#define EREG_PLL_CTRL 0x3010 //PLL control 0x0014 470 -+#define EREG_PLL_DIV_L 0x3012 //PLL divisors, large values 0x500C 471 -+#define EREG_PLL_DIV_S 0x3014 //PLL divisors, small values 0x500C 472 -+ -+/************************************************************************************* -+ * -+ * Expert Control Registers -+ * -+ *************************************************************************************/ -+// name addr description default page -+#define EREG_SZR_IN_WID_V 0x0100 //Sizer input width, video mode 0x0280 184 -+#define EREG_SZR_IN_HGT_V 0x0102 //Sizer input height, video mode 0x01e0 185 -+#define EREG_SZR_OUT_WID_V 0x0104 //Sizer output width, video mode 0x0140 186 -+#define EREG_SZR_OUT_HGT_V 0x0106 //Sizer output height, video mode 0x00f0 187 -+#define EREG_CPP_V 0x0108 //Clocks per pixel, video mode 0x0002 188 -+#define EREG_HBLANK_V 0x010a //Horizontal blanking period, video mode 0x0000 189 -+#define EREG_VBLANK_V 0x010c //Vertical blanking period, video mode 0x0000 190 -+#define EREG_MIN_MAX_F_V 0x010e //Frame convergence rates, video mode 0x0000 191 -+#define EREG_OUTPUT_CTRL_V 0x0110 //Output control, video mode 0x9019 192 -+#define EREG_PROC_CTRL_V 0x0112 //Processing control, video mode 0x0280 194 -+#define EREG_RPT_V 0x0114 //Row processing time, video mode 0x0546 196 -+#define EREG_HYSNC_PER_V 0x0116 //HSYNC period, video mode 0x0a8b 197 -+#define EREG_CLK_DIV_V 0x0118 //Clock divisors, video mode 0x0000 198 -+#define EREG_PARALLEL_CTRL_V 0x011a //Parallel output control, video mode 0x0003 199 -+#define EREG_SEN_CTRL_V 0x011c //Sensor control, video mode 0x0000 200 -+ -+#define EREG_SZR_IN_WID_S 0x0120 //Sizer input width, still mode 0x0280 202 -+#define EREG_SZR_IN_HGT_S 0x0122 //Sizer input height, still mode 0x01e0 203 -+#define EREG_SZR_OUT_WID_S 0x0124 //Sizer output width, still mode 0x0280 204 -+#define EREG_SZR_OUT_HGT_S 0x0126 //Sizer output height, still mode 0x01e0 205 -+#define EREG_CPP_S 0x0128 //Clocks per pixel, still mode 0x0002 206 -+#define EREG_HBLANK_S 0x012a //Horizontal blanking period, still mode 0x0000 207 -+#define EREG_VBLANK_S 0x012c //Vertical blanking period, still mode 0x0000 208 -+#define EREG_MIN_MAX_F_S 0x012e //Frame convergence rates, still mode 0x0002 209 -+#define EREG_OUTPUT_CTRL_S 0x0130 //Output control, still mode 0x8019 210 -+#define EREG_PROC_CTRL_S 0x0132 //Processing control, still mode 0x0280 212 -+#define EREG_RPT_S 0x0134 //Row processing time, still mode 0x0546 214 -+#define EREG_HYSNC_PER_S 0x0136 //HSYNC period, still mode 0x0545 215 -+#define EREG_CLK_DIV_S 0x0138 //Clock divisors, still mode 0x0000 216 -+#define EREG_PARALLEL_CTRL_S 0x013a //Parallel output control, still mode 0x0000 217 -+#define EREG_SEN_CTRL_S 0x013c //Sensor control, still mode 0x0000 218 -+ -+#define EREG_AF_CTRL1 0x0140 //Auto functions control 1 0x0013 220 -+#define EREG_AF_CTRL2 0x0142 //Auto functions control 2 0x0001 221 -+#define EREG_AF_STATUS 0x0144 //Auto functions status 0x0000 222 -+#define EREG_SOF_CODES 0x0146 //Start of frame codes 0xfeff 223 -+#define EREG_EOF_CODES 0x0148 //End of frame codes 0x0100 224 -+#define EREG_ABL_TARGET 0x014a //Auto black level target 0x0005 225 -+#define EREG_ABL_MAX_BIN 0x014c //Auto black level maximum bin 0x0003 226 -+#define EREG_ABL_MAX_BLACK 0x014e //Auto black level maximum black 0x0010 227 -+#define EREG_AE_GAIN_MIN 0x0150 //Auto exposure gain minimum 0x01c0 228 -+#define EREG_AE_GAIN_MIN_P 0x0152 //Auto exposure gain minimum, preferred 0x0200 229 -+#define EREG_AE_GAIN_MAX 0x0154 //Auto exposure gain maximum 0x0500 230 -+#define EREG_AE_GAIN_DFLT 0x0156 //Auto exposure gain default 0x0200 231 -+#define EREG_AE_ETIME_MIN 0x0158 //Auto exposure time minimum 0x0005 232 -+#define EREG_AE_ETIME_MAX 0x015a //Auto exposure time maximum 0x4e20 233 -+#define EREG_AE_ETIME_DFLT 0x015c //Auto exposure time default 0x03e8 234 -+#define EREG_AE_TARGET 0x015e //Auto exposure target 0x0040 235 -+#define EREG_AE_TOL_ACQ 0x0160 //Auto exposure tolerance acquire 0x0118 236 -+#define EREG_AE_TOL_MON 0x0162 //Auto exposure tolerance monitor 0x0118 237 -+#define EREG_AE_MARGIN 0x0164 //Auto exposure margin 0x0120 238 -+#define EREG_AE_DOE_FACTOR 0x0166 //AE deliberate overexposure factor 0x014e 239 -+#define EREG_AE_DOE_MARGIN 0x0168 //AE deliberate overexposure margin 0x0140 240 -+ -+#define EREG_AWB_RED_MIN 0x0170 //AWB minimum red/green ratio 0x00c0 242 -+#define EREG_AWB_RED_MAX 0x0172 //AWB maximum red/green ratio 0x01a6 243 -+#define EREG_AWB_RED_DFLT 0x0174 //AWB default red/green ratio 0x0134 244 -+#define EREG_AWB_BLUE_MIN 0x0176 //AWB minimum blue/green ratio 0x00c0 245 -+#define EREG_AWB_BLUE_MAX 0x0178 //AWB maximum blue/green ratio 0x02a4 246 -+#define EREG_AWB_BLUE_DFLT 0x017a //AWB default blue/green ratio 0x01e4 247 -+#define EREG_AWB_TOL_ACQ 0x017c //Auto white balance tolerance acquire 0x0110 248 -+#define EREG_AWB_TOL_MON 0x017e //Auto white balance tolerance monitor 0x0120 249 -+#define EREG_FIRMWARE_REV 0x0180 //Current firmware revision 0x0152 250 -+#define EREG_FLICK_CFG_1 0x0182 //Flicker configuration 1 0x2aeb 251 -+#define EREG_FLICK_CFG_2 0x0184 //Flicker configuration 2 0x0005 252 -+ -+#define EREG_MAX_SCLK 0x018a //Maximum sensor clock 0x1964 254 -+ -+#define EREG_CSC_00_V 0x0190 //Color conversion coefficient 00, video 0x0026 256 -+#define EREG_CSC_01_V 0x0192 //Color conversion coefficient 01, video 0x004b 256 -+#define EREG_CSC_02_V 0x0194 //Color conversion coefficient 02, video 0x000f 256 -+#define EREG_CSC_10_V 0x0196 //Color conversion coefficient 10, video 0x01ed 256 -+#define EREG_CSC_11_V 0x0198 //Color conversion coefficient 11, video 0x01db 256 -+#define EREG_CSC_12_V 0x019a //Color conversion coefficient 12, video 0x0038 256 -+#define EREG_CSC_20_V 0x019c //Color conversion coefficient 20, video 0x004f 256 -+#define EREG_CSC_21_V 0x019e //Color conversion coefficient 21, video 0x01be 256 -+#define EREG_CSC_22_V 0x01a0 //Color conversion coefficient 22, video 0x01f3 256 -+ -+#define EREG_CSC_OS0_V 0x01a2 //Color space conversion offset 0, video 0x0000 257 -+#define EREG_CSC_OS1_V 0x01a4 //Color space conversion offset 1, video 0x0080 257 -+#define EREG_CSC_OS2_V 0x01a6 //Color space conversion offset 2, video 0x0080 257 -+ -+#define EREG_CSC_00_S 0x01a8 //Color conversion coefficient 00, still 0x0026 258 -+#define EREG_CSC_01_S 0x01aa //Color conversion coefficient 01, still 0x004b 258 -+#define EREG_CSC_02_S 0x01ac //Color conversion coefficient 02, still 0x000f 258 -+#define EREG_CSC_10_S 0x01ae //Color conversion coefficient 10, still 0x01ed 258 -+#define EREG_CSC_11_S 0x01b0 //Color conversion coefficient 11, still 0x01db 258 -+#define EREG_CSC_12_S 0x01b2 //Color conversion coefficient 12, still 0x0038 258 -+#define EREG_CSC_20_S 0x01b4 //Color conversion coefficient 20, still 0x004f 258 -+#define EREG_CSC_21_S 0x01b6 //Color conversion coefficient 21, still 0x01be 258 -+#define EREG_CSC_22_S 0x01b8 //Color conversion coefficient 22, still 0x01f3 258 -+ -+#define EREG_CSC_OS0_S 0x01ba //Color space conversion offset 0, still 0x0000 259 -+#define EREG_CSC_OS1_S 0x01bc //Color space conversion offset 1, still 0x0080 259 -+#define EREG_CSC_OS2_S 0x01be //Color space conversion offset 2, still 0x0080 259 -+ -+ -+#define EREG_TM_COEF_00_V 0x01c0 //Tonemap coefficient 00, video 0x0000 261 -+#define EREG_TM_COEF_01_V 0x01c2 //Tonemap coefficient 01, video 0x0017 261 -+#define EREG_TM_COEF_02_V 0x01c4 //Tonemap coefficient 02, video 0x0032 261 -+#define EREG_TM_COEF_03_V 0x01c6 //Tonemap coefficient 03, video 0x0046 261 -+#define EREG_TM_COEF_04_V 0x01c8 //Tonemap coefficient 04, video 0x0056 261 -+#define EREG_TM_COEF_05_V 0x01ca //Tonemap coefficient 05, video 0x0064 261 -+#define EREG_TM_COEF_06_V 0x01cc //Tonemap coefficient 06, video 0x0071 261 -+#define EREG_TM_COEF_07_V 0x01ce //Tonemap coefficient 07, video 0x007c 261 -+#define EREG_TM_COEF_08_V 0x01d0 //Tonemap coefficient 08, video 0x0086 261 -+#define EREG_TM_COEF_09_V 0x01d2 //Tonemap coefficient 09, video 0x0099 261 -+#define EREG_TM_COEF_10_V 0x01d4 //Tonemap coefficient 10, video 0x00a9 261 -+#define EREG_TM_COEF_11_V 0x01d6 //Tonemap coefficient 11, video 0x00b8 261 -+#define EREG_TM_COEF_12_V 0x01d8 //Tonemap coefficient 12, video 0x00c6 261 -+#define EREG_TM_COEF_13_V 0x01da //Tonemap coefficient 13, video 0x00df 261 -+#define EREG_TM_COEF_14_V 0x01dc //Tonemap coefficient 14, video 0x00f5 261 -+#define EREG_TM_COEF_15_V 0x01de //Tonemap coefficient 15, video 0x0109 261 -+#define EREG_TM_COEF_16_V 0x01e0 //Tonemap coefficient 16, video 0x011b 261 -+#define EREG_TM_COEF_17_V 0x01e2 //Tonemap coefficient 17, video 0x013d 261 -+#define EREG_TM_COEF_18_V 0x01e4 //Tonemap coefficient 18, video 0x015a 261 -+#define EREG_TM_COEF_19_V 0x01e6 //Tonemap coefficient 19, video 0x0175 261 -+#define EREG_TM_COEF_20_V 0x01e8 //Tonemap coefficient 20, video 0x018d 261 -+#define EREG_TM_COEF_21_V 0x01ea //Tonemap coefficient 21, video 0x01ba 261 -+#define EREG_TM_COEF_22_V 0x01ec //Tonemap coefficient 22, video 0x01e1 261 -+#define EREG_TM_COEF_23_V 0x01ee //Tonemap coefficient 23, video 0x0205 261 -+#define EREG_TM_COEF_24_V 0x01f0 //Tonemap coefficient 24, video 0x0225 261 -+#define EREG_TM_COEF_25_V 0x01f2 //Tonemap coefficient 25, video 0x0261 261 -+#define EREG_TM_COEF_26_V 0x01f4 //Tonemap coefficient 26, video 0x0295 261 -+#define EREG_TM_COEF_27_V 0x01f6 //Tonemap coefficient 27, video 0x02c5 261 -+#define EREG_TM_COEF_28_V 0x01f8 //Tonemap coefficient 28, video 0x02f1 261 -+#define EREG_TM_COEF_29_V 0x01fa //Tonemap coefficient 29, video 0x033f 261 -+#define EREG_TM_COEF_30_V 0x01fc //Tonemap coefficient 30, video 0x0385 261 -+#define EREG_TM_COEF_31_V 0x01fe //Tonemap coefficient 31, video 0x03c5 261 -+#define EREG_TM_COEF_32_V 0x0200 //Tonemap coefficient 32, video 0x0400 261 -+ -+#define EREG_TM_COEF_00_S 0x0202 //Tonemap coefficient 00, still 0x0000 262 -+#define EREG_TM_COEF_01_S 0x0204 //Tonemap coefficient 01, still 0x0017 262 -+#define EREG_TM_COEF_02_S 0x0206 //Tonemap coefficient 02, still 0x0032 262 -+#define EREG_TM_COEF_03_S 0x0208 //Tonemap coefficient 03, still 0x0046 262 -+#define EREG_TM_COEF_04_S 0x020a //Tonemap coefficient 04, still 0x0056 262 -+#define EREG_TM_COEF_05_S 0x020c //Tonemap coefficient 05, still 0x0064 262 -+#define EREG_TM_COEF_06_S 0x020e //Tonemap coefficient 06, still 0x0071 262 -+#define EREG_TM_COEF_07_S 0x0210 //Tonemap coefficient 07, still 0x007c 262 -+#define EREG_TM_COEF_08_S 0x0212 //Tonemap coefficient 08, still 0x0086 262 -+#define EREG_TM_COEF_09_S 0x0214 //Tonemap coefficient 09, still 0x0099 262 -+#define EREG_TM_COEF_10_S 0x0216 //Tonemap coefficient 10, still 0x00a9 262 -+#define EREG_TM_COEF_11_S 0x0218 //Tonemap coefficient 11, still 0x00b8 262 -+#define EREG_TM_COEF_12_S 0x021a //Tonemap coefficient 12, still 0x00c6 262 -+#define EREG_TM_COEF_13_S 0x021c //Tonemap coefficient 13, still 0x00df 262 -+#define EREG_TM_COEF_14_S 0x021e //Tonemap coefficient 14, still 0x00f5 262 -+#define EREG_TM_COEF_15_S 0x0220 //Tonemap coefficient 15, still 0x0109 262 -+#define EREG_TM_COEF_16_S 0x0222 //Tonemap coefficient 16, still 0x011b 262 -+#define EREG_TM_COEF_17_S 0x0224 //Tonemap coefficient 17, still 0x013d 262 -+#define EREG_TM_COEF_18_S 0x0226 //Tonemap coefficient 18, still 0x015a 262 -+#define EREG_TM_COEF_19_S 0x0228 //Tonemap coefficient 19, still 0x0175 262 -+#define EREG_TM_COEF_20_S 0x022a //Tonemap coefficient 20, still 0x018d 262 -+#define EREG_TM_COEF_21_S 0x022c //Tonemap coefficient 21, still 0x01ba 262 -+#define EREG_TM_COEF_22_S 0x022e //Tonemap coefficient 22, still 0x01e1 262 -+#define EREG_TM_COEF_23_S 0x0230 //Tonemap coefficient 23, still 0x0205 262 -+#define EREG_TM_COEF_24_S 0x0232 //Tonemap coefficient 24, still 0x0225 262 -+#define EREG_TM_COEF_25_S 0x0234 //Tonemap coefficient 25, still 0x0261 262 -+#define EREG_TM_COEF_26_S 0x0236 //Tonemap coefficient 26, still 0x0295 262 -+#define EREG_TM_COEF_27_S 0x0238 //Tonemap coefficient 27, still 0x02c5 262 -+#define EREG_TM_COEF_28_S 0x023a //Tonemap coefficient 28, still 0x02f1 262 -+#define EREG_TM_COEF_29_S 0x023c //Tonemap coefficient 29, still 0x033f 262 -+#define EREG_TM_COEF_30_S 0x023e //Tonemap coefficient 30, still 0x0385 262 -+#define EREG_TM_COEF_31_S 0x0240 //Tonemap coefficient 31, still 0x03c5 262 -+#define EREG_TM_COEF_32_S 0x0242 //Tonemap coefficient 32, still 0x0400 262 -+ -+#define EREG_NACC_EGP_1 0x0250 //NACC EGP 1 0x05dc 265 -+#define EREG_NACC_SAT_1 0x0252 //NACC saturation 1 0x0000 265 -+#define EREG_NACC_EGP_2 0x0254 //NACC EGP 2 0x0465 265 -+#define EREG_NACC_SAT_2 0x0256 //NACC saturation 2 0x0040 265 -+#define EREG_NACC_EGP_3 0x0258 //NACC EGP 3 0x02ee 265 -+#define EREG_NACC_SAT_3 0x025a //NACC saturation 3 0x0080 265 -+#define EREG_NACC_EGP_4 0x025c //NACC EGP 4 0x0177 265 -+#define EREG_NACC_SAT_4 0x025e //NACC saturation 4 0x00c0 265 -+#define EREG_NACC_EGP_5 0x0260 //NACC EGP 5 0x0000 265 -+#define EREG_NACC_SAT_5 0x0262 //NACC saturation 5 0x0100 265 -+#define EREG_NACC_EGP_6 0x0264 //NACC EGP 6 0x0000 265 -+#define EREG_NACC_SAT_6 0x0266 //NACC saturation 6 0x0000 265 -+#define EREG_NACC_EGP_7 0x0268 //NACC EGP 7 0x0000 265 -+#define EREG_NACC_SAT_7 0x026a //NACC saturation 7 0x0000 265 -+#define EREG_NACC_EGP_8 0x026c //NACC EGP 8 0x0000 265 -+#define EREG_NACC_SAT_8 0x026e //NACC saturation 8 0x0000 265 -+#define EREG_NACC_BC_00 0x0270 //NACC NACC bright coefficients 00 0x0235 266 -+#define EREG_NACC_BC_01 0x0272 //NACC NACC bright coefficients 01 0xff46 266 -+#define EREG_NACC_BC_02 0x0274 //NACC bright coefficients 02 0xff85 266 -+#define EREG_NACC_BC_10 0x0276 //NACC bright coefficients 10 0xff64 266 -+#define EREG_NACC_BC_11 0x0278 //NACC bright coefficients 11 0x01fc 266 -+#define EREG_NACC_BC_12 0x027a //NACC bright coefficients 12 0xff9f 266 -+#define EREG_NACC_BC_20 0x027c //NACC bright coefficients 20 0x0008 266 -+#define EREG_NACC_BC_21 0x027e //NACC bright coefficients 21 0xfe8d 266 -+#define EREG_NACC_BC_22 0x0280 //NACC bright coefficients 22 0x026b 266 -+#define EREG_NACC_DC_00 0x0282 //NACC dark coefficients 00 0x0048 266 -+#define EREG_NACC_DC_01 0x0284 //NACC dark coefficients 01 0x010b 266 -+#define EREG_NACC_DC_02 0x0286 //NACC dark coefficients 02 0xffaa 266 -+#define EREG_NACC_DC_10 0x0288 //NACC dark coefficients 10 0x0048 266 -+#define EREG_NACC_DC_11 0x028a //NACC dark coefficients 11 0x010b 266 -+#define EREG_NACC_DC_12 0x028c //NACC dark coefficients 12 0xffaa 266 -+#define EREG_NACC_DC_20 0x028e //NACC dark coefficients 20 0x0048 266 -+#define EREG_NACC_DC_21 0x0290 //NACC dark coefficients 21 0x010b 266 -+#define EREG_NACC_DC_22 0x0292 //NACC dark coefficients 22 0xffaa 266 -+ -+/************************************************************************************* -+ * -+ * Expert Sensor Registers -+ * -+ *************************************************************************************/ -+// name addr description default page -+#define EREG_IDENT 0x0800 //Image sensor identification 0x60 272 -+#define EREG_IS_STATUS 0x0801 //Image sensor status 0x00 273 -+#define EREG_ICTRL 0x0805 //Interface control 0x00 275 -+ -+#define EREG_ADC_CTRL 0x0809 //ADC control 0x01 277 -+#define EREG_FWROW 0x080a //Window first row address 0x01 278 -+#define EREG_FWCOL 0x080b //Window first column address 0x01 279 -+#define EREG_LWROW 0x080c //Window last row address 0x7a 280 -+#define EREG_LWCOL 0x080d //Window last column address 0xa2 281 -+#define EREG_CLK_PIXEL 0x080e //Clocks per pixel 0x02 282 -+#define EREG_EREC_PGA 0x080f //Even row, even column(green 1)PGA gain 0x00 283 -+#define EREG_EROC_PGA 0x0810 //Even row, odd column (red) PGA gain 0x00 284 -+#define EREG_OREC_PGA 0x0811 //Odd row, even column (blue) PGA gain 0x00 285 -+#define EREG_OROC_PGA 0x0812 //Odd row, odd column (green 2) PGA gain 0x00 286 -+#define EREG_ROWEXP_L 0x0813 //Row exposure low 0x54 287 -+#define EREG_ROWEXP_H 0x0814 //Row exposure high 0x00 288 -+#define EREG_SROWEXP 0x0815 //Sub row exposure 0x31 289 -+#define EREG_ERROR 0x0816 //Error control 0x00 290 -+ -+#define EREG_HBLANK 0x0819 //Horizontal blank 0x00 292 -+#define EREG_VBLANK 0x081a //Vertical blank 0x00 293 -+#define EREG_CONFIG_1 0x081b //Image sensor configuration 1 0x0e 294 -+#define EREG_CONTROL_1 0x081c //Image sensor control 1 0x24 295 -+ -+#define EREG_CONFIG_2 0x0827 //Image sensor configuration 2 0x00 298 -+#define EREG_GRR_CTRL 0x0828 //Ground reset reference control 0x00 299 -+ -+#define EREG_BIAS_TRM 0x0837 //Bias trim 0x00 301 -+#define EREG_SMP_GR_E2 0x08d7 //Sample ground reference edge 2 0x00 303 -+#define EREG_SMP_GR_E1 0x08d8 //Sample ground reference edge 1 0x10 304 -+#define EREG_SMP_GR_E0 0x08d9 //Sample ground reference edge 0 0x0a 305 -+ -+#define EREG_EXP_GR_E1 0x08dc //Exposure, ground reference edge 1 0x10 307 -+#define EREG_EXP_GR_E0 0x08dd //Exposure, ground reference edge 0 0x06 308 -+#define EREG_GR_POL 0x08df //Ground reference polarity 0xd3 310 -+ -+#define EREG_SMP_RST_E2 0x08eb //Sample, reset edge 2 0x04 312 -+#define EREG_SMP_RST_E1 0x08ec //Sample, reset edge 1 0x10 313 -+#define EREG_SMP_RST_E0 0x08ed //Sample, reset edge 0 0x07 314 -+ -+#define EREG_EXP_RST_E1 0x08f0 //Exposure, reset edge 1 0x10 316 -+#define EREG_EXP_RST_E0 0x08f1 //Exposure, reset edge 1 0x03 317 -+#define EREG_RESET_POL 0x08f3 //Reset polarity enable 0xd3 319 -+ -+#define EREG_SMP_PRST_E2 0x08f5 //Sample, preset edge 2 0x00 321 -+#define EREG_SMP_PRST_E1 0x08f6 //Sample, preset edge 1 0x02 322 -+#define EREG_SMP_PRST_E0 0x08f7 //Sample, preset edge 0 0x0a 323 -+ -+#define EREG_EXP_PRST_E1 0x08fa //Exposure, preset edge 1 0x02 325 -+#define EREG_EXP_PRST_E0 0x08fb //Exposure, preset edge 1 0x06 326 -+#define EREG_PRESET_POL 0x08fd //Preset polarity enable 0xd3 328 -+ -+/************************************************************************************* -+ * -+ * Expert Image Pipeline Registers -+ * -+ *************************************************************************************/ -+// name addr description default page -+ -+#define EREG_CMD_1 0x1002 //Main command 1 0x0000 335 -+#define EREG_CMD_2 0x1004 //Main command 2 (write 1¡¯s only) 0x0002 336 -+#define EREG_OUTPUT_CTRL 0x1008 //Output control, working 0x9019 338 -+#define EREG_PARALLEL_CTRL 0x100a //Parallel output control working copy 0x0000 340 -+#define EREG_SOF_CODE_W 0x100c //Start of frame code working copy 0x00ff 341 -+#define EREG_PEOF_CODES 0x100e //End of frame codes working copy 0x0100 342 -+#define EREG_CCIR_TIMING 0x1010 //CCIR interface timing 0x0000 343 -+#define EREG_R_Y_MAX_MIN 0x1012 //Luminance, Y (or red) maximum/minimum 0xff00 344 -+#define EREG_G_CB_MAX_MIN 0x1014 //Chrominance,Cb(or green)maximum/minimum 0xff00 345 -+#define EREG_B_CR_MAX_MIN 0x1016 //Chrominance,Cr(or blue)maximum/minimum 0xff00 346 -+#define EREG_PROCESS_CTRL 0x1018 //Processing control working copy 0x0280 347 -+#define EREG_BPA_SF_GTHRESH 0x101a //BPA scale factor,green filter threshold 0x0220 349 -+#define EREG_BPA_OUTL_PED 0x101c //BPA outlier, pedestal 0x4008 350 -+#define EREG_BPA_BADPIX_CNT 0x101e //BPA bad pixel count (read only) 0x0000 351 -+#define EREG_SZR_IN_W 0x1020 //Sizer input width 0x0280 352 -+#define EREG_SZR_IN_H 0x1022 //Sizer input height 0x01e0 353 -+#define EREG_SZR_OUT_W 0x1024 //Sizer output width 0x0140 354 -+#define EREG_SZR_OUT_H 0x1026 //Sizer output height 0x00f0 355 -+ -+ -+#define EREG_CC_COEF_00 0x1028 //Color correction coefficient 00 0x02f9 358 -+#define EREG_CC_COEF_01 0x102a //Color correction coefficient 01 0x0f03 358 -+#define EREG_CC_COEF_02 0x102c //Color correction coefficient 02 0x0f02 358 -+#define EREG_CC_COEF_10 0x102e //Color correction coefficient 10 0x0f4f 358 -+#define EREG_CC_COEF_11 0x1030 //Color correction coefficient 11 0x025c 358 -+#define EREG_CC_COEF_12 0x1032 //Color correction coefficient 12 0x0f54 358 -+#define EREG_CC_COEF_20 0x1034 //Color correction coefficient 20 0x0fe0 358 -+#define EREG_CC_COEF_21 0x1036 //Color correction coefficient 21 0x0e4a 358 -+#define EREG_CC_COEF_22 0x1038 //Color correction coefficient 22 0x02d5 358 -+ -+#define EREG_CC_PRE_OS_0 0x103a //Color correction pre-offset 0 0x01f8 360 -+#define EREG_CC_PRE_OS_1 0x103c //Color correction pre-offset 1 0x01f8 360 -+#define EREG_CC_PRE_OS_2 0x103e //Color correction pre-offset 2 0x01f8 360 -+#define EREG_CC_POST_OS_0 0x1040 //Color correction post-offset 0 0x0000 360 -+#define EREG_CC_POST_OS_1 0x1042 //Color correction post-offset 1 0x0000 360 -+#define EREG_CC_POST_OS_2 0x1044 //Color correction post-offset 2 0x0000 360 -+ -+#define EREG_CSC_COEF_00 0x1046 //Color space conversion coefficient 00 0x0026 363 -+#define EREG_CSC_COEF_01 0x1048 //Color space conversion coefficient 01 0x004b 363 -+#define EREG_CSC_COEF_02 0x104a //Color space conversion coefficient 02 0x000f 363 -+#define EREG_CSC_COEF_10 0x104c //Color space conversion coefficient 10 0x01ed 363 -+#define EREG_CSC_COEF_11 0x104e //Color space conversion coefficient 11 0x01db 363 -+#define EREG_CSC_COEF_12 0x1050 //Color space conversion coefficient 12 0x0038 363 -+#define EREG_CSC_COEF_20 0x1052 //Color space conversion coefficient 20 0x004f 363 -+#define EREG_CSC_COEF_21 0x1054 //Color space conversion coefficient 21 0x01be 363 -+#define EREG_CSC_COEF_22 0x1056 //Color space conversion coefficient 22 0x01f3 363 -+#define EREG_CSC_OS_0 0x1058 //Color space conversion offset 0 0x0000 364 -+#define EREG_CSC_OS_1 0x105a //Color space conversion offset 1 0x0080 364 -+#define EREG_CSC_OS_2 0x105c //Color space conversion offset 2 0x0080 364 -+#define EREG_DATA_GEN 0x105e //Test data generator 0x0000 365 -+#define EREG_HSYNC_PER 0x1060 //Horizontal synchronization period 0x0a8b 366 -+#define EREG_APS_COEF_GRN1 0x1062 //Green 1 AWB gain 0x0080 368 -+#define EREG_APS_COEF_RED 0x1064 //Red AWB gain 0x0080 368 -+ -+ -+#define EREG_APS_COEF_BLUE 0x1066 //Blue AWB gain 0x0080 368 -+#define EREG_APS_COEF_GRN2 0x1068 //Green 2 AWB gain 0x0080 368 -+#define EREG_AV_LEFT_TOP 0x106a //Anti-v,sensor first row and column 0x0101 369 -+#define EREG_AV_RIGHT_BOT 0x106c //Anti-v, sensor last row and column 0xa27a 370 -+#define EREG_AV_CENTER_COL 0x106e //Anti-v, sensor center column 0x0148 371 -+#define EREG_AV_CENTER_ROW 0x1070 //Anti-v, sensor center row 0x00f8 372 -+#define EREG_STAT_CAP_CTRL 0x1072 //Image statistics capture control 0x0021 373 -+#define EREG_STAT_MODE_CTRL 0x1074 //Image statistics mode control 0x0000 374 -+#define EREG_GREEN_1_SUM 0x1076 //Green 1 pixel sum 0x0000 375 -+#define EREG_RED_SUM 0x1078 //Red pixel sum 0x0000 375 -+#define EREG_BLUE_SUM 0x107a //Blue pixel sum 0x0000 375 -+#define EREG_GREEN_2_SUM 0x107c //Green 2 pixel sum 0x0000 375 -+#define EREG_I_WIDTH 0x107e //Current image width 0x0000 376 -+#define EREG_I_HEIGHT 0x1080 //Current image height 0x0000 377 -+#define EREG_STATUS_FLAGS 0x1082 //Status flags (read only) 0x0000 378 -+#define EREG_CLK_GATE_DIS 0x1084 //Clock gate disable 0x0000 379 -+#define EREG_CCIR_TIMING2 0x1086 //CCIR interface timing 2 0x0000 381 -+#define EREG_CCIR_TIMING3 0x1088 //CCIR interface timing 3 0x0010 382 -+#define EREG_G1G2_DIAG_THRESH 0x108a //Green 1/green 2 diagonal threshold 0x0040 383 -+#define EREG_BPA_D2_THRESH 0x108c //BPA second derivative threshold 0x0100 384 -+#define EREG_SERIAL_CTRL 0x108e //Serial control 0x0000 385 -+#define EREG_INTP_CTRL_1 0x1090 //Interpolation control 1(demosaic) 0x0188 387 -+#define EREG_INTP_CTRL_2 0x1092 //Interpolation control 2(demosaic) 0x00c8 388 -+#define EREG_AV_OVAL_FACT 0x1094 //Anti-vignetting oval factor 0x0100 389 -+#define EREG_AV_OS_GREEN1 0x1096 //Anti-vignetting green 1 offset 0x0000 391 -+#define EREG_AV_OS_RED 0x1098 //Anti-vignetting red offset 0x0000 391 -+#define EREG_AV_OS_BLUE 0x109a //Anti-vignetting blue offset 0x0000 391 -+#define EREG_AV_OS_GREEN2 0x109c //Anti-vignetting green 2 offset 0x0000 391 -+ -+ -+/*********************************************************************** -+ * -+ * typedefs & Structures -+ * -+ ***********************************************************************/ -+ -+struct adcm3800_context_s -+{ -+ int video_running; // =1 video is running -+ int SCL_partial; // =1 partial SCL updated -+ int SCL_restart; // =1 SCL & restart updated -+ -+ u32 chipid; -+ -+ u16 format; -+ u16 sensor_w; -+ u16 sensor_h; -+ u16 output_w; -+ u16 output_h; -+ -+ // frame rate control -+ unsigned int fps; -+ unsigned int mclk; -+ -+ int bright; -+ V4l_PIC_STYLE style; -+ V4l_PIC_WB light; -+ int flicker_freq; -+ -+ V4l_NM expo_mode; -+ int max_expotime; -+}; -+ -+typedef struct adcm3800_context_s adcm3800_context_t, *p_adcm3800_context_t; -+ -+ -+/*********************************************************************** -+ * -+ * Function Prototype -+ * -+ ***********************************************************************/ -+ -+// Configuration Procedures -+int adcm3800_power_on(u32 clk); -+int adcm3800_power_off(void ); -+int adcm3800_viewfinder_on( void ); -+int adcm3800_viewfinder_off( void ); -+int adcm3800_reconfigure(p_camera_context_t cam_ctx, int frames); -+ -+int adcm3800_set_output_format(u16 format); -+int adcm3800_set_output_size(u16 width, u16 height); -+int adcm3800_set_sensor_size(u16 width, u16 height); -+ -+int adcm3800_set_fps(u16 fps); -+ -+/*set picture style(normal/black white/sepia/solarize/neg.art)*/ -+int adcm3800_set_style(V4l_PIC_STYLE style); -+/*set picture light(direct sun/incandescent/fluorescent)*/ -+int adcm3800_set_light(V4l_PIC_WB light); -+/*set picture brightness*/ -+int adcm3800_set_bright(int bright); -+int adcm3800_set_flicker(int freq); -+int adcm3800_set_exposure_mode(V4l_NM mode, int maxexpotime); -+ -+extern int i2c_adcm3800_read(u16 addr, u16 *pvalue); -+extern int i2c_adcm3800_write(u16 addr, u16 value); -+extern int i2c_adcm3800_read_byte(u16 addr, u8 *pvalue); -+extern int i2c_adcm3800_write_byte(u16 addr, u8 value); -+ -+#endif /* _PXA_ADCM3800_HW_H__ */ -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/camera.h linux-2.6.16.5-exz/drivers/media/video/camera.h ---- linux-2.6.16.5/drivers/media/video/camera.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/camera.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,663 @@ -+/*================================================================================ -+ -+ Module Name: camera.h -+ -+General Description: Camera module adcm2700 head file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+Wangfei(w20239) 12/19/2003 LIBdd35749 Created -+wangfei(w20239) 02/26/2004 LIBdd81055 Update algorithm for DMA transfer -+ -+Portability: Indicate ifthis module is portable to other compilers or -+platforms. If not, indicate specific reasons why is it not portable. -+ -+================================================================================== -+ INCLUDE FILES -+================================================================================*/ -+#ifndef CAMERA_H_ -+#define CAMERA_H_ -+ -+#include <linux/pxa_camera.h> -+#include <linux/videodev.h> -+ -+#define DEBUG 1 -+ -+#ifdef CONFIG_CAMERA_ADCM2700 -+#endif -+ -+#ifdef CONFIG_CAMERA_OV9640 -+#endif -+ -+#ifdef CONFIG_CAMERA_MT9M111 -+#endif -+ -+/* -+Bpp definition -+*/ -+ -+#define YUV422_BPP 16 -+#define RGB565_BPP 16 -+#define RGB666_UNPACKED_BPP 32 -+#define RGB666_PACKED_BPP 24 -+ -+//--------------------------------------------------------------------------- -+// Register definitions -+//--------------------------------------------------------------------------- -+ -+enum CI_REGBITS_CICR0 { -+ CI_CICR0_FOM = 0x00000001, -+ CI_CICR0_EOFM = 0x00000002, -+ CI_CICR0_SOFM = 0x00000004, -+ CI_CICR0_CDM = 0x00000008, -+ CI_CICR0_QDM = 0x00000010, -+ CI_CICR0_PERRM = 0x00000020, -+ CI_CICR0_EOLM = 0x00000040, -+ CI_CICR0_FEM = 0x00000080, -+ CI_CICR0_RDAVM = 0x00000100, -+ CI_CICR0_TOM = 0x00000200, -+ CI_CICR0_RESERVED = 0x03FFFC00, -+ CI_CICR0_SIM_SHIFT = 24, -+ CI_CICR0_SIM_SMASK = 0x7, -+ CI_CICR0_DIS = 0x08000000, -+ CI_CICR0_ENB = 0x10000000, -+ CI_CICR0_SL_CAP_EN = 0x20000000, -+ CI_CICR0_PAR_EN = 0x40000000, -+ CI_CICR0_DMA_EN = 0x80000000, -+ CI_CICR0_INTERRUPT_MASK = 0x3FF -+}; -+ -+enum CI_REGBITS_CICR1 { -+ CI_CICR1_DW_SHIFT = 0, -+ CI_CICR1_DW_SMASK = 0x7, -+ CI_CICR1_COLOR_SP_SHIFT = 3, -+ CI_CICR1_COLOR_SP_SMASK = 0x3, -+ CI_CICR1_RAW_BPP_SHIFT = 5, -+ CI_CICR1_RAW_BPP_SMASK = 0x3, -+ CI_CICR1_RGB_BPP_SHIFT = 7, -+ CI_CICR1_RGB_BPP_SMASK = 0x7, -+ CI_CICR1_YCBCR_F = 0x00000400, -+ CI_CICR1_RBG_F = 0x00000800, -+ CI_CICR1_RGB_CONV_SHIFT = 12, -+ CI_CICR1_RGB_CONV_SMASK = 0x7, -+ CI_CICR1_PPL_SHIFT = 15, -+ CI_CICR1_PPL_SMASK = 0x7FF, -+ CI_CICR1_RESERVED = 0x1C000000, -+ CI_CICR1_RGBT_CONV_SHIFT= 29, -+ CI_CICR1_RGBT_CONV_SMASK= 0x3, -+ CI_CICR1_TBIT = 0x80000000 -+}; -+ -+enum CI_REGBITS_CICR2 { -+ CI_CICR2_FSW_SHIFT = 0, -+ CI_CICR2_FSW_SMASK = 0x3, -+ CI_CICR2_BFPW_SHIFT= 3, -+ CI_CICR2_BFPW_SMASK= 0x3F, -+ CI_CICR2_RESERVED = 0x00000200, -+ CI_CICR2_HSW_SHIFT = 10, -+ CI_CICR2_HSW_SMASK = 0x3F, -+ CI_CICR2_ELW_SHIFT = 16, -+ CI_CICR2_ELW_SMASK = 0xFF, -+ CI_CICR2_BLW_SHIFT = 24, -+ CI_CICR2_BLW_SMASK = 0xFF -+}; -+ -+enum CI_REGBITS_CICR3 { -+ CI_CICR3_LPF_SHIFT = 0, -+ CI_CICR3_LPF_SMASK = 0x7FF, -+ CI_CICR3_VSW_SHIFT = 11, -+ CI_CICR3_VSW_SMASK = 0x1F, -+ CI_CICR3_EFW_SHIFT = 16, -+ CI_CICR3_EFW_SMASK = 0xFF, -+ CI_CICR3_BFW_SHIFT = 24, -+ CI_CICR3_BFW_SMASK = 0xFF -+}; -+ -+enum CI_REGBITS_CICR4 { -+ CI_CICR4_DIV_SHIFT = 0, -+ CI_CICR4_DIV_SMASK = 0xFF, -+ CI_CICR4_FR_RATE_SHIFT = 8, -+ CI_CICR4_FR_RATE_SMASK = 0x7, -+ CI_CICR4_RESERVED1 = 0x0007F800, -+ CI_CICR4_MCLK_EN = 0x00080000, -+ CI_CICR4_VSP = 0x00100000, -+ CI_CICR4_HSP = 0x00200000, -+ CI_CICR4_PCP = 0x00400000, -+ CI_CICR4_PCLK_EN = 0x00800000, -+ CI_CICR4_RESERVED2 = 0xFF000000, -+ CI_CICR4_RESERVED = CI_CICR4_RESERVED1 | CI_CICR4_RESERVED2 -+}; -+ -+enum CI_REGBITS_CISR { -+ CI_CISR_IFO_0 = 0x00000001, -+ CI_CISR_IFO_1 = 0x00000002, -+ CI_CISR_IFO_2 = 0x00000004, -+ CI_CISR_EOF = 0x00000008, -+ CI_CISR_SOF = 0x00000010, -+ CI_CISR_CDD = 0x00000020, -+ CI_CISR_CQD = 0x00000040, -+ CI_CISR_PAR_ERR = 0x00000080, -+ CI_CISR_EOL = 0x00000100, -+ CI_CISR_FEMPTY_0 = 0x00000200, -+ CI_CISR_FEMPTY_1 = 0x00000400, -+ CI_CISR_FEMPTY_2 = 0x00000800, -+ CI_CISR_RDAV_0 = 0x00001000, -+ CI_CISR_RDAV_1 = 0x00002000, -+ CI_CISR_RDAV_2 = 0x00004000, -+ CI_CISR_FTO = 0x00008000, -+ CI_CISR_RESERVED = 0xFFFF0000 -+}; -+ -+enum CI_REGBITS_CIFR { -+ CI_CIFR_FEN0 = 0x00000001, -+ CI_CIFR_FEN1 = 0x00000002, -+ CI_CIFR_FEN2 = 0x00000004, -+ CI_CIFR_RESETF = 0x00000008, -+ CI_CIFR_THL_0_SHIFT= 4, -+ CI_CIFR_THL_0_SMASK= 0x3, -+ CI_CIFR_RESERVED1 = 0x000000C0, -+ CI_CIFR_FLVL0_SHIFT= 8, -+ CI_CIFR_FLVL0_SMASK= 0xFF, -+ CI_CIFR_FLVL1_SHIFT= 16, -+ CI_CIFR_FLVL1_SMASK= 0x7F, -+ CI_CIFR_FLVL2_SHIFT= 23, -+ CI_CIFR_FLVL2_SMASK= 0x7F, -+ CI_CIFR_RESERVED2 = 0xC0000000, -+ CI_CIFR_RESERVED = CI_CIFR_RESERVED1 | CI_CIFR_RESERVED2 -+}; -+ -+//--------------------------------------------------------------------------- -+// Parameter Type definitions -+//--------------------------------------------------------------------------- -+typedef enum { -+ CI_RAW8 = 0, //RAW -+ CI_RAW9, -+ CI_RAW10, -+ CI_YCBCR422, //YCBCR -+ CI_YCBCR422_PLANAR, //YCBCR Planaried -+ CI_RGB444, //RGB -+ CI_RGB555, -+ CI_RGB565, -+ CI_RGB666, -+ CI_RGB888, -+ CI_RGBT555_0, //RGB+Transparent bit 0 -+ CI_RGBT888_0, -+ CI_RGBT555_1, //RGB+Transparent bit 1 -+ CI_RGBT888_1, -+ CI_RGB666_PACKED, //RGB Packed -+ CI_RGB888_PACKED, -+ CI_INVALID_FORMAT = 0xFF -+} CI_IMAGE_FORMAT; -+ -+typedef enum { -+ CI_INTSTATUS_IFO_0 = 0x00000001, -+ CI_INTSTATUS_IFO_1 = 0x00000002, -+ CI_INTSTATUS_IFO_2 = 0x00000004, -+ CI_INTSTATUS_EOF = 0x00000008, -+ CI_INTSTATUS_SOF = 0x00000010, -+ CI_INTSTATUS_CDD = 0x00000020, -+ CI_INTSTATUS_CQD = 0x00000040, -+ CI_INTSTATUS_PAR_ERR = 0x00000080, -+ CI_INTSTATUS_EOL = 0x00000100, -+ CI_INTSTATUS_FEMPTY_0 = 0x00000200, -+ CI_INTSTATUS_FEMPTY_1 = 0x00000400, -+ CI_INTSTATUS_FEMPTY_2 = 0x00000800, -+ CI_INTSTATUS_RDAV_0 = 0x00001000, -+ CI_INTSTATUS_RDAV_1 = 0x00002000, -+ CI_INTSTATUS_RDAV_2 = 0x00004000, -+ CI_INTSTATUS_FTO = 0x00008000, -+ CI_INTSTATUS_ALL = 0x0000FFFF -+} CI_INTERRUPT_STATUS; -+ -+typedef enum { -+ CI_INT_IFO = 0x00000001, -+ CI_INT_EOF = 0x00000002, -+ CI_INT_SOF = 0x00000004, -+ CI_INT_CDD = 0x00000008, -+ CI_INT_CQD = 0x00000010, -+ CI_INT_PAR_ERR = 0x00000020, -+ CI_INT_EOL = 0x00000040, -+ CI_INT_FEMPTY = 0x00000080, -+ CI_INT_RDAV = 0x00000100, -+ CI_INT_FTO = 0x00000200, -+ CI_INT_ALL = 0x000003FF -+} CI_INTERRUPT_MASK; -+#define CI_INT_MAX 10 -+ -+typedef enum CI_MODE { -+ CI_MODE_MP, // Master-Parallel -+ CI_MODE_SP, // Slave-Parallel -+ CI_MODE_MS, // Master-Serial -+ CI_MODE_EP, // Embedded-Parallel -+ CI_MODE_ES // Embedded-Serial -+} CI_MODE; -+ -+ -+typedef enum { -+ CI_FR_ALL = 0, // Capture all incoming frames -+ CI_FR_1_2, // Capture 1 out of every 2 frames -+ CI_FR_1_3, // Capture 1 out of every 3 frames -+ CI_FR_1_4, -+ CI_FR_1_5, -+ CI_FR_1_6, -+ CI_FR_1_7, -+ CI_FR_1_8 -+} CI_FRAME_CAPTURE_RATE; -+ -+ -+typedef enum { -+ CI_FIFO_THL_32 = 0, -+ CI_FIFO_THL_64, -+ CI_FIFO_THL_96 -+} CI_FIFO_THRESHOLD; -+ -+typedef struct { -+ unsigned int BFW; -+ unsigned int BLW; -+} CI_MP_TIMING, CI_MS_TIMING; -+ -+typedef struct { -+ unsigned int BLW; -+ unsigned int ELW; -+ unsigned int HSW; -+ unsigned int BFPW; -+ unsigned int FSW; -+ unsigned int BFW; -+ unsigned int EFW; -+ unsigned int VSW; -+} CI_SP_TIMING; -+ -+typedef enum { -+ CI_DATA_WIDTH4 = 0x0, -+ CI_DATA_WIDTH5 = 0x1, -+ CI_DATA_WIDTH8 = 0x2, -+ CI_DATA_WIDTH9 = 0x3, -+ CI_DATA_WIDTH10= 0x4 -+} CI_DATA_WIDTH; -+ -+//------------------------------------------------------------------------------------------------------- -+// Configuration APIs -+//------------------------------------------------------------------------------------------------------- -+ -+void ci_set_frame_rate(CI_FRAME_CAPTURE_RATE frate); -+CI_FRAME_CAPTURE_RATE ci_get_frame_rate(void); -+void ci_set_image_format(CI_IMAGE_FORMAT input_format, CI_IMAGE_FORMAT output_format); -+void ci_set_mode(CI_MODE mode, CI_DATA_WIDTH data_width); -+void ci_configure_mp(unsigned int PPL, unsigned int LPF, CI_MP_TIMING* timing); -+void ci_configure_sp(unsigned int PPL, unsigned int LPF, CI_SP_TIMING* timing); -+void ci_configure_ms(unsigned int PPL, unsigned int LPF, CI_MS_TIMING* timing); -+void ci_configure_ep(int parity_check); -+void ci_configure_es(int parity_check); -+void ci_set_clock(unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz); -+void ci_set_polarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low); -+void ci_set_fifo( unsigned int timeout, CI_FIFO_THRESHOLD threshold, int fifo1_enable, -+ int fifo2_enable); -+void ci_set_int_mask( unsigned int mask); -+void ci_clear_int_status( unsigned int status); -+void ci_set_reg_value( unsigned int reg_offset, unsigned int value); -+int ci_get_reg_value(unsigned int reg_offset); -+ -+void ci_reset_fifo(void); -+unsigned int ci_get_int_mask(void); -+unsigned int ci_get_int_status(void); -+void ci_slave_capture_enable(void); -+void ci_slave_capture_disable(void); -+ -+//------------------------------------------------------------------------------------------------------- -+// Control APIs -+//------------------------------------------------------------------------------------------------------- -+int ci_init(void); -+void ci_deinit(void); -+void ci_enable( int dma_en); -+int ci_disable(int quick); -+ -+//debug -+void ci_dump(void); -+// IRQ -+irqreturn_t pxa_camera_irq(int irq, void *dev_id, struct pt_regs *regs); -+ -+#ifdef DEBUG -+ -+#define dbg_print(fmt, args...) printk(KERN_INFO "fun %s "fmt"\n", __FUNCTION__, ##args) -+ -+#if DEBUG > 1 -+#define ddbg_print(fmt, args...) printk(KERN_INFO "fun %s "fmt"\n", __FUNCTION__, ##args) -+#else -+#define ddbg_print(fmt, args...) ; -+#endif -+ -+#else -+ -+#define dbg_print(fmt, args...) ; -+#define ddbg_print(fmt, args...) ; -+ -+#endif -+ -+ -+#define VID_HARDWARE_PXA_CAMERA 50 /* subject to change */ -+ -+#define STATUS_FAILURE (0) -+#define STATUS_SUCCESS (1) -+#define STATUS_WRONG_PARAMETER -1 -+ -+#ifdef CONFIG_CAMERA_OV9640 -+#define CIBR0_PHY (0x50000000 + 0x28) -+#define CIBR1_PHY (0x50000000 + 0x30) -+#define CIBR2_PHY (0x50000000 + 0x38) -+#endif -+/* -+Macros -+*/ -+/*GPIO and CIF pin definitions*/ -+#define CIF_PD 50 -+#define CIF_RST 19 -+#define CIF_MCLK 23 -+#define CIF_PCLK 54 -+#define CIF_LV 85 -+#define CIF_FV 84 -+#define CIF_DD0 27 -+#define CIF_DD1 114 -+#define CIF_DD2 51 -+#define CIF_DD3 115 -+#define CIF_DD4 95 -+#define CIF_DD5 94 -+#define CIF_DD6 17 -+#define CIF_DD7 108 -+ -+#define CIF_PD_MD (CIF_PD | GPIO_OUT) -+#define CIF_RST_MD (CIF_RST | GPIO_OUT) -+#define CIF_MCLK_MD (CIF_MCLK | GPIO_ALT_FN_1_OUT) -+#define CIF_PCLK_MD (CIF_PCLK | GPIO_ALT_FN_3_IN) -+#define CIF_LV_MD (CIF_LV | GPIO_ALT_FN_3_IN) -+#define CIF_FV_MD (CIF_FV | GPIO_ALT_FN_3_IN) -+#define CIF_DD0_MD (CIF_DD0 | GPIO_ALT_FN_3_IN) -+#define CIF_DD1_MD (CIF_DD1 | GPIO_ALT_FN_1_IN) -+#define CIF_DD2_MD (CIF_DD2 | GPIO_ALT_FN_1_IN) -+#define CIF_DD3_MD (CIF_DD3 | GPIO_ALT_FN_2_IN) -+#define CIF_DD4_MD (CIF_DD4 | GPIO_ALT_FN_2_IN) -+#define CIF_DD5_MD (CIF_DD5 | GPIO_ALT_FN_2_IN) -+#define CIF_DD6_MD (CIF_DD6 | GPIO_ALT_FN_2_IN) -+#define CIF_DD7_MD (CIF_DD7 | GPIO_ALT_FN_1_IN) -+ -+/* -+Image format definition -+*/ -+#define CAMERA_IMAGE_FORMAT_MAX CAMERA_IMAGE_FORMAT_YCBCR444_PLANAR -+ -+// Interrupt mask -+#define CAMERA_INTMASK_FIFO_OVERRUN 0x0001 -+#define CAMERA_INTMASK_END_OF_FRAME 0x0002 -+#define CAMERA_INTMASK_START_OF_FRAME 0x0004 -+#define CAMERA_INTMASK_CI_DISABLE_DONE 0x0008 -+#define CAMERA_INTMASK_CI_QUICK_DISABLE 0x0010 -+#define CAMERA_INTMASK_PARITY_ERROR 0x0020 -+#define CAMERA_INTMASK_END_OF_LINE 0x0040 -+#define CAMERA_INTMASK_FIFO_EMPTY 0x0080 -+#define CAMERA_INTMASK_RCV_DATA_AVALIBLE 0x0100 -+#define CAMERA_INTMASK_TIME_OUT 0x0200 -+#define CAMERA_INTMASK_END_OF_DMA 0x0400 -+ -+// Interrupt status -+#define CAMERA_INTSTATUS_FIFO_OVERRUN_0 0x00000001 -+#define CAMERA_INTSTATUS_FIFO_OVERRUN_1 0x00000002 -+#define CAMERA_INTSTATUS_FIFO_OVERRUN_2 0x00000004 -+#define CAMERA_INTSTATUS_END_OF_FRAME 0x00000008 -+#define CAMERA_INTSTATUS_START_OF_FRAME 0x00000010 -+#define CAMERA_INTSTATUS_CI_DISABLE_DONE 0x00000020 -+#define CAMERA_INTSTATUS_CI_QUICK_DISABLE 0x00000040 -+#define CAMERA_INTSTATUS_PARITY_ERROR 0x00000080 -+#define CAMERA_INTSTATUS_END_OF_LINE 0x00000100 -+#define CAMERA_INTSTATUS_FIFO_EMPTY_0 0x00000200 -+#define CAMERA_INTSTATUS_FIFO_EMPTY_1 0x00000400 -+#define CAMERA_INTSTATUS_FIFO_EMPTY_2 0x00000800 -+#define CAMERA_INTSTATUS_RCV_DATA_AVALIBLE_0 0x00001000 -+#define CAMERA_INTSTATUS_RCV_DATA_AVALIBLE_1 0x00002000 -+#define CAMERA_INTSTATUS_RCV_DATA_AVALIBLE_2 0x00004000 -+#define CAMERA_INTSTATUS_TIME_OUT 0x00008000 -+#define CAMERA_INTSTATUS_END_OF_DMA 0x00010000 -+ -+// Capture status -+#define CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS 0x0001 -+#define CAMERA_STATUS_RING_BUFFER_FULL 0x0002 -+ -+ -+/* -+Structures -+*/ -+typedef struct camera_context_s camera_context_t, *p_camera_context_t; -+ -+typedef struct { -+ int (*init)(p_camera_context_t context); -+ int (*deinit)(p_camera_context_t); -+ int (*set_capture_format)(p_camera_context_t); -+ int (*start_capture)(p_camera_context_t, unsigned int frames); -+ int (*stop_capture)(p_camera_context_t); -+ int (*command)(p_camera_context_t, unsigned int cmd, void *param); -+ int (*pm_management)(p_camera_context_t, int suspend); -+} camera_function_t, *p_camera_function_t; -+// context -+ -+struct camera_context_s { -+ // syncronization stuff -+ atomic_t refcount; -+ -+ /* -+ * DRIVER FILLED PARAMTER -+ */ -+ -+ // sensor info -+ unsigned int sensor_type; -+ -+ // capture image info -+ unsigned int capture_width; -+ unsigned int capture_height; -+ unsigned int sensor_width; -+ unsigned int sensor_height; -+ -+ unsigned int capture_input_format; -+ unsigned int capture_output_format; -+ V4l_PIC_STYLE capture_style; -+ V4l_PIC_WB capture_light; -+ int capture_bright; -+ int capture_contrast; -+ int flicker_freq; -+ -+ -+ -+ struct video_capability vc; -+ -+ -+ // frame rate control -+ unsigned int frame_rate; -+ unsigned int fps; -+ unsigned int mini_fps; -+ -+ unsigned int mclk; -+ -+ // ring buffers -+ // note: must pass in 8 bytes aligned address -+ void *buffer_virtual; -+ void *buffer_physical; -+ unsigned int buf_size; -+ -+ // memory for dma descriptors, layout: -+ // dma descriptor chain 0, -+ // dma descriptor chain 1, -+ // ... -+ void *dma_descriptors_virtual; -+ void *dma_descriptors_physical; -+ unsigned int dma_descriptors_size; -+ -+ // os mapped register address -+ unsigned int clk_reg_base; -+ unsigned int ost_reg_base; -+ unsigned int gpio_reg_base; -+ unsigned int ci_reg_base; -+ unsigned int board_reg_base; -+ -+ // function dispatch table -+ p_camera_function_t camera_functions; -+ -+ /* -+ * FILLED PARAMTER -+ */ -+ int dma_channels[3]; -+ unsigned int capture_status; -+ -+ /* -+ * INTERNALLY USED: DON'T TOUCH! -+ */ -+ unsigned int block_number, block_size, block_number_max; -+ unsigned int block_header, block_tail; -+ unsigned int fifo0_descriptors_virtual, fifo0_descriptors_physical; -+ unsigned int fifo1_descriptors_virtual, fifo1_descriptors_physical; -+ unsigned int fifo2_descriptors_virtual, fifo2_descriptors_physical; -+ unsigned int fifo0_num_descriptors; -+ unsigned int fifo1_num_descriptors; -+ unsigned int fifo2_num_descriptors; -+ unsigned int fifo0_transfer_size; -+ unsigned int fifo1_transfer_size; -+ unsigned int fifo2_transfer_size; -+ -+ struct page **page_array; -+ -+ unsigned int pages_allocated; -+ unsigned int page_aligned_block_size; -+ unsigned int pages_per_block; -+ unsigned int pages_per_fifo0; -+ unsigned int pages_per_fifo1; -+ unsigned int pages_per_fifo2; -+ -+#ifdef CONFIG_DPM -+ struct pm_dev *pmdev; -+#endif -+ int dma_started; -+}; -+ -+ -+/* -+Prototypes -+*/ -+/*********************************************************************** -+ * -+ * Init/Deinit APIs -+ * -+ ***********************************************************************/ -+// Setup the sensor type, configure image capture format (RGB, yuv 444, yuv 422, yuv 420, packed | planar, MJPEG) regardless -+// of current operating mode (i.e. sets mode for both still capture and video capture) -+int camera_init( p_camera_context_t camera_context ); -+ -+// Power off sensor -+int camera_deinit( p_camera_context_t camera_context ); -+ -+ -+/*********************************************************************** -+ * -+ * Capture APIs -+ * -+ ***********************************************************************/ -+// Set the image format -+int camera_set_capture_format( p_camera_context_t camera_context ); -+ -+// take a picture and copy it into the ring buffer -+int camera_capture_still_image( p_camera_context_t camera_context, unsigned int block_id ); -+ -+// capture motion video and copy it the ring buffer -+int camera_start_video_capture( p_camera_context_t camera_context, unsigned int block_id ); -+ -+// disable motion video image capture -+void camera_stop_video_capture( p_camera_context_t camera_context ); -+ -+int camera_func_ov9640_command(p_camera_context_t camera_context, unsigned int cmd, void *param); -+ -+/*********************************************************************** -+ * -+ * Flow Control APIs -+ * -+ ***********************************************************************/ -+// continue capture image to next available buffer -+// Returns the continued buffer id, -1 means buffer full and no transfer started -+void camera_continue_transfer( p_camera_context_t camera_context ); -+ -+// Return 1: there is available buffer, 0: buffer is full -+int camera_next_buffer_available( p_camera_context_t camera_context ); -+ -+// Application supplies the FrameBufferID to the driver to tell it that the application has completed processing of the given frame buffer, and that buffer is now available for re-use. -+void camera_release_frame_buffer( p_camera_context_t camera_context, unsigned int frame_buffer_id ); -+ -+// Returns the FrameBufferID for the first filled frame -+// Note: -1 represents buffer empty -+int camera_get_first_frame_buffer_id( p_camera_context_t camera_context ); -+ -+/* -+Returns the FrameBufferID for the last filled frame, this would be used if we were polling for image completion data, -+or we wanted to make sure there were no frames waiting for us to process. -+Note: -1 represents buffer empty -+*/ -+int camera_get_last_frame_buffer_id( p_camera_context_t camera_context ); -+ -+ -+/*********************************************************************** -+ * -+ * Buffer Info APIs -+ * -+ ***********************************************************************/ -+// Return: the number of frame buffers allocated for use. -+unsigned int camera_get_num_frame_buffers( p_camera_context_t camera_context ); -+ -+/* -+FrameBufferID is a number between 0 and N-1, where N is the total number of frame buffers in use. -+Returns the address of the given frame buffer. -+The application will call this once for each frame buffer at application initialization only. -+*/ -+void* camera_get_frame_buffer_addr( p_camera_context_t camera_context, unsigned int frame_buffer_id ); -+ -+// Return the block id -+int camera_get_frame_buffer_id( p_camera_context_t camera_context, void* address ); -+ -+/*********************************************************************** -+ * -+ * Frame rate APIs -+ * -+ ***********************************************************************/ -+// Set desired frame rate -+void camera_set_capture_frame_rate( p_camera_context_t camera_context ); -+ -+// return current setting -+void camera_get_capture_frame_rate( p_camera_context_t camera_context ); -+ -+ -+/*********************************************************************** -+ * -+ * Interrupt APIs -+ * -+ ***********************************************************************/ -+// set interrupt mask -+void camera_set_int_mask( p_camera_context_t camera_context, unsigned int mask ); -+ -+// get interrupt mask -+unsigned int camera_get_int_mask( p_camera_context_t camera_context ); -+ -+// clear interrupt status -+void camera_clear_int_status( p_camera_context_t camera_context, unsigned int status ); -+ -+// gpio init -+void camera_gpio_init(void); -+void camera_gpio_deinit(void); -+ -+// ci functions -+void ci_reset(void); -+ -+// dma functions -+extern void start_dma_transfer(p_camera_context_t camera_context, unsigned block_id); -+extern void stop_dma_transfer(p_camera_context_t camera_context); -+extern int camera_ring_buf_init(p_camera_context_t camera_context); -+ -+#endif -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ci.h linux-2.6.16.5-exz/drivers/media/video/ci.h ---- linux-2.6.16.5/drivers/media/video/ci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ci.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,303 @@ -+/******************************************************************************
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+********************************************************************************/
-+#ifndef __CI_H__
-+#define __CI_H__
-+
-+//---------------------------------------------------------------------------
-+// Register definitions
-+//---------------------------------------------------------------------------
-+
-+extern unsigned long ci_regs_base ; /* for CI registers IOMEM mapping */
-+
-+#define CI_REG(x) (* (volatile u32*)(x) )
-+#define CI_REG_SIZE 0x40 /* 0x5000_0000 --- 0x5000_0038 * 64K */
-+#define CI_REGS_PHYS 0x50000000 /* Start phyical address of CI registers */
-+//
-+#define CICR0 CI_REG((u32)(ci_regs_base) + 0x00)
-+#define CICR1 CI_REG((u32)(ci_regs_base) + 0x04)
-+#define CICR2 CI_REG((u32)(ci_regs_base) + 0x08)
-+#define CICR3 CI_REG((u32)(ci_regs_base) + 0x0c)
-+#define CICR4 CI_REG((u32)(ci_regs_base) + 0x10)
-+#define CISR CI_REG((u32)(ci_regs_base) + 0x14)
-+#define CIFR CI_REG((u32)(ci_regs_base) + 0x18)
-+#define CITOR CI_REG((u32)(ci_regs_base) + 0x1c)
-+#define CIBR0 CI_REG((u32)(ci_regs_base) + 0x28)
-+#define CIBR1 CI_REG((u32)(ci_regs_base) + 0x30)
-+#define CIBR2 CI_REG((u32)(ci_regs_base) + 0x38)
-+/*
-+*/
-+enum CI_REGBITS_CICR0 {
-+ CI_CICR0_FOM = 0x00000001,
-+ CI_CICR0_EOFM = 0x00000002,
-+ CI_CICR0_SOFM = 0x00000004,
-+ CI_CICR0_CDM = 0x00000008,
-+ CI_CICR0_QDM = 0x00000010,
-+ CI_CICR0_PERRM = 0x00000020,
-+ CI_CICR0_EOLM = 0x00000040,
-+ CI_CICR0_FEM = 0x00000080,
-+ CI_CICR0_RDAVM = 0x00000100,
-+ CI_CICR0_TOM = 0x00000200,
-+ CI_CICR0_RESERVED = 0x03FFFC00,
-+ CI_CICR0_SIM_SHIFT = 24,
-+ CI_CICR0_SIM_SMASK = 0x7,
-+ CI_CICR0_DIS = 0x08000000,
-+ CI_CICR0_ENB = 0x10000000,
-+ CI_CICR0_SL_CAP_EN = 0x20000000,
-+ CI_CICR0_PAR_EN = 0x40000000,
-+ CI_CICR0_DMA_EN = 0x80000000,
-+ CI_CICR0_INTERRUPT_MASK = 0x3FF
-+};
-+
-+enum CI_REGBITS_CICR1 {
-+ CI_CICR1_DW_SHIFT = 0,
-+ CI_CICR1_DW_SMASK = 0x7,
-+ CI_CICR1_COLOR_SP_SHIFT = 3,
-+ CI_CICR1_COLOR_SP_SMASK = 0x3,
-+ CI_CICR1_RAW_BPP_SHIFT = 5,
-+ CI_CICR1_RAW_BPP_SMASK = 0x3,
-+ CI_CICR1_RGB_BPP_SHIFT = 7,
-+ CI_CICR1_RGB_BPP_SMASK = 0x7,
-+ CI_CICR1_YCBCR_F = 0x00000400,
-+ CI_CICR1_RBG_F = 0x00000800,
-+ CI_CICR1_RGB_CONV_SHIFT = 12,
-+ CI_CICR1_RGB_CONV_SMASK = 0x7,
-+ CI_CICR1_PPL_SHIFT = 15,
-+ CI_CICR1_PPL_SMASK = 0x7FF,
-+ CI_CICR1_RESERVED = 0x1C000000,
-+ CI_CICR1_RGBT_CONV_SHIFT= 29,
-+ CI_CICR1_RGBT_CONV_SMASK= 0x3,
-+ CI_CICR1_TBIT = 0x80000000
-+};
-+
-+enum CI_REGBITS_CICR2 {
-+ CI_CICR2_FSW_SHIFT = 0,
-+ CI_CICR2_FSW_SMASK = 0x3,
-+ CI_CICR2_BFPW_SHIFT= 3,
-+ CI_CICR2_BFPW_SMASK= 0x3F,
-+ CI_CICR2_RESERVED = 0x00000200,
-+ CI_CICR2_HSW_SHIFT = 10,
-+ CI_CICR2_HSW_SMASK = 0x3F,
-+ CI_CICR2_ELW_SHIFT = 16,
-+ CI_CICR2_ELW_SMASK = 0xFF,
-+ CI_CICR2_BLW_SHIFT = 24,
-+ CI_CICR2_BLW_SMASK = 0xFF
-+};
-+
-+enum CI_REGBITS_CICR3 {
-+ CI_CICR3_LPF_SHIFT = 0,
-+ CI_CICR3_LPF_SMASK = 0x7FF,
-+ CI_CICR3_VSW_SHIFT = 11,
-+ CI_CICR3_VSW_SMASK = 0x1F,
-+ CI_CICR3_EFW_SHIFT = 16,
-+ CI_CICR3_EFW_SMASK = 0xFF,
-+ CI_CICR3_BFW_SHIFT = 24,
-+ CI_CICR3_BFW_SMASK = 0xFF
-+};
-+
-+enum CI_REGBITS_CICR4 {
-+ CI_CICR4_DIV_SHIFT = 0,
-+ CI_CICR4_DIV_SMASK = 0xFF,
-+ CI_CICR4_FR_RATE_SHIFT = 8,
-+ CI_CICR4_FR_RATE_SMASK = 0x7,
-+ CI_CICR4_RESERVED1 = 0x0007F800,
-+ CI_CICR4_MCLK_EN = 0x00080000,
-+ CI_CICR4_VSP = 0x00100000,
-+ CI_CICR4_HSP = 0x00200000,
-+ CI_CICR4_PCP = 0x00400000,
-+ CI_CICR4_PCLK_EN = 0x00800000,
-+ CI_CICR4_RESERVED2 = 0xFF000000,
-+ CI_CICR4_RESERVED = CI_CICR4_RESERVED1 | CI_CICR4_RESERVED2
-+};
-+
-+enum CI_REGBITS_CISR {
-+ CI_CISR_IFO_0 = 0x00000001,
-+ CI_CISR_IFO_1 = 0x00000002,
-+ CI_CISR_IFO_2 = 0x00000004,
-+ CI_CISR_EOF = 0x00000008,
-+ CI_CISR_SOF = 0x00000010,
-+ CI_CISR_CDD = 0x00000020,
-+ CI_CISR_CQD = 0x00000040,
-+ CI_CISR_PAR_ERR = 0x00000080,
-+ CI_CISR_EOL = 0x00000100,
-+ CI_CISR_FEMPTY_0 = 0x00000200,
-+ CI_CISR_FEMPTY_1 = 0x00000400,
-+ CI_CISR_FEMPTY_2 = 0x00000800,
-+ CI_CISR_RDAV_0 = 0x00001000,
-+ CI_CISR_RDAV_1 = 0x00002000,
-+ CI_CISR_RDAV_2 = 0x00004000,
-+ CI_CISR_FTO = 0x00008000,
-+ CI_CISR_RESERVED = 0xFFFF0000
-+};
-+
-+enum CI_REGBITS_CIFR {
-+ CI_CIFR_FEN0 = 0x00000001,
-+ CI_CIFR_FEN1 = 0x00000002,
-+ CI_CIFR_FEN2 = 0x00000004,
-+ CI_CIFR_RESETF = 0x00000008,
-+ CI_CIFR_THL_0_SHIFT= 4,
-+ CI_CIFR_THL_0_SMASK= 0x3,
-+ CI_CIFR_RESERVED1 = 0x000000C0,
-+ CI_CIFR_FLVL0_SHIFT= 8,
-+ CI_CIFR_FLVL0_SMASK= 0xFF,
-+ CI_CIFR_FLVL1_SHIFT= 16,
-+ CI_CIFR_FLVL1_SMASK= 0x7F,
-+ CI_CIFR_FLVL2_SHIFT= 23,
-+ CI_CIFR_FLVL2_SMASK= 0x7F,
-+ CI_CIFR_RESERVED2 = 0xC0000000,
-+ CI_CIFR_RESERVED = CI_CIFR_RESERVED1 | CI_CIFR_RESERVED2
-+};
-+
-+//---------------------------------------------------------------------------
-+// Parameter Type definitions
-+//---------------------------------------------------------------------------
-+typedef enum {
-+ CI_RAW8 = 0, //RAW
-+ CI_RAW9,
-+ CI_RAW10,
-+ CI_YCBCR422, //YCBCR
-+ CI_YCBCR422_PLANAR, //YCBCR Planaried
-+ CI_RGB444, //RGB
-+ CI_RGB555,
-+ CI_RGB565,
-+ CI_RGB666,
-+ CI_RGB888,
-+ CI_RGBT555_0, //RGB+Transparent bit 0
-+ CI_RGBT888_0,
-+ CI_RGBT555_1, //RGB+Transparent bit 1
-+ CI_RGBT888_1,
-+ CI_RGB666_PACKED, //RGB Packed
-+ CI_RGB888_PACKED,
-+ CI_INVALID_FORMAT = 0xFF
-+} CI_IMAGE_FORMAT;
-+
-+typedef enum {
-+ CI_INTSTATUS_IFO_0 = 0x00000001,
-+ CI_INTSTATUS_IFO_1 = 0x00000002,
-+ CI_INTSTATUS_IFO_2 = 0x00000004,
-+ CI_INTSTATUS_EOF = 0x00000008,
-+ CI_INTSTATUS_SOF = 0x00000010,
-+ CI_INTSTATUS_CDD = 0x00000020,
-+ CI_INTSTATUS_CQD = 0x00000040,
-+ CI_INTSTATUS_PAR_ERR = 0x00000080,
-+ CI_INTSTATUS_EOL = 0x00000100,
-+ CI_INTSTATUS_FEMPTY_0 = 0x00000200,
-+ CI_INTSTATUS_FEMPTY_1 = 0x00000400,
-+ CI_INTSTATUS_FEMPTY_2 = 0x00000800,
-+ CI_INTSTATUS_RDAV_0 = 0x00001000,
-+ CI_INTSTATUS_RDAV_1 = 0x00002000,
-+ CI_INTSTATUS_RDAV_2 = 0x00004000,
-+ CI_INTSTATUS_FTO = 0x00008000,
-+ CI_INTSTATUS_ALL = 0x0000FFFF
-+} CI_INTERRUPT_STATUS;
-+
-+typedef enum {
-+ CI_INT_IFO = 0x00000001,
-+ CI_INT_EOF = 0x00000002,
-+ CI_INT_SOF = 0x00000004,
-+ CI_INT_CDD = 0x00000008,
-+ CI_INT_CQD = 0x00000010,
-+ CI_INT_PAR_ERR = 0x00000020,
-+ CI_INT_EOL = 0x00000040,
-+ CI_INT_FEMPTY = 0x00000080,
-+ CI_INT_RDAV = 0x00000100,
-+ CI_INT_FTO = 0x00000200,
-+ CI_INT_ALL = 0x000003FF
-+} CI_INTERRUPT_MASK;
-+#define CI_INT_MAX 10
-+
-+typedef enum CI_MODE {
-+ CI_MODE_MP, // Master-Parallel
-+ CI_MODE_SP, // Slave-Parallel
-+ CI_MODE_MS, // Master-Serial
-+ CI_MODE_EP, // Embedded-Parallel
-+ CI_MODE_ES // Embedded-Serial
-+} CI_MODE;
-+
-+
-+typedef enum {
-+ CI_FR_ALL = 0, // Capture all incoming frames
-+ CI_FR_1_2, // Capture 1 out of every 2 frames
-+ CI_FR_1_3, // Capture 1 out of every 3 frames
-+ CI_FR_1_4,
-+ CI_FR_1_5,
-+ CI_FR_1_6,
-+ CI_FR_1_7,
-+ CI_FR_1_8
-+} CI_FRAME_CAPTURE_RATE;
-+
-+
-+typedef enum {
-+ CI_FIFO_THL_32 = 0,
-+ CI_FIFO_THL_64,
-+ CI_FIFO_THL_96
-+} CI_FIFO_THRESHOLD;
-+
-+typedef struct {
-+ unsigned int BFW;
-+ unsigned int BLW;
-+} CI_MP_TIMING, CI_MS_TIMING;
-+
-+typedef struct {
-+ unsigned int BLW;
-+ unsigned int ELW;
-+ unsigned int HSW;
-+ unsigned int BFPW;
-+ unsigned int FSW;
-+ unsigned int BFW;
-+ unsigned int EFW;
-+ unsigned int VSW;
-+} CI_SP_TIMING;
-+
-+typedef enum {
-+ CI_DATA_WIDTH4 = 0x0,
-+ CI_DATA_WIDTH5 = 0x1,
-+ CI_DATA_WIDTH8 = 0x2,
-+ CI_DATA_WIDTH9 = 0x3,
-+ CI_DATA_WIDTH10= 0x4
-+} CI_DATA_WIDTH;
-+
-+//-------------------------------------------------------------------------------------------------------
-+// Configuration APIs
-+//-------------------------------------------------------------------------------------------------------
-+
-+void ci_set_frame_rate(CI_FRAME_CAPTURE_RATE frate);
-+CI_FRAME_CAPTURE_RATE ci_get_frame_rate();
-+void ci_set_image_format(CI_IMAGE_FORMAT input_format, CI_IMAGE_FORMAT output_format);
-+void ci_set_mode(CI_MODE mode, CI_DATA_WIDTH data_width);
-+void ci_configure_mp(unsigned int PPL, unsigned int LPF, CI_MP_TIMING* timing);
-+void ci_configure_sp(unsigned int PPL, unsigned int LPF, CI_SP_TIMING* timing);
-+void ci_configure_ms(unsigned int PPL, unsigned int LPF, CI_MS_TIMING* timing);
-+void ci_configure_ep(int parity_check);
-+void ci_configure_es(int parity_check);
-+void ci_set_clock(unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz);
-+void ci_set_polarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low);
-+void ci_set_fifo( unsigned int timeout, CI_FIFO_THRESHOLD threshold, int fifo1_enable,
-+ int fifo2_enable);
-+void ci_set_int_mask( unsigned int mask);
-+void ci_clear_int_status( unsigned int status);
-+void ci_set_reg_value( unsigned int reg_offset, unsigned int value);
-+int ci_get_reg_value(unsigned int reg_offset);
-+
-+void ci_reset_fifo(void);
-+unsigned int ci_get_int_mask(void);
-+unsigned int ci_get_int_status(void);
-+void ci_slave_capture_enable(void);
-+void ci_slave_capture_disable(void);
-+
-+//-------------------------------------------------------------------------------------------------------
-+// Control APIs
-+//-------------------------------------------------------------------------------------------------------
-+int ci_init(void);
-+void ci_deinit(void);
-+void ci_enable( int dma_en);
-+int ci_disable(int quick);
-+
-+//debug
-+void ci_dump(void);
-+// IRQ
-+void pxa_camera_irq(int irq, void *dev_id, struct pt_regs *regs);
-+
-+#endif
-diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/e680_camera.c linux-2.6.16.5-exz/drivers/media/video/e680_camera.c ---- linux-2.6.16.5/drivers/media/video/e680_camera.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/e680_camera.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,144 @@ -+ -+ -+/*================================================================================ -+ -+ Header Name: e680_camera.c -+ -+General Description: Camera module interface source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 04/15/2004 Created -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+#include <linux/types.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+ -+#include <asm/pgtable.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+ -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+#include <linux/videodev.h> -+#include <linux/pci.h> -+#include <linux/pm.h> -+#include <linux/poll.h> -+#include <linux/wait.h> -+ -+#include "camera.h" -+#include "adcm2700.h" -+ -+#define MCLK_DEFT 13 /* Default Master clock*/ -+ -+extern int i2c_adcm2700_init(void); -+extern int i2c_mt9v111_init(void); -+////////////////////////////////////////////////////////////////////////////////////// -+//adcm2700 functions -+// -+int camera_func_adcm2700_init(p_camera_context_t); -+int camera_func_adcm2700_deinit(p_camera_context_t); -+int camera_func_adcm2700_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param); -+int camera_func_adcm2700_set_capture_format(p_camera_context_t); -+int camera_func_adcm2700_start_capture(p_camera_context_t, unsigned int frames); -+int camera_func_adcm2700_stop_capture(p_camera_context_t); -+ -+int camera_func_adcm2700_pm_management(p_camera_context_t, int); -+ -+////////////////////////////////////////////////////////////////////////////////////// -+//mt9v111 functions -+// -+int camera_func_mt9v111_init(p_camera_context_t); -+int camera_func_mt9v111_deinit(p_camera_context_t); -+int camera_func_mt9v111_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param); -+int camera_func_mt9v111_set_capture_format(p_camera_context_t); -+int camera_func_mt9v111_start_capture(p_camera_context_t, unsigned int frames); -+int camera_func_mt9v111_stop_capture(p_camera_context_t); -+ -+int camera_func_mt9v111_pm_management(p_camera_context_t, int); -+ -+ -+extern int camera_func_init(p_camera_context_t cam_ctx); -+ -+ -+camera_function_t camera_func = -+{ -+ init: camera_func_init, -+}; -+ -+int camera_func_init(p_camera_context_t cam_ctx) -+{ -+ // Configure CI according to hardware -+ // master parallel with 8 data pins -+ ci_set_mode(CI_MODE_MP, CI_DATA_WIDTH8); -+ -+ // enable pixel clock(sensor will provide pclock) and master clock = 26MHZ -+ ci_set_clock(cam_ctx->clk_reg_base, 1, 1, MCLK_DEFT); -+ -+ // data sample on rising and h,vsync active high -+ ci_set_polarity(0, 0, 0); -+ -+ // fifo control -+ ci_set_fifo(0, CI_FIFO_THL_32, 1, 1); // quality -+ -+ // Turn on M_CLK using xx MHz and wait for 150 ms. -+ ci_enable(1); -+ mdelay(150); -+ -+ cam_ctx->mclk = MCLK_DEFT; -+ dbg_print("detect..."); -+ if(i2c_adcm2700_init() == 0) -+ { -+ dbg_print("Agilent ADCM2700 camera module detected!"); -+ cam_ctx->sensor_type = CAMERA_TYPE_ADCM_2700; -+ -+ camera_func.deinit = camera_func_adcm2700_deinit; -+ camera_func.command = camera_func_adcm2700_docommand; -+ camera_func.set_capture_format = camera_func_adcm2700_set_capture_format; -+ camera_func.start_capture = camera_func_adcm2700_start_capture; -+ camera_func.stop_capture = camera_func_adcm2700_stop_capture; -+ camera_func.pm_management = camera_func_adcm2700_pm_management; -+ -+ return camera_func_adcm2700_init(cam_ctx); -+ } -+ else if(i2c_mt9v111_init() == 0) -+ { -+ dbg_print("Micro MT9V111 camera module detected!"); -+ cam_ctx->sensor_type = CAMERA_TYPE_MT9V111; -+ -+ camera_func.deinit = camera_func_mt9v111_deinit; -+ camera_func.command = camera_func_mt9v111_docommand; -+ camera_func.set_capture_format = camera_func_mt9v111_set_capture_format; -+ camera_func.start_capture = camera_func_mt9v111_start_capture; -+ camera_func.stop_capture = camera_func_mt9v111_stop_capture; -+ camera_func.pm_management = camera_func_mt9v111_pm_management; -+ -+ return camera_func_mt9v111_init(cam_ctx); -+ } -+ return -1; -+} -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/mt9m111.c linux-2.6.16.5-exz/drivers/media/video/mt9m111.c ---- linux-2.6.16.5/drivers/media/video/mt9m111.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/mt9m111.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,795 @@ -+ -+/*================================================================================ -+ -+ Header Name: mt9m111.c -+ -+General Description: Camera module mt9m111 interface source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+Ma Zhiqiang 06/29/2004 Change for auto-detect -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+#include <linux/types.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+ -+#include <asm/pgtable.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+ -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+#include <linux/videodev.h> -+#include <linux/pci.h> -+#include <linux/pm.h> -+#include <linux/poll.h> -+#include <linux/wait.h> -+ -+#include "camera.h" -+#include "mt9m111.h" -+#include "mt9m111_hw.h" -+ -+//#define LOG_TIME_STAMP //If defined, the time stamp log will be printed out -+//#define MT9M111_LOG //If defined, the mt9m111_mt9m111_dbg_print logs will be printed out -+//#define MT9M111_ECHO_CMD //If defined, the "echo {address, value} > cam" commands will be enabled. -+ -+#ifdef MT9M111_LOG -+#define mt9m111_dbg_print(fmt, args...) dbg_print(fmt, ##args) -+#else -+#define mt9m111_dbg_print(fmt, args...) ; -+#endif -+ -+#define MCLK_DEFT (24) /* Default Master clock*/ -+#define MSCWR1_CAMERA_ON (0x1 << 15) /* Camera Interface Power Control */ -+#define MSCWR1_CAMERA_SEL (0x1 << 14) /* Camera Interface Mux control */ -+ -+#define MAX_WIDTH 1280 -+#define MAX_HEIGHT 1024 -+ -+#define MIN_WIDTH 40 -+#define MIN_HEIGHT 30 -+ -+#define VIEW_FINDER_WIDTH_DEFT 320 -+#define VIEW_FINDER_HEIGHT_DEFT 240 -+ -+#define FRAMERATE_DEFT 15 -+#define BUF_SIZE_DEFT ((PAGE_ALIGN(MAX_WIDTH * MAX_HEIGHT) + (PAGE_ALIGN(MAX_WIDTH*MAX_HEIGHT/2)*2))) -+ -+extern int mt9m111_read(u16 addr, u16 *pvalue); -+extern int mt9m111_write(u16 addr, u16 value); -+extern int i2c_mt9m111_cleanup(void); -+extern int i2c_mt9m111_init(void); -+ -+extern void stop_dma_transfer(p_camera_context_t camera_context); -+extern int camera_ring_buf_init(p_camera_context_t camera_context); -+extern void camera_gpio_init(void); -+extern void camera_gpio_deinit(void); -+extern void start_dma_transfer(p_camera_context_t camera_context, unsigned block_id); -+ -+/*********************************************************************** -+ * -+ * MT9M111 Functions -+ * -+ ***********************************************************************/ -+int camera_func_mt9m111_init(p_camera_context_t); -+int camera_func_mt9m111_deinit(p_camera_context_t); -+int camera_func_mt9m111_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param); -+int camera_func_mt9m111_set_capture_format(p_camera_context_t); -+int camera_func_mt9m111_start_capture(p_camera_context_t, unsigned int frames); -+int camera_func_mt9m111_stop_capture(p_camera_context_t); -+int camera_func_mt9m111_pm_management(p_camera_context_t, int); -+ -+ -+camera_function_t mt9m111_func = -+{ -+ init: camera_func_mt9m111_init, -+ deinit: camera_func_mt9m111_deinit, -+ command: camera_func_mt9m111_docommand, -+ set_capture_format: camera_func_mt9m111_set_capture_format, -+ start_capture: camera_func_mt9m111_start_capture, -+ stop_capture: camera_func_mt9m111_stop_capture, -+ pm_management: camera_func_mt9m111_pm_management -+}; -+ -+int camera_func_mt9m111_init( p_camera_context_t cam_ctx ) -+{ -+ u16 device_id = 0 ; -+ -+ // init context status -+ cam_ctx->dma_channels[0] = 0xFF; -+ cam_ctx->dma_channels[1] = 0xFF; -+ cam_ctx->dma_channels[2] = 0xFF; -+ -+ cam_ctx->capture_width = VIEW_FINDER_WIDTH_DEFT; -+ cam_ctx->capture_height = VIEW_FINDER_HEIGHT_DEFT; -+ -+ cam_ctx->capture_input_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ cam_ctx->capture_output_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ -+ cam_ctx->frame_rate = cam_ctx->fps = FRAMERATE_DEFT; -+ -+ cam_ctx->mini_fps = FRAMERATE_DEFT; -+ -+ cam_ctx->mclk = MCLK_DEFT; -+ -+ cam_ctx->buf_size = BUF_SIZE_DEFT; -+ cam_ctx->dma_descriptors_size = (cam_ctx->buf_size/PAGE_SIZE + 10); -+ strcpy (cam_ctx->vc.name, "Micron MT9M111"); -+ cam_ctx->vc.maxwidth = MAX_WIDTH; -+ cam_ctx->vc.maxheight = MAX_HEIGHT; -+ cam_ctx->vc.minwidth = MIN_WIDTH; -+ cam_ctx->vc.minheight = MIN_HEIGHT; -+ -+ camera_gpio_init(); -+ ci_init(); -+ -+ // Configure CI according to MT9M111's hardware -+ // master parallel with 8 data pins -+ ci_set_mode(CI_MODE_MP, CI_DATA_WIDTH8); -+ -+ // enable pixel clock(sensor will provide pclock) -+ ci_set_clock(cam_ctx->clk_reg_base, 1, 1, cam_ctx->mclk); -+ -+ // data sample on rising and h,vsync active high -+ ci_set_polarity(1, 0, 0); -+ -+ // fifo control -+ ci_set_fifo(0, CI_FIFO_THL_32, 1, 1); // quality -+ -+ // Turn on M_CLK and wait for 150 ms. -+ ci_enable(1); -+ //mdelay(150); -+ -+ i2c_mt9m111_init(); -+ -+ // read out device id -+ mt9m111_get_device_id(&device_id); -+ if(device_id != 0x1419 && device_id != 0x1429 && device_id != 0x143A) -+ { -+ //ci_disable(1); -+ //camera_gpio_deinit(); -+ return -1; -+ } -+ else -+ { -+ mt9m111_dbg_print("Micron MT9M111 camera module detected!"); -+ } -+ -+ -+ /* To resolve the vertical line in view finder issue (LIBff11930) -+ * The solution is: -+ * AP Kernel camera driver: set TCMM_EN to low when camera is running and TCMM_EN to high when camera stops. -+ * BP Software: if TCMM_EN is low, BP do not shut off 26M clock ,but BP can sleep itself.*/ -+ -+ set_GPIO_mode(99|GPIO_OUT);//It's GPIO99 for the "TCMM_EN" -+ GPCR(99) = GPIO_bit(99); -+ -+ cam_ctx->sensor_type = CAMERA_TYPE_MT9M111; -+ -+ mt9m111_default_settings(); -+ -+ mt9m111_dbg_print("mt9m111 init success!"); -+ -+#ifdef MT9M111_ECHO_CMD -+ /*for test commmand throught terminal*/ -+ struct proc_dir_entry *pw; -+ static ssize_t test_command_write(struct file *file, const char *buf, size_t count, loff_t *pos); -+ -+ static struct file_operations test_command_funcs = -+ { -+ read:NULL, -+ write:test_command_write, -+ }; -+ -+ if ((pw = create_proc_entry ("cam", 0666, 0)) != NULL) -+ { -+ pw->proc_fops = &test_command_funcs; -+ } -+#endif -+ return 0; -+} -+ -+static void mt9m111_gpio_deinit(void) -+{ -+ GPSR(CIF_PD) = GPIO_bit(CIF_PD); -+} -+ -+int camera_func_mt9m111_deinit( p_camera_context_t camera_context ) -+{ -+ mt9m111_write(0x1B3, 0); -+ mdelay(5); -+ -+ i2c_mt9m111_cleanup(); -+ -+ /* disable CI */ -+ ci_disable(1); -+ -+ mt9m111_gpio_deinit(); -+ -+#ifdef MT9M111_ECHO_CMD -+ /*for test commmand throught terminal*/ -+ remove_proc_entry ("cam", NULL); -+#endif -+ -+ /* To resolve the vertical line in view finder issue (LIBff11930) -+ * The solution is: -+ * AP Kernel camera driver: set TCMM_EN to low when camera is running and TCMM_EN to high when camera stops. -+ * BP Software: if TCMM_EN is low, BP do not shut off 26M clock ,but BP can sleep itself.*/ -+ -+ set_GPIO_mode(99|GPIO_OUT);//It's GPIO99 for the "TCMM_EN" -+ GPSR(99) = GPIO_bit(99); -+ -+ return 0; -+} -+ -+int camera_func_mt9m111_set_capture_format( p_camera_context_t camera_context ) -+{ -+ micron_window_size wsize; -+ u16 micron_format; -+ mt9m111_dbg_print(""); -+ -+ // set sensor input/output window -+ wsize.width = camera_context->capture_width; -+ wsize.height = camera_context->capture_height; -+ mt9m111_output_size(&wsize); -+ -+ // set sensor format -+ switch(camera_context->capture_input_format) { -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ micron_format = O_FORMAT_422_YCbYCr; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ micron_format = O_FORMAT_565_RGB; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB555: -+ micron_format = O_FORMAT_555_RGB; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB444: -+ micron_format = O_FORMAT_444_RGB; -+ break; -+ default: -+ micron_format = O_FORMAT_422_YCbYCr; -+ break; -+ } -+ mt9m111_output_format(micron_format); -+ -+ return 0; -+} -+ -+int camera_func_mt9m111_start_capture( p_camera_context_t cam_ctx, unsigned int frames ) -+{ -+ int waitingFrame = 0; -+ -+#ifdef LOG_TIME_STAMP -+ struct timeval tv0,tv1,tv2,tv3,tv4; -+ do_gettimeofday(&tv0); -+#endif -+ -+ ci_reset_fifo(); -+ ci_clear_int_status(0xFFFFFFFF); -+ -+ // frames=0 means video mode capture -+ if (frames == 0) -+ { -+ mt9m111_dbg_print("video capture!"); -+ mt9m111_viewfinder_on(); -+ } -+ else -+ { -+ mt9m111_dbg_print("still capture"); -+ mt9m111_snapshot_trigger(); -+ } -+ -+#ifdef LOG_TIME_STAMP -+ do_gettimeofday(&tv1); -+#endif -+ -+ ci_disable(1); -+ ci_enable(1); -+ -+#ifdef LOG_TIME_STAMP -+ do_gettimeofday(&tv2); -+#endif -+ -+ if(frames == 1) //Wait 1 frames to begin capture photo -+ { -+ waitingFrame = 1; -+ } -+ else -+ { -+ waitingFrame = 1; -+ } -+ -+ while(waitingFrame--) -+ { -+ CISR |= (1<<4); -+ while(!(CISR&(1<<4))); //Wait a SOF then begin start DMA -+ } -+ -+#ifdef LOG_TIME_STAMP -+ do_gettimeofday(&tv3); -+#endif -+ -+ ci_disable(1); -+ ci_enable(1); -+ ci_reset_fifo(); -+ start_dma_transfer(cam_ctx, 0); -+ -+#ifdef LOG_TIME_STAMP -+ do_gettimeofday(&tv4); -+ -+ printk("mt9m111 capture: Begin time is sec: %d , msec: %d\n", tv0.tv_sec, tv0.tv_usec/1000); -+ printk("mt9m111 capture: End time is sec: %d , msec: %d\n", tv4.tv_sec, tv4.tv_usec/1000); -+ if(frames) -+ printk("mt9m111 capture: Total time(photo) is %d ms\n\n", (tv4.tv_sec-tv0.tv_sec)*1000+ (tv4.tv_usec-tv0.tv_usec)/1000); -+ else -+ printk("mt9m111 capture: Total time(preview) is %d ms\n\n", (tv4.tv_sec-tv0.tv_sec)*1000+ (tv4.tv_usec-tv0.tv_usec)/1000); -+ printk("mt9m111 capture: Write reg time is %d ms\n\n", (tv1.tv_sec-tv0.tv_sec)*1000+ (tv1.tv_usec-tv0.tv_usec)/1000); -+ printk("mt9m111 capture: Reset ci time is %d ms\n\n", (tv2.tv_sec-tv1.tv_sec)*1000+ (tv2.tv_usec-tv1.tv_usec)/1000); -+ printk("mt9m111 capture: Wait sof time is %d ms\n\n", (tv3.tv_sec-tv2.tv_sec)*1000+ (tv3.tv_usec-tv2.tv_usec)/1000); -+ printk("mt9m111 capture: Left time is %d ms\n\n", (tv4.tv_sec-tv3.tv_sec)*1000+ (tv4.tv_usec-tv3.tv_usec)/1000); -+#endif -+ return 0; -+} -+ -+int camera_func_mt9m111_stop_capture( p_camera_context_t camera_context ) -+{ -+ mt9m111_viewfinder_off(); -+ stop_dma_transfer(camera_context); -+ -+ /* disable CI */ -+ //ci_disable(1); -+ -+ return 0; -+} -+ -+static int camera_mt9m111_restore_settings(p_camera_context_t cam_ctx) -+{ -+ micron_window_size size; -+ -+ size.width = cam_ctx->sensor_width; -+ size.height = cam_ctx->sensor_height; -+ mt9m111_input_size(&size); -+ -+ size.width = cam_ctx->capture_width; -+ size.height = cam_ctx->capture_height; -+ mt9m111_output_size(&size); -+ -+ mt9m111_set_bright(cam_ctx->capture_bright); -+ -+ mt9m111_set_fps(cam_ctx->fps, cam_ctx->mini_fps); -+ mt9m111_set_light(cam_ctx->capture_light); -+ mt9m111_set_style(cam_ctx->capture_style); -+ //mt9m111_set_contrast(cam_ctx->capture_contrast); -+ mt9m111_set_autoexposure_zone(cam_ctx->mini_fps); -+ mt9m111_set_flicker(cam_ctx->flicker_freq); -+ -+ return 0; -+} -+ -+int camera_func_mt9m111_pm_management(p_camera_context_t cam_ctx, int suspend) -+{ -+ static int resume_dma = 0; -+ if(suspend) -+ { -+ if(cam_ctx != NULL ) -+ { -+ if(cam_ctx->dma_started) -+ { -+ mt9m111_dbg_print("camera running, suspended"); -+ stop_dma_transfer(cam_ctx); -+ resume_dma = 1; -+ } -+ } -+ -+ disable_irq(IRQ_CAMERA); -+ CKEN &= ~CKEN24_CAMERA; -+ } -+ else -+ { -+ CKEN |= CKEN24_CAMERA; -+ enable_irq(IRQ_CAMERA); -+ -+ if(cam_ctx != NULL) -+ { -+ mt9m111_dbg_print("camera running, resumed"); -+ camera_init(cam_ctx); -+ -+ camera_mt9m111_restore_settings(cam_ctx); -+ -+ if(resume_dma == 1) -+ { -+ camera_start_video_capture(cam_ctx, 0); -+ resume_dma = 0; -+ } -+ } -+ } -+ return 0; -+} -+ -+static int pxa_camera_WCAM_VIDIOCGCAMREG(p_camera_context_t cam_ctx, void * param) -+{ -+ int reg_value, offset; -+ mt9m111_dbg_print("WCAM_VIDIOCGCAMREG"); -+ if(copy_from_user(&offset, param, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ reg_value = (int)mt9m111_reg_read((u16)offset); -+ -+ if(copy_to_user(param, ®_value, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+static int pxa_camera_WCAM_VIDIOCSCAMREG(p_camera_context_t cam_ctx, void * param) -+{ -+ struct reg_set_s{int val1; int val2;} reg_s; -+ mt9m111_dbg_print("WCAM_VIDIOCSCAMREG"); -+ -+ if(copy_from_user(®_s, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ mt9m111_reg_write((u16)reg_s.val1, (u16)reg_s.val2); -+ return 0; -+} -+ -+static int pxa_cam_WCAM_VIDIOCSFPS(p_camera_context_t cam_ctx, void * param) -+{ -+ struct {int fps, minfps;} cam_fps; -+ mt9m111_dbg_print("WCAM_VIDIOCSFPS"); -+ if(copy_from_user(&cam_fps, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ cam_ctx->fps = cam_fps.fps; -+ cam_ctx->mini_fps = cam_fps.minfps; -+ mt9m111_set_fps(cam_fps.fps, cam_fps.minfps); -+ return 0; -+} -+ -+ -+/*Set sensor size*/ -+static int pxa_cam_WCAM_VIDIOCSSSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ micron_window_size size; -+ mt9m111_dbg_print("WCAM_VIDIOCSSSIZE"); -+ -+ if(copy_from_user(&size, param, sizeof(micron_window_size))) -+ { -+ return -EFAULT; -+ } -+ -+ size.width = (size.width+3)/4 * 4; -+ size.height = (size.height+3)/4 * 4; -+ cam_ctx->sensor_width = size.width; -+ cam_ctx->sensor_height = size.height; -+ mt9m111_input_size(&size); -+ return 0; -+} -+ -+//set output size -+static int pxa_cam_WCAM_VIDIOCSOSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ micron_window_size size; -+ CI_MP_TIMING timing; -+ mt9m111_dbg_print("WCAM_VIDIOCSOSIZE"); -+ -+ if(copy_from_user(&size, param, sizeof(micron_window_size))) -+ { -+ return -EFAULT; -+ } -+ -+ //make it in an even number -+ size.width = (size.width+1)/2 * 2; -+ size.height = (size.height+1)/2 * 2; -+ mt9m111_output_size(&size); -+ -+ cam_ctx->capture_width = size.width; -+ cam_ctx->capture_height = size.height; -+ timing.BFW = timing.BLW = 0; -+ -+ ci_configure_mp(cam_ctx->capture_width-1, cam_ctx->capture_height-1, &timing); -+ camera_ring_buf_init(cam_ctx); -+ -+ return 0; -+} -+ -+/*set picture style*/ -+static int pxa_cam_WCAM_VIDIOCSSTYLE(p_camera_context_t cam_ctx, void * param) -+{ -+ mt9m111_dbg_print("WCAM_VIDIOCSSTYLE"); -+ cam_ctx->capture_style = (V4l_PIC_STYLE)param; -+ -+ return mt9m111_set_style(cam_ctx->capture_style); -+} -+ -+/*set picture light*/ -+static int pxa_cam_WCAM_VIDIOCSLIGHT(p_camera_context_t cam_ctx, void * param) -+{ -+ mt9m111_dbg_print("WCAM_VIDIOCSLIGHT"); -+ cam_ctx->capture_light = (V4l_PIC_WB)param; -+ -+ return mt9m111_set_light((V4l_PIC_WB)param); -+} -+ -+/*set picture brightness*/ -+static int pxa_cam_WCAM_VIDIOCSBRIGHT(p_camera_context_t cam_ctx, void * param) -+{ -+ mt9m111_dbg_print("WCAM_VIDIOCSBRIGHT"); -+ cam_ctx->capture_bright = (int)param; -+ -+ return mt9m111_set_bright((int)param); -+} -+ -+/*set picture contrast*/ -+/*static int pxa_cam_WCAM_VIDIOCSCONTRAST(p_camera_context_t cam_ctx, void * param) -+{ -+ mt9m111_dbg_print("WCAM_VIDIOCSCONTRAST"); -+ cam_ctx->capture_contrast = ((int)param-50)/12; -+ -+ return mt9m111_set_contrast(cam_ctx->capture_contrast); -+}*/ -+ -+/*set flicker frequency*/ -+static int pxa_cam_WCAM_VIDIOCSFLICKER(p_camera_context_t cam_ctx, void * param) -+{ -+ mt9m111_dbg_print("WCAM_VIDIOCSFLICKER"); -+ cam_ctx->flicker_freq = (int)param; -+ -+ return mt9m111_set_flicker(cam_ctx->flicker_freq); -+} -+ -+ -+/*set night mode*/ -+static int pxa_cam_WCAM_VIDIOCSNIGHTMODE(p_camera_context_t cam_ctx, void * param) -+{ -+ struct {u32 mode, maxexpotime; } cam_mode; -+ u32 maxexpotime; -+ -+ if (copy_from_user(&cam_mode, param, sizeof(cam_mode))) -+ { -+ return -EFAULT; -+ } -+ -+ maxexpotime = cam_mode.maxexpotime; -+ if(maxexpotime == 0) -+ { -+ return -EFAULT; -+ } -+ -+ switch (cam_mode.mode) -+ { -+ case V4l_NM_NIGHT: -+ case V4l_NM_ACTION: -+ case V4l_NM_AUTO: -+ cam_ctx->mini_fps = (1000000+maxexpotime/2)/maxexpotime; -+ mt9m111_set_autoexposure_zone(cam_ctx->mini_fps); -+ break; -+ default: -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+int camera_func_mt9m111_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param) -+{ -+ switch(cmd) -+ { -+ /*read mt9m111 registers*/ -+ case WCAM_VIDIOCGCAMREG: -+ return pxa_camera_WCAM_VIDIOCGCAMREG(cam_ctx, param); -+ -+ /*write mt9m111 registers*/ -+ case WCAM_VIDIOCSCAMREG: -+ return pxa_camera_WCAM_VIDIOCSCAMREG(cam_ctx, param); -+ -+ /*set sensor size */ -+ case WCAM_VIDIOCSSSIZE: -+ return pxa_cam_WCAM_VIDIOCSSSIZE(cam_ctx, param); -+ -+ /*set output size*/ -+ case WCAM_VIDIOCSOSIZE: -+ return pxa_cam_WCAM_VIDIOCSOSIZE(cam_ctx, param); -+ -+ /*set video mode fps*/ -+ case WCAM_VIDIOCSFPS: -+ return pxa_cam_WCAM_VIDIOCSFPS(cam_ctx, param); -+ -+ /*set picture style*/ -+ case WCAM_VIDIOCSSTYLE: -+ return pxa_cam_WCAM_VIDIOCSSTYLE(cam_ctx, param); -+ -+ /*set picture light*/ -+ case WCAM_VIDIOCSLIGHT: -+ return pxa_cam_WCAM_VIDIOCSLIGHT(cam_ctx, param); -+ -+ /*set picture brightness*/ -+ case WCAM_VIDIOCSBRIGHT: -+ return pxa_cam_WCAM_VIDIOCSBRIGHT(cam_ctx, param); -+ -+ /*set picture contrast*/ -+ //case WCAM_VIDIOCSCONTRAST: -+ // return pxa_cam_WCAM_VIDIOCSCONTRAST(cam_ctx, param); -+ -+ /*set flicker frequency*/ -+ case WCAM_VIDIOCSFLICKER: -+ return pxa_cam_WCAM_VIDIOCSFLICKER(cam_ctx, param); -+ -+ case WCAM_VIDIOCSNIGHTMODE: -+ return pxa_cam_WCAM_VIDIOCSNIGHTMODE(cam_ctx, param); -+ -+ default: -+ { -+ mt9m111_dbg_print("Error cmd=0x%x", cmd); -+ return -1; -+ } -+ } -+ return 0; -+ -+} -+ -+#ifdef MT9M111_ECHO_CMD -+/*********************************************************************** -+ * -+ * MT9M111 test command throught terminal -+ * -+ ***********************************************************************/ -+ -+#define MIN(a, b) ((a) < (b) ? (a) : (b)) -+#define MAX_WRITE_LEN 12 -+ -+extern int mt9m111_write(u16 addr, u16 value); -+ -+static ssize_t test_command_write (struct file *file, const char *buf, size_t count, loff_t * pos) -+{ -+ char feedback[2*MAX_WRITE_LEN + 1] ={0}; -+ char feedback1[2*MAX_WRITE_LEN + 1] = {0}; -+ size_t n = count; -+ size_t l; -+ char c; -+ int i,x,y,t; -+ -+ u16 reg, value; -+ -+ MOD_INC_USE_COUNT; -+ -+ if (n > 0) -+ { -+ l = MIN (n, MAX_WRITE_LEN); -+ if (copy_from_user (feedback, buf, l)) -+ { -+ count = -1; -+ } -+ else -+ { -+ if (l > 0 && feedback[l - 1] == '\n') -+ { -+ l -= 1; -+ } -+ feedback[l] = 0; -+ n -= l; -+ -+ while (n > 0) -+ { -+ if (copy_from_user (&c, buf + (count - n), 1)) -+ { -+ count = -1; -+ break; -+ } -+ n -= 1; -+ } -+ } -+ } -+ -+ i = x = y = 1; -+ -+ if (count > 0 && feedback[0] == '{') -+ { -+ while(feedback[i] != '}' && i<=MAX_WRITE_LEN*2) -+ { -+ c= feedback[i]; -+ i++; -+ if(c>='a' && c<='f') -+ { -+ c -= 0x20; -+ } -+ if(!((c>='0'&& c<='9')||(c>='A'&&c<='F')||c==',')) -+ { -+ continue; -+ } -+ feedback1[x++] = c; -+ } -+ -+ feedback1[x]='}'; -+ feedback1[0]='{'; -+ -+ for(i=1;i<=x;i++) -+ { -+ if(feedback1[i] == ',') -+ { -+ y=3; -+ for(t=i-1;t>=1;t--) -+ { -+ if(y==0) -+ break; -+ feedback[y--]=feedback1[t]; -+ } -+ if(y>=1) -+ { -+ for(t=y;t>=1;t--) -+ { -+ feedback[t] = '0'; -+ } -+ } -+ } -+ -+ if(feedback1[i] == '}') -+ { -+ y=8; -+ for(t=i-1;feedback1[t]!=','&&t>=1;t--) -+ { -+ if(y==4) -+ break; -+ feedback[y--]=feedback1[t]; -+ } -+ if(y>=5) -+ { -+ for(t=y;t>=5;t--) -+ { -+ feedback[t] = '0'; -+ } -+ } -+ } -+ } -+ -+ reg = 16 * 16 * (feedback[1]>='A'?feedback[1]-'A'+10:feedback[1]-0x30) + 16 * (feedback[2]>='A'?feedback[2]-'A'+10:feedback[2]-0x30) + (feedback[3]>='A'?feedback[3]-'A'+10:feedback[3]-0x30) ; -+ value = 16 * 16 * 16 * (feedback[5]>='A'?feedback[5]-'A'+10:feedback[5]-0x30) + 16 *16* (feedback[6]>='A'?feedback[6]-'A'+10:feedback[6]-0x30) + 16 * (feedback[7]>='A'?feedback[7]-'A'+10:feedback[7]-0x30) + (feedback[8]>='A'?feedback[8]-'A'+10:feedback[8]-0x30) ; -+ -+ if(reg == 0xFFF && value == 0xFFFF) -+ { -+ mt9m111_dump_register(0,0x2ff,NULL); -+ } -+ else if(reg == 0xFFF || reg == 0xFF) -+ { -+ mt9m111_reg_read(value); -+ } -+ else -+ { -+ mt9m111_write(reg, value); -+ } -+ } -+ -+ MOD_DEC_USE_COUNT; -+ -+ return (count); -+} -+#endif -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/mt9m111.h linux-2.6.16.5-exz/drivers/media/video/mt9m111.h ---- linux-2.6.16.5/drivers/media/video/mt9m111.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/mt9m111.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,44 @@ -+ -+/*================================================================================ -+ -+ Header Name: mt9m111.h -+ -+General Description: Camera module mt9m111 interface head file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+Ma Zhiqiang 6/30/2004 Change for auto-detect -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+ -+#ifndef _MT9M111_H_ -+#define _MT9M111_H_ -+ -+#include "camera.h" -+ -+////////////////////////////////////////////////////////////////////////////////////// -+// -+// Prototypes -+// -+////////////////////////////////////////////////////////////////////////////////////// -+ -+int camera_func_mt9m111_init(p_camera_context_t); -+int camera_func_mt9m111_deinit(p_camera_context_t); -+int camera_func_mt9m111_set_capture_format(p_camera_context_t); -+int camera_func_mt9m111_start_capture(p_camera_context_t, unsigned int frames); -+int camera_func_mt9m111_stop_capture(p_camera_context_t); -+int camera_func_mt9m111_pm_management(p_camera_context_t cam_ctx, int suspend); -+int camera_func_mt9m111_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param); -+ -+#endif /* _MT9M111_H_ */ -+ -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/mt9m111_hw.c linux-2.6.16.5-exz/drivers/media/video/mt9m111_hw.c ---- linux-2.6.16.5/drivers/media/video/mt9m111_hw.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/mt9m111_hw.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,994 @@ -+/*================================================================================ -+ -+ Header Name: mt9m111_hw.c -+ -+General Description: Camera module mt9m111 interface source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+Ma Zhiqiang 6/30/2004 Change for auto-detect -+Ma Zhiqiang 9/03/2004 Add the update from Peter -+ (worked out with Micron/Flextronix and LV CTO team) -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+#include <linux/types.h> -+#include <asm/mach-types.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+ -+#include <linux/types.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/wrapper.h> -+#include <linux/delay.h> -+#include <linux/i2c.h> -+ -+#include "mt9m111_hw.h" -+#include "camera.h" -+ -+//#define MT9M111_LOG -+ -+#ifdef MT9M111_LOG -+#define mt9m111_dbg_print(fmt, args...) dbg_print(fmt, ##args) -+#else -+#define mt9m111_dbg_print(fmt, args...) ; -+#endif -+ -+extern int mt9m111_read(u16 addr, u16 *pvalue); -+extern int mt9m111_write(u16 addr, u16 value); -+ -+static u16 outWidth = 320; -+static u16 outHeight = 240; -+static u16 sensorWidth = 1280; -+static u16 sensorHeight = 1024; -+ -+static u16 preferredFlickerMask = 0; -+static int inSkipMode = 1; -+static int didSnapPhoto = 0; -+static u16 minFPS = -1; -+static u16 maxFPS = -1; -+ -+static u8 isHalfSensorSize = 0; -+ -+// light tables -+ -+#if 0 -+// table generated by Micron's default calibration -+ -+// auto -+static u16 autoLight[] = -+{ 0x00AE, 0x2923, 0x04E4, 0x00B7, 0x009F, 0x0068, 0x00C5, 0x0088, -+ 0x0027, 0x007A, 0x0088, 0x00AF, 0x00C9, 0x0014, 0x0005, 0x0033, -+ 0x0031, 0x0004, 0x0052, 0x0057, 0x0091, 0x005B, 0x6345, 0x3E26, -+ 0x0002 }; -+ -+// direct sun -+static u16 directSun[] = -+{ 0x00AE, 0x2923, 0x0524, 0x00BF, 0x009B, 0x004A, 0x00AC, 0x008A, -+ 0x0051, 0x004F, 0x007E, 0x0082, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4458, 0x0000, -+ 0x0000 }; -+ -+// incandescent -+static u16 incandescentLight[] = -+{ 0x00A6, 0x2923, 0x04E4, 0x00A8, 0x0090, 0x007A, 0x00DC, 0x0083, -+ 0x0004, 0x00A7, 0x00CC, 0x00DB, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8232, 0x0000, -+ 0x0000 }; -+ -+// fluorescent -+static u16 tl84Light[] = -+{ 0x00A6, 0x2737, 0x04E4, 0x00AF, 0x006F, 0x003C, 0x008B, 0x0097, -+ 0x000F, 0x00D2, 0x00B5, 0x00DF, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8630, 0x0000, -+ 0x0000 }; -+ -+#endif -+ -+#if 1 -+// no lens cover ccmat -- Satish likes this one -+ -+/* -+static u16 autoLight[] = -+{ 0x00AE, 0x271B, 0x02A4, 0x00E9, 0x0082, 0x006D, 0x007A, 0x009C, -+ 0x0047, 0x0095, 0x0065, 0x006C, 0x00C9, 0x0010, 0x0007, 0x0027, -+ 0x001A, 0x0001, 0x004C, 0x0062, 0x0059, 0x0037, 0x6345, 0x3E26, -+ 0x0002 }; -+*/ -+// -+static u16 autoLight[] = -+{ 0x00AE, 0x2923, 0x04E4, 0x00C8, 0x00DF, 0x0080, 0x00C2, 0x0084, -+ 0x001F, 0x006B, 0x007F, 0x00AB, 0x00C9, 0x001F, 0x0002, 0x002F, -+ 0x0022, 0x000D, 0x005E, 0x002E, 0x007B, 0x0048, 0x604C, 0x3C28, -+ 0x0002 }; -+ -+static u16 incandescentLight[] = -+{ 0x00AE, 0x2723, 0x02A4, 0x00D8, 0x00EB, 0x0076, 0x0084, 0x0096, -+ 0x001E, 0x00C5, 0x008D, 0x0085, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8232, 0x0000, -+ 0x0000 }; -+ -+static u16 tl84Light[] = -+{ 0x00AE, 0x2723, 0x02A4, 0x00EB, 0x00D6, 0x002C, 0x00A8, 0x00B0, -+ 0x000E, 0x00F8, 0x0086, 0x008B, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8630, 0x0000, -+ 0x0000 }; -+ -+static u16 d65Light[] = -+{ 0x00AE, 0x291B, 0x0524, 0x00EF, 0x0082, 0x0054, 0x00D9, 0x009D, -+ 0x006E, 0x0064, 0x00E0, 0x00A1, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4458, 0x0000, -+ 0x0000 }; -+ -+#endif -+ -+#if 0 -+ -+// lens cover ccmat -- Satish doesn't like this one -+ -+static u16 autoLight[] = -+{ 0x00AE, 0x271A, 0x02A4, 0x007E, 0x0081, 0x003A, 0x0082, 0x00BB, -+ 0x00AD, 0x009B, 0x007D, 0x0079, 0x0099, 0x000C, 0x0025, 0x0011, -+ 0x0024, 0x0009, 0x001E, 0x007F, 0x0063, 0x003F, 0x6344, 0x3A28, -+ 0x0002 }; -+ -+static u16 incandescentLight[] = -+{ 0x00AE, 0x2723, 0x02A4, 0x00EF, 0x00DE, 0x0032, 0x0094, 0x00BF, -+ 0x009E, 0x00DA, 0x00AF, 0x0098, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8030, 0x0000, -+ 0x0000 }; -+ -+static u16 tl84Light[] = -+{ 0x00AE, 0x2723, 0x02A4, 0x00E9, 0x00EC, 0x0045, 0x0093, 0x0097, -+ 0x0001, 0x00DA, 0x0092, 0x008A, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8630, 0x0000, -+ 0x0000 }; -+ -+static u16 d65Light[] = -+{ 0x00AE, 0x291A, 0x04E4, 0x0082, 0x0092, 0x0042, 0x00DD, 0x00B4, -+ 0x00B9, 0x005A, 0x0096, 0x00B0, 0x0000, 0x0000, 0x0000, 0x0000, -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4658, 0x0000, -+ 0x0000 }; -+ -+#endif -+ -+ -+/***************************************************************************** -+* -+*****************************************************************************/ -+static void mt9m111_reset(void) -+{ -+ minFPS = -1; -+ maxFPS = -1; -+ inSkipMode = 1; -+ didSnapPhoto = 0; -+ isHalfSensorSize = 0; -+} -+ -+/***************************************************************************** -+* * -+* I2C Management * -+* * -+*****************************************************************************/ -+u16 mt9m111_reg_read(u16 reg_addr) -+{ -+ u16 value=0; -+ mt9m111_read(reg_addr, &value); -+ return value; -+} -+ -+void mt9m111_reg_write(u16 reg_addr, u16 reg_value) -+{ -+ mt9m111_write(reg_addr, reg_value); -+} -+ -+///////////////////////////////////////////////////////////////////////////////////// -+// -+// Programming Guide : Configuration Methods -+// -+///////////////////////////////////////////////////////////////////////////////////// -+ -+int mt9m111_get_device_id(u16 *id) -+{ -+ /*Device ID is in register 0x0 */ -+ *id = mt9m111_reg_read(0x0); -+ mt9m111_dbg_print("mt9m111 device ID is 0x%x", *id); -+ -+ return MICRON_ERR_NONE; -+} -+ -+static int mt9m111_update_size(int context) -+{ -+ mt9m111_dbg_print("mt9m111_update_size, sensor=%dx%d, out=%dx%d", sensorWidth, sensorHeight, outWidth, outHeight); -+ -+ /* set the sensor size */ -+ if(context == 0) -+ { -+ //context A -+ mt9m111_write(0x1A6, sensorWidth); -+ mt9m111_write(0x1A9, sensorHeight); -+ } -+ else -+ { -+ //context B -+ mt9m111_write(0x1A0, sensorWidth); -+ mt9m111_write(0x1A3, sensorHeight); -+ } -+ /* set output size */ -+ if(outWidth > sensorWidth) -+ { -+ outWidth = sensorWidth; -+ } -+ if(outHeight > sensorHeight) -+ { -+ outHeight = sensorHeight; -+ } -+ -+ if(context == 0) -+ { -+ //context A -+ mt9m111_write(0x1A7, outWidth); -+ mt9m111_write(0x1AA, outHeight); -+ } -+ else -+ { -+ //context B -+ mt9m111_write(0x1A1, outWidth); -+ mt9m111_write(0x1A4, outHeight); -+ } -+ -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_viewfinder_on() -+{ -+ mt9m111_dbg_print("mt9m111_viewfinder_on, sensor=%dx%d, out=%dx%d", sensorWidth, sensorHeight, outWidth, outHeight); -+ -+ if((outWidth*2 > sensorWidth) || (outHeight*2 > sensorHeight)) -+ { -+ mt9m111_dbg_print("mt9m111_viewfinder_on: making sure skip mode is off"); -+ -+ // make sure skip mode is off -+ -+ if (inSkipMode || didSnapPhoto) -+ { -+ mt9m111_dbg_print("mt9m111_viewfinder_on: skip mode is on -- turning in off"); -+ // -+ // set to full power, turn off subsampling -+ // switch to context B for read mode, full frame, and max line delay -+ // -+ -+ mt9m111_write(0x2D2, 0x0041); // turn off subsampling and turn on full power mode -+ mt9m111_write(0x2CC, 0x4); // Context Ctl Program Select -- use default program -+ u16 v = mt9m111_reg_read(0x2CB); // read Context Ctl Program Advance -+ mt9m111_write(0x2CB, v|1); // advance program -+ -+ didSnapPhoto = 0; -+ inSkipMode = 0; -+ -+ // -+ // after program advance, we need to poll Global Context Ctl to wait for -+ // sensor read mode context has switched to context B -+ // -+ -+ int count = 0; -+ while ((mt9m111_reg_read(0x00C8) != 0x000B) && (++count < 20)) -+ { -+ mdelay(10); -+ } -+ } -+ -+ mt9m111_update_size(0); -+ } -+ else -+ { -+ mt9m111_update_size(0); -+ -+ // make sure skip mode is on -+ -+ mt9m111_dbg_print("mt9m111_viewfinder_on: making sure skip mode is on"); -+ -+ if (!inSkipMode || didSnapPhoto) -+ { -+ mt9m111_dbg_print("mt9m111_viewfinder_on: skip mode is off -- turning in on"); -+ -+ // -+ // set to low power, turn on subsampling -+ // switch to context A for read mode, full frame, and max line delay -+ -+ mt9m111_write(0x2D2, 0x0000); // turn off subsampling and turn on full power mode -+ mt9m111_write(0x2CC, 0x4); // Context Ctl Program Select -- use default program -+ u16 v = mt9m111_reg_read(0x2CB); // read Context Ctl Program Advance -+ mt9m111_write(0x2CB, v|1); // advance program -+ -+ inSkipMode = 1; -+ didSnapPhoto = 0; -+ } -+ } -+ -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_viewfinder_off() -+{ -+ mt9m111_dbg_print("mt9m111_viewfinder_off"); -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_snapshot_trigger() -+{ -+ mt9m111_dbg_print("mt9m111_snapshot_trigger"); -+ -+ mt9m111_update_size(1); -+ -+ mt9m111_write(0x2D2, 0x007F); // Context return to default => all in context B -+ mt9m111_write(0x2CC, 0x0004); // Program Select = default => run program to default -+ u16 v = mt9m111_reg_read(0x2CB); -+ mt9m111_write(0x2CB, v | 1); // Program Advance = RUN/GO -+ -+ didSnapPhoto = 1; -+ -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_snapshot_complete() -+{ -+ mt9m111_dbg_print("mt9m111_snapshot_complete"); -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_input_size(micron_window_size * window) -+{ -+ sensorWidth = window->width; -+ sensorHeight = window->height; -+ -+ mt9m111_dbg_print("mt9m111_input_size, sensor=%dx%d", sensorWidth, sensorHeight); -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_output_size(micron_window_size * window) -+{ -+ outWidth = window->width; -+ outHeight = window->height; -+ -+ mt9m111_dbg_print("mt9m111_output_size, out=%dx%d", outWidth, outHeight); -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_get_input_size( micron_window_size * window) -+{ -+ window->width = mt9m111_reg_read(0x1A6); -+ window->height = mt9m111_reg_read(0x1A9); -+ -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_set_fps(u16 newMaxFPS, u16 newMinFPS) -+{ -+ mt9m111_dbg_print("mt9m111_set_fps: newMaxFPS=%d, newMinFPS=%d", newMaxFPS, newMinFPS); -+ -+ // -+ // clamp newMaxFPS to a legal range -+ // -+ -+ const int MIN_FPS = 5; -+ const int MAX_FPS = 15; -+ -+ newMaxFPS = (newMaxFPS > MAX_FPS) ? MAX_FPS : newMaxFPS; -+ newMaxFPS = (newMaxFPS < MIN_FPS) ? MIN_FPS : newMaxFPS; -+ -+ mt9m111_dbg_print("mt9m111_set_fps: newMaxFPS=%d, newMinFPS=%d", newMaxFPS, newMinFPS); -+ -+ // -+ // if the maxFPS has changed, update the vblank -+ // -+ -+ if (newMaxFPS != maxFPS) -+ { -+ -+ // -+ // enforce max fps by setting the vertical blanking -+ // -+ // The table below assumes: -+ // MCLK = 24.375 MHz -+ // target line time = 127 micro seconds -+ // HBLANK in low power = ??? -+ // HBLANK in full power = ??? -+ // -+ // The following values came from Micron during a site visit on 9/1. -+ // -+ // If the input clock changes, these settings also need to change. -+ // -+ // The basic idea is that a flicker-detection friendly framerate close -+ // to the requested frame rate is chosen. -+ // -+ -+ const u16 vblanksLowPower[] = -+ { -+ 1021, /* 5.11 */ -+ 701, /* 6.45 */ -+ 556, /* 7.32 */ -+ 412, /* 8.45 */ -+ 309, /* 9.5 */ -+ 233, /* 10.45 */ -+ 162, /* 11.55 */ -+ 123, /* 12.25 */ -+ 90, /* 12.91 */ -+ 50, /* 13.81 */ -+ 18 /* 14.645 */ -+ }; -+ -+ const u16 vblanksFullPower[] = -+ { -+ 509, /* 5.11 */ -+ 189, /* 6.45 */ -+ 44, /* 7.32 */ -+ 44, /* 7.32 */ -+ 44, /* 7.32 */ -+ 44, /* 7.32 */ -+ 44, /* 7.32 */ -+ 44, /* 7.32 */ -+ 44, /* 7.32 */ -+ 44, /* 7.32 */ -+ 44 /* 7.32 */ -+ }; -+ -+ // -+ // use the following hblanks to achieve a line rate of 127us -+ // -+ -+ const u16 readModeLowPower = 0x040C; -+ const u16 readModeFullPower = 0x0300; -+ const u16 hblankLowPower = 126; -+ const u16 hblankFullPower = 260; -+ const u16 aeLineSizeLowPower = 1548; -+ const u16 aeLineSizeFullPower = 1548; -+ const u16 aeShutterDelayLimitLowPower = 1548; -+ const u16 aeShutterDelayLimitFullPower = 1548; -+ const u16 aeFlickerFullFrameTime60HzLowPower = 262; -+ const u16 aeFlickerFullFrameTime60HzFullPower = 262; -+ const u16 aeFlickerFullFrameTime50HzLowPower = 314; -+ const u16 aeFlickerFullFrameTime50HzFullPower = 314; -+ const u16 flickerSearchRange50HZ = 0x1712; -+ const u16 flickerSearchRange60HZ = 0x120D; -+ // const u16 flickerParameter = 0x1E1C; // 7/8 trials -+ const u16 flickerParameter = 0x0D1C; // 3/4 trials -+ -+ mt9m111_write(0x005, hblankFullPower); -+ mt9m111_write(0x006, vblanksFullPower[newMaxFPS-5]); -+ mt9m111_write(0x007, hblankLowPower); -+ mt9m111_write(0x008, vblanksLowPower[newMaxFPS-5]); -+ mt9m111_write(0x020, readModeFullPower); -+ mt9m111_write(0x021, readModeLowPower); -+ mt9m111_write(0x239, aeLineSizeLowPower); -+ mt9m111_write(0x23A, aeLineSizeFullPower); -+ mt9m111_write(0x23B, aeShutterDelayLimitLowPower); -+ mt9m111_write(0x23C, aeShutterDelayLimitFullPower); -+ mt9m111_write(0x257, aeFlickerFullFrameTime60HzLowPower); -+ mt9m111_write(0x258, aeFlickerFullFrameTime50HzLowPower); -+ mt9m111_write(0x259, aeFlickerFullFrameTime60HzFullPower); -+ mt9m111_write(0x25A, aeFlickerFullFrameTime50HzFullPower); -+ mt9m111_write(0x25C, flickerSearchRange60HZ); -+ mt9m111_write(0x25D, flickerSearchRange50HZ); -+ mt9m111_write(0x264, flickerParameter); -+ -+ maxFPS = newMaxFPS; -+ } -+ -+ return MICRON_ERR_NONE; -+ -+} -+ -+int mt9m111_set_autoexposure_zone(u16 newMinFPS) -+{ -+ const int MIN_FPS = 5; -+ const int MAX_FPS = 15; -+ -+ // -+ // This driver only implements two minimum framerates: 5fps and 15fps. -+ // -+ // The mt9m111 can support every min fps between 5fps and 15fps, but the AE settings -+ // will become very complex. -+ // -+ -+ if (newMinFPS > 5) -+ { -+ newMinFPS = MAX_FPS; -+ } -+ else -+ { -+ newMinFPS = MIN_FPS; -+ } -+ -+ // -+ // if the minFPS has changed, update the AE limit -+ // -+ -+ if (newMinFPS != minFPS) -+ { -+ // -+ // enforce min fps by setting max exposure time -+ // -+ -+ if (newMinFPS == 5) -+ { -+ // set min fps to 5 fps -> AE Zone 24 -+ u16 limitAE = ((120/5) << 5) & 0x03E0; -+ mt9m111_write(0x237, limitAE); -+ -+ // -+ // work-around for AE strangeness -+ // symptom: start in dark, preview gets darker, darker, very dark, black, then is OK. -+ // -+ -+ if (mt9m111_reg_read(0x23F) == 8) -+ { -+ u16 v; -+ v = mt9m111_reg_read(0x22E); // read target luma register -+ -+ // by setting target luma to 0, trick AE into zone <= 8 -+ mt9m111_write(0x22E, 0x0000); // set target luma to 0 -+ -+ // -+ // wait until AE zone is in bounds (or time exceeds 1500ms) -+ // -+ // 1500ms is a long time! -+ // -+ -+ int count=0; -+ while ((mt9m111_reg_read(0x23F) == 8) && (++count < 30)) -+ { -+ mdelay(50); -+ } -+ -+ mt9m111_write(0x22E, v); // rewrite target luma register -+ } -+ } -+ else -+ { -+ // set min fps to 15 fps -> AE Zone 8 -+ u16 limitAE = ((120/15) << 5) & 0x03E0; -+ mt9m111_write(0x237, limitAE); -+ mt9m111_dbg_print("AE zone limit is %0x\n", limitAE); -+ -+ // -+ // work-around for AE strangeness -+ // symptom: start in dark, preview gets darker, darker, very dark, black, then is OK. -+ // -+ -+ if (mt9m111_reg_read(0x23F) > 8) -+ { -+ u16 v; -+ v = mt9m111_reg_read(0x22E); // read target luma register -+ -+ // by setting target luma to 0, trick AE into zone <= 8 -+ mt9m111_write(0x22E, 0x0000); // set target luma to 0 -+ -+ // -+ // wait until AE zone is in bounds (or time exceeds 1500ms) -+ // -+ // 1500ms is a long time! -+ // -+ -+ int count=0; -+ while ((mt9m111_reg_read(0x23F) > 8) && (++count < 30)) -+ { -+ mdelay(50); -+ } -+ -+ mt9m111_write(0x22E, v); // rewrite target luma register -+ } -+ } -+ -+ minFPS = newMinFPS; -+ } -+ -+ return MICRON_ERR_NONE; -+ -+} -+ -+int mt9m111_output_format(u16 format) -+{ -+ u16 value; -+ -+ if(format == O_FORMAT_422_YCbYCr) -+ { -+ mt9m111_write(0x13A, 0); -+ } -+ else -+ { -+ value = (1<<8)|((format-1)<<6); -+ mt9m111_write(0x13A, value); -+ } -+ return MICRON_ERR_NONE; -+} -+ -+void mt9m111_dump_register(u16 startRegAddr, u16 endRegAddr, u16* buffer) -+{ -+ u16 addr,value; -+ -+ for(addr = startRegAddr; addr <= endRegAddr; addr++) -+ { -+ unsigned long flags; -+ local_irq_save(flags); -+ -+ mt9m111_read(addr, &value); -+ -+ local_irq_restore(flags); -+ -+ mt9m111_dbg_print("mt9m111 register: 0x%04x = %04x",addr,value); -+ -+ if(buffer) -+ { -+ *buffer = value; -+ buffer++; -+ } -+ } -+} -+ -+// -+// TODO: make this an IOCTL that is called by the application some time after set_flicker() is -+// called -+// -+ -+int mt9m111_set_flicker_2(void) -+{ -+ mt9m111_dbg_print("mt9m111_set_flicker_2: %04x", preferredFlickerMask); -+ -+ int count=0; -+ -+ // -+ // read flicker_control_1 until it verifies that flicker is set to the preferred rate. -+ // -+ -+ while(((mt9m111_reg_read(0x25B) & 0x8000) != preferredFlickerMask) && (++count < 50)) -+ { -+ mdelay(20); -+ } -+ -+ mt9m111_write(0x25B, 0x0002); // back to auto mode -+ -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_set_flicker(int flicker) -+{ -+ mt9m111_dbg_print("mt9m111_set_flicker: %d", flicker); -+ -+ preferredFlickerMask = (flicker == 50) ? 0x0000 : 0x8000; -+ -+ if (flicker == 50) -+ { -+ mt9m111_write(0x25B, 0x0001); // manual mode 50Hz -+ } -+ else if (flicker == 60) -+ { -+ mt9m111_write(0x25B, 0x0003); // manual mode 60Hz -+ } -+ else -+ { -+ return MICRON_ERR_PARAMETER; -+ } -+ -+ mt9m111_set_flicker_2(); -+ -+ return MICRON_ERR_NONE; -+} -+ -+int mt9m111_set_contrast(int contrast) -+{ -+ mt9m111_dbg_print("mt9m111_set_contrast: %d (skipped)", contrast); -+ return MICRON_ERR_NONE; -+ -+#if 0 -+ // -+ // we don't support setting the contrast in the initial release of A780 -+ // -+ -+ const u16 gammaTable[] = -+ { -+ //0x3B2C,0x664D,0x9F87,0xC3B3,0xE0D2, //0.40 -+ //0x3224,0x664D,0x9F87,0xC3B3,0xE0D2, //0.45 -+ 0x2A1D,0x543B,0x9277,0xBDA9,0xE0CF, //0.50 -+ 0x2318,0x4C34,0x8C70,0xBAA4,0xE0CD, //0.55 -+ 0x1E14,0x462E,0x876A,0xB7A0,0xE0CC, //0.60 -+ 0x1910,0x3F28,0x8163,0xB39B,0xE0CA, //0.65 -+ 0x150D,0x3923,0x7B5D,0xB097,0xE0C9, //0.70 -+ 0x120A,0x341E,0x7657,0xAE93,0xE0C7, //0.75 -+ 0x0F08,0x2F1B,0x7152,0xAB8F,0xE0C6, //0.80 -+ 0x0D07,0x2A17,0x6D4D,0xA88B,0xE0C4, //0.85 -+ 0x0B05,0x2614,0x6848,0xA587,0xE0C2, //0.90 -+ //0x0804,0x2010,0x6040,0xA080,0xE0C0, //1.00 -+ //0x0502,0x1A0C,0x5838,0x9A79,0xE0BD, //1.10 -+ //0x0401,0x1509,0x5131,0x9572,0xE0BA, //1.20 -+ }; -+ -+ if(contrast < -4 || contrast > 4) -+ { -+ return MICRON_ERR_PARAMETER; -+ } -+ -+ u16 i, regA=0x153, regB=0x1DC; -+ -+ for(i=0; i<5; i++) -+ { -+ mt9m111_write(regA++, gammaTable[(contrast+4)*5+i]); -+ mt9m111_write(regB++, gammaTable[(contrast+4)*5+i]); -+ } -+ -+ return MICRON_ERR_NONE; -+#endif -+ -+} -+ -+/*set picture style(normal/black white/sepia/solarize/neg.art)*/ -+int mt9m111_set_style(V4l_PIC_STYLE style) -+{ -+ mt9m111_dbg_print("mt9m111_set_style: %d", style); -+ -+ switch(style) -+ { -+ case V4l_STYLE_BLACK_WHITE: -+ mt9m111_write(0x1E2,0x7001); -+ break; -+ case V4l_STYLE_SEPIA: -+ mt9m111_write(0x1E2,0x7002); -+ mt9m111_write(0x1E3,0xB023); -+ break; -+ case V4l_STYLE_SOLARIZE: -+ mt9m111_write(0x1E2,0x7004); -+ break; -+ case V4l_STYLE_NEG_ART: -+ mt9m111_write(0x1E2,0x7003); -+ break; -+ default: -+ mt9m111_write(0x1E2,0x7000); -+ break; -+ } -+ -+ return MICRON_ERR_NONE; -+} -+ -+ -+/*set picture light(auto/direct sun/incandescent/fluorescent)*/ -+int mt9m111_set_light(V4l_PIC_WB light) -+{ -+ u16 *m; -+ u16 v; -+ -+ switch(light) -+ { -+ case V4l_WB_DIRECT_SUN: -+ -+ mt9m111_dbg_print("mt9m111_set_light: %d (direct sun)", light); -+ m = d65Light; -+ break; -+ -+ case V4l_WB_INCANDESCENT: -+ -+ mt9m111_dbg_print("mt9m111_set_light: %d (incandescent)", light); -+ m = incandescentLight; -+ break; -+ -+ case V4l_WB_FLUORESCENT: -+ -+ mt9m111_dbg_print("mt9m111_set_light: %d (fluorescent)", light); -+ m = tl84Light; -+ break; -+ -+ default: -+ -+ mt9m111_dbg_print("mt9m111_set_light: %d (default)", light); -+ m = autoLight; -+ break; -+ -+ } -+ -+ mt9m111_write(0x202, m[0]); //BASE_MATRIX_SIGNS -+ mt9m111_write(0x203, m[1]); //BASE_MATRIX_SCALE_K1_K5 -+ mt9m111_write(0x204, m[2]); //BASE_MATRIX_SCALE_K6_K9 -+ -+ mt9m111_write(0x209, m[3]); //BASE_MATRIX_COEF_K1 -+ mt9m111_write(0x20A, m[4]); //BASE_MATRIX_COEF_K2 -+ mt9m111_write(0x20B, m[5]); //BASE_MATRIX_COEF_K3 -+ mt9m111_write(0x20C, m[6]); //BASE_MATRIX_COEF_K4 -+ mt9m111_write(0x20D, m[7]); //BASE_MATRIX_COEF_K5 -+ mt9m111_write(0x20E, m[8]); //BASE_MATRIX_COEF_K6 -+ mt9m111_write(0x20F, m[9]); //BASE_MATRIX_COEF_K7 -+ mt9m111_write(0x210, m[10]); //BASE_MATRIX_COEF_K8 -+ mt9m111_write(0x211, m[11]); //BASE_MATRIX_COEF_K9 -+ mt9m111_write(0x215, m[12]); //DELTA_COEF_SIGNS -+ mt9m111_write(0x216, m[13]); //DELTA_MATRIX_COEF_D1 -+ mt9m111_write(0x217, m[14]); //DELTA_MATRIX_COEF_D2 -+ mt9m111_write(0x218, m[15]); //DELTA_MATRIX_COEF_D3 -+ mt9m111_write(0x219, m[16]); //DELTA_MATRIX_COEF_D4 -+ mt9m111_write(0x21A, m[17]); //DELTA_MATRIX_COEF_D5 -+ mt9m111_write(0x21B, m[18]); //DELTA_MATRIX_COEF_D6 -+ mt9m111_write(0x21C, m[19]); //DELTA_MATRIX_COEF_D7 -+ mt9m111_write(0x21D, m[20]); //DELTA_MATRIX_COEF_D8 -+ mt9m111_write(0x21E, m[21]); //DELTA_MATRIX_COEF_D9 -+ -+ mt9m111_write(0x25E, m[22]); //RATIO_BASE_REG -+ mt9m111_write(0x25F, m[23]); //RATIO_DELTA_REG -+ mt9m111_write(0x260, m[24]); //SIGNS_DELTA_REG -+ -+ //Toggle Manual White Balance to force loading the new table -+ v = mt9m111_reg_read(0x106); -+ mt9m111_write(0x106, v|0x8000); // Operating Mode Control -- P.13 708E -+ mdelay(200); // TODO: correct amount of time? -+ mt9m111_write(0x106, v&~0x8000); -+ -+ return MICRON_ERR_NONE; -+} -+ -+ -+/*set picture brightness*/ -+int mt9m111_set_bright(int bright) -+{ -+ mt9m111_dbg_print("mt9m111_set_bright (gamma) %d", bright); -+ -+ const u16 target[] = -+ { -+ 37, // -2.0 EV -+ 44, // -1.5 EV -+ 52, // -1.0 EV -+ 62, // -0.5 EV -+ 74, // 0.0 EV -+ 88, // +0.5 EV -+ 105, // +1.0 EV -+ 124, // +1.5 EV -+ 148 // +2.0 EV -+ }; -+ -+ if(bright < -4 || bright > 4) -+ { -+ return MICRON_ERR_PARAMETER; -+ } -+ -+ /*set luma value of AE target*/ -+ mt9m111_write(0x22E, 0x0C00 + target[bright+4]); -+ return MICRON_ERR_NONE; -+} -+ -+ -+int mt9m111_default_settings() -+{ -+ mt9m111_dbg_print("mt9m111_default_settings"); -+ -+ mt9m111_reset(); -+ -+ // Soft Reset -- Reset both sensor AND SOC (and leave sensor digital logic enabled) -+ -+ mt9m111_write(0x00D, 0x29); // Reset sensor and SOC -- P.54 -+ // i2c will delay enough here for reset to finish (1us is enough) -+ mt9m111_write(0x00D, 0x08); // Release reset -- P.54 -+ -+ mt9m111_write(0x285, 0x0061); // AE Gain table -+ mt9m111_write(0x286, 0x0080); // AE Gain table -+ mt9m111_write(0x287, 0x0061); // AE Gain table -+ mt9m111_write(0x288, 0x0061); // AE Gain table -+ mt9m111_write(0x289, 0x03E2); // AE Gain table -+ mt9m111_write(0x238, 0x0840); // Shutter priority transition zone -+ -+ //Enable flicker detection -+ mt9m111_write(0x106, 0x708E); // Operating Mode Control -- P.13 0x0708C -+ -+ // Enable 2D defect correction in both contexts -+ mt9m111_write(0x14C, 0x0001); // Defect Buffer Context A -- P.13 0x0000 -- Enable 2D defect correct context A -+ mt9m111_write(0x14D, 0x0001); // Defect Buffer Context B -- P.13 0x0000 -- Enable 2D defect correct context B -+ -+ // Set centered origin -+ mt9m111_write(0x1a8, 0x4000); // Reducer YPan A -- P.14 0x0000 -- Cntxt A Y Crop centering -+ mt9m111_write(0x1a5, 0x4000); // Reducer XPan A -- P.14 0x0000 -- Cntxt A X Crop centering -+ mt9m111_write(0x1a2, 0x4000); // Reducer YPan B -- P.14 0x0000 -- Cntxt B Y Crop centering -+ mt9m111_write(0x19F, 0x4000); // Reducer XPan B -- P.14 0x0000 -- Cntxt B X Crop centering -+ -+ // Sensor is running in semi auto mode only -+ mt9m111_write(0x2CC, 0x0004); // Context Ctl Pgm Select -- P.19 0x0000 -+ -+ //mt9m111_write(0x034, 0xC039); // Reserved -- P.54 0xC019 in es3 -- turn on eclipse -+ -+ // Do not invert the pixel clock -+ mt9m111_write(0x13A, 0x0000); // Output Format Control 2A -- P.13 0x0000 -+ mt9m111_write(0x19B, 0x0000); // Output Format Control 2B -- P.14 0x0000 -+ -+ //Auto sharpening -+ mt9m111_write(0x105, 0x000B); // Aperature Correction (sharpening) gain -- 0x0003 -+ // 75% sharpening, auto-sharpening on -+ -+ //Enable classic interpolation at full res -+ mt9m111_write(0x1AF, 0x0018); // Reducer Zoom Control -- P.14 0x0010 -+ -+ //AWB settings for 12mm lens, no ulens shift -+ mt9m111_write(0x222, 0xb070); // Red Gain AWB Limits -- P.16 0x0D960 -- overconstrained currently? (sunburned->0x8870) -+ mt9m111_write(0x223, 0xb070); // Blue Gain AWB Limits -- P.16 0x0D960 -- overconstrained currently? -+ mt9m111_write(0x229, 0x847C); // Reserved -- P.16 0x8D73 -- Thresholds (tied into digital gains above) -+ -+ //mt9m111_set_light(V4l_WB_AUTO); //the app will call ioctl to set light -+ -+ // lens correction for Micron es3 + flex module 9/31 -+ -+ mt9m111_write(0x180, 0x0003); // LENS_ADJ_PARAM_0_5 -+ mt9m111_write(0x181, 0xC813); // LENS_ADJ_VERT_RED_0 -+ mt9m111_write(0x182, 0xEEE2); // LENS_ADJ_VERT_RED_1_2 -+ mt9m111_write(0x183, 0xFDF9); // LENS_ADJ_VERT_RED_3_4 -+ mt9m111_write(0x184, 0xE10C); // LENS_ADJ_VERT_GREEN_0 -+ mt9m111_write(0x185, 0xF0E9); // LENS_ADJ_VERT_GREEN_1_2 -+ mt9m111_write(0x186, 0xFFF8); // LENS_ADJ_VERT_GREEN_3_4 -+ mt9m111_write(0x187, 0xE60A); // LENS_ADJ_VERT_BLUE_0 -+ mt9m111_write(0x188, 0xF2EB); // LENS_ADJ_VERT_BLUE_1_2 -+ mt9m111_write(0x189, 0x01F9); // LENS_ADJ_VERT_BLUE_3_4 -+ mt9m111_write(0x18A, 0xAE25); // LENS_ADJ_HORIZ_RED_0 -+ mt9m111_write(0x18B, 0xDACE); // LENS_ADJ_HORIZ_RED_1_2 -+ mt9m111_write(0x18C, 0xF5EF); // LENS_ADJ_HORIZ_RED_3_4 -+ mt9m111_write(0x18D, 0x00FD); // LENS_ADJ_HORIZ_RED_5 -+ mt9m111_write(0x18E, 0xDE18); // LENS_ADJ_HORIZ_GREEN_0 -+ mt9m111_write(0x18F, 0xE5E2); // LENS_ADJ_HORIZ_GREEN_1_2 -+ mt9m111_write(0x190, 0xF7F2); // LENS_ADJ_HORIZ_GREEN_3_4 -+ mt9m111_write(0x191, 0x00FE); // LENS_ADJ_HORIZ_GREEN_5 -+ mt9m111_write(0x192, 0xCF17); // LENS_ADJ_HORIZ_BLUE_0 -+ mt9m111_write(0x193, 0xEAE4); // LENS_ADJ_HORIZ_BLUE_1_2 -+ mt9m111_write(0x194, 0xF8F4); // LENS_ADJ_HORIZ_BLUE_3_4 -+ mt9m111_write(0x195, 0x00FF); // LENS_ADJ_HORIZ_BLUE_5 -+ mt9m111_write(0x1B6, 0x1104); // LENS_ADJ_VERT_RED_5_6 -+ mt9m111_write(0x1B7, 0x3420); // LENS_ADJ_VERT_RED_7_8 -+ mt9m111_write(0x1B8, 0x0503); // LENS_ADJ_VERT_GREEN_5_6 -+ mt9m111_write(0x1B9, 0x1C0F); // LENS_ADJ_VERT_GREEN_7_8 -+ mt9m111_write(0x1BA, 0x0502); // LENS_ADJ_VERT_BLUE_5_6 -+ mt9m111_write(0x1BB, 0x1B0C); // LENS_ADJ_VERT_BLUE_7_8 -+ mt9m111_write(0x1BC, 0x0F03); // LENS_ADJ_HORIZ_RED_6_7 -+ mt9m111_write(0x1BD, 0x2E1C); // LENS_ADJ_HORIZ_RED_8_9 -+ mt9m111_write(0x1BE, 0x0050); // LENS_ADJ_HORIZ_RED_10 -+ mt9m111_write(0x1BF, 0x0A02); // LENS_ADJ_HORIZ_GREEN_6_7 -+ mt9m111_write(0x1C0, 0x1C13); // LENS_ADJ_HORIZ_GREEN_8_9 -+ mt9m111_write(0x1C1, 0x0023); // LENS_ADJ_HORIZ_GREEN_10 -+ mt9m111_write(0x1C2, 0x0801); // LENS_ADJ_HORIZ_BLUE_6_7 -+ mt9m111_write(0x1C3, 0x1B0F); // LENS_ADJ_HORIZ_BLUE_8_9 -+ mt9m111_write(0x1C4, 0x0027); // LENS_ADJ_HORIZ_BLUE_10 -+ -+ //turn on lens correction -+ mt9m111_write(0x106, 0x748E); // Operating Mode Control -- P.13 0x708E -+ -+ // set luma offset and clip for both contexts -+ mt9m111_write(0x134, 0x0000); // Luma offset (Brightness Offset) -+ mt9m111_write(0x135, 0xFF01); // Luma clip (Brightness Offset) -+ // TODO: why FF01, why not FF00? -+ -+ // load hard-coded 0.6 gamma table (Context A) -+ mt9m111_write(0x153, 0x2217); -+ mt9m111_write(0x154, 0x4F34); -+ mt9m111_write(0x155, 0x9978); -+ mt9m111_write(0x156, 0xD0B6); -+ mt9m111_write(0x157, 0xFEE8); -+ mt9m111_write(0x158, 0x0000); -+ -+ // load hard-coded 0.6 gamma table (Context B) -+ mt9m111_write(0x1DC, 0x2217); -+ mt9m111_write(0x1DD, 0x4F34); -+ mt9m111_write(0x1DE, 0x9978); -+ mt9m111_write(0x1DF, 0xD0B6); -+ mt9m111_write(0x1E0, 0xFEE8); -+ mt9m111_write(0x1E1, 0x0000); -+ -+ // add new setting from Kenta's email, Nov.2, 2004 -+ mt9m111_write(0x21F, 0x0090); -+ //mt9m111_write(0x222, 0xb070); // aleady write above -+ //mt9m111_write(0x223, 0xb070); // aleady write above -+ mt9m111_write(0x228, 0xef14); -+ -+ return MICRON_ERR_NONE; -+} -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/mt9m111_hw.h linux-2.6.16.5-exz/drivers/media/video/mt9m111_hw.h ---- linux-2.6.16.5/drivers/media/video/mt9m111_hw.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/mt9m111_hw.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,89 @@ -+/*================================================================================ -+ -+ Header Name: mt9m111_hw.h -+ -+General Description: Camera module mt9m111 interface header file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+Ma Zhiqiang 6/30/2004 Change for auto-detect -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+ -+#ifndef _PXA_MT9M111_HW_H__ -+#define _PXA_MT9M111_HW_H__ -+ -+#include "camera.h" -+/*********************************************************************** -+ * -+ * Constants & Structures -+ * -+ ***********************************************************************/ -+ -+/* MICRON_WINDOWSIZE */ -+typedef struct { -+ u16 width; -+ u16 height; -+} micron_window_size; -+ -+ -+// Return codes -+#define MICRON_ERR_NONE 0 -+#define MICRON_ERR_TIMEOUT -1 -+#define MICRON_ERR_PARAMETER -2 -+ -+ -+// Output Format -+#define O_FORMAT_422_YCbYCr 0 -+#define O_FORMAT_565_RGB 1 -+#define O_FORMAT_555_RGB 2 -+#define O_FORMAT_444_RGB 3 -+ -+ -+/*********************************************************************** -+ * -+ * Function Prototype -+ * -+ ***********************************************************************/ -+ -+u16 mt9m111_reg_read(u16 reg_addr); -+void mt9m111_reg_write(u16 reg_addr, u16 reg_value); -+ -+ -+// Configuration Procedures -+int mt9m111_get_device_id(u16 *id); -+ -+int mt9m111_viewfinder_on( void ); -+int mt9m111_viewfinder_off( void ); -+int mt9m111_snapshot_trigger( void ); -+int mt9m111_snapshot_complete( void ); -+ -+int mt9m111_set_fps(u16 fps, u16 minfps); -+int mt9m111_set_autoexposure_zone(u16 minfps); -+ -+int mt9m111_input_size(micron_window_size * win); -+int mt9m111_output_size(micron_window_size * win); -+int mt9m111_get_input_size(micron_window_size * win); -+int mt9m111_output_format(u16 format); -+ -+int mt9m111_set_contrast(int contrast); -+int mt9m111_set_style(V4l_PIC_STYLE style); -+int mt9m111_set_light(V4l_PIC_WB light); -+int mt9m111_set_bright(int bright); -+int mt9m111_set_flicker(int bright); -+ -+int mt9m111_default_settings( void ); -+ -+void mt9m111_dump_register(u16 startRegAddr, u16 endRegAddr, u16* buffer); -+ -+#endif /* _PXA_MT9M111_HW_H__ */ -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/mt9v111.c linux-2.6.16.5-exz/drivers/media/video/mt9v111.c ---- linux-2.6.16.5/drivers/media/video/mt9v111.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/mt9v111.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,910 @@ -+ -+/*================================================================================ -+ -+ Header Name: mt9v111.c -+ -+General Description: Camera module mt9v111 interface source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+wangfei(w20239) 04/14/2003 Created -+ -+================================================================================== -+ INCLUDE FILES -+==================================================================================*/ -+#include <linux/types.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+ -+#include <asm/pgtable.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+ -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+#include <linux/videodev.h> -+#include <linux/pci.h> -+#include <linux/pm.h> -+#include <linux/poll.h> -+#include <linux/wait.h> -+ -+#include <asm/arch/pxa-regs.h> -+ -+#include "adcm2700.h" -+#include "adcm2700_hw.h" -+ -+#define ADDRSPACE_CORE 0x04 /* code to select core registers 0-170*/ -+#define ADDRSPACE_IFP 0x01 /* code to select IFP/SOC registers 0-255*/ -+#define MT9V111_SENSOR_WIDTH 640 -+#define MT9V111_SENSOR_HEIGHT 480 -+ -+extern int mt9v111_write(u8 addrSpace, u16 addr, u16 value); -+extern int mt9v111_read(u8 addrSpace, u16 addr); -+extern int i2c_mt9v111_cleanup(void); -+extern int camera_ring_buf_init(p_camera_context_t); -+extern void adcm2700_wait(u32); -+extern void start_dma_transfer(p_camera_context_t,unsigned); -+extern void stop_dma_transfer(p_camera_context_t); -+extern int camera_func_mt9v111_stop_capture(p_camera_context_t camera_context); -+ -+static int mt9v111_restore_property(p_camera_context_t); -+ -+static inline int mt9v111_read_core_reg(u16 addr) -+{ -+ return mt9v111_read(ADDRSPACE_CORE, addr); -+} -+ -+static inline int mt9v111_read_ifp_reg(u16 addr) -+{ -+ return mt9v111_read(ADDRSPACE_IFP, addr); -+} -+static inline int mt9v111_write_core_reg(u16 addr, u16 value) -+{ -+ return mt9v111_write(ADDRSPACE_CORE, addr, value); -+} -+static inline int mt9v111_write_ifp_reg(u16 addr, u16 value) -+{ -+ return mt9v111_write(ADDRSPACE_IFP, addr, value); -+} -+static int mt9v111_input_size(adcm_window_size * size) -+{ -+ u16 pan_ver,pan_hor; -+ pan_hor=(MT9V111_SENSOR_WIDTH - size->width)>>1; -+ pan_ver=(MT9V111_SENSOR_HEIGHT- size->height)>>1; -+ -+ mt9v111_write_ifp_reg(0xa5,0x8000|pan_hor); -+ mt9v111_write_ifp_reg(0xa8,0x8000|pan_ver); -+ mt9v111_write_ifp_reg(0xa6,0x8000|size->width); -+ mt9v111_write_ifp_reg(0xa9,size->height); -+ dbg_print("set sensor width : %d height : %d\n",size->width , size->height); -+ //dbg_print("horizontal pan :%d vertical pan %d \n",pan_hor,pan_ver); -+ return 0; -+} -+static int mt9v111_set_fps(int fps, int minfps) -+{ -+ //write to r55 (0x37) [9..5] to change minimum fps -+ u16 blank_v,r55,zone_low,zone_high; -+ dbg_print("set fps : %d min fps : %d\n",fps,minfps); -+ -+ //Set vertical blank to adjust frame rate -+ blank_v = (15-fps)*496/fps + 4; -+ mt9v111_write_core_reg(0x06,blank_v); -+ -+ //shut width -+ zone_low=0; -+ zone_high=fps*8/minfps; -+ r55 = zone_low|(zone_high<<5); -+ mt9v111_write_ifp_reg(0x37, r55); -+ -+ return 0; -+} -+static int mt9v111_set_bright(int bright) -+{ -+ const u16 target[]= -+ { -+ 25, -+ 35, -+ 50, -+ 75, -+ 100, -+ 120, -+ 140, -+ 160, -+ 180 -+ }; -+ if(bright > 4|| bright < -4) -+ { -+ return -EFAULT; -+ } -+ mt9v111_write_ifp_reg(0x2e,(16<<8)|target[bright+4]); -+ return 0; -+} -+static int mt9v111_output_size(adcm_window_size * size) -+{ -+ //0xA7 Horizontal size of output -+ //0xAA Vertical size of output -+ //refer to mt9v111-datasheet.pdf page 45 and page 46 -+ mt9v111_write_ifp_reg(0xA7, 0x8000|size->width); -+ mt9v111_write_ifp_reg(0xAA, size->height); -+ dbg_print("output size :%d * %d \n",size->width,size->height); -+ adcm2700_wait(50); -+ return 0; -+} -+static int mt9v111_set_blackwhite(int black_white) -+{ -+ u16 value = mt9v111_read_ifp_reg(0x08); -+ if(black_white) -+ { -+ value |= 1<<5; -+ } -+ else -+ { -+ value &= ~(1<<5); -+ } -+ -+ mt9v111_write_ifp_reg(0x08, value); -+ return 0; -+} -+//set color correction matrix -+static int mt9v111_set_ccm(int index) -+{ -+ int i; -+ u16 r6; -+ const u16 regs[]= -+ { -+ 72, //digital gain -+ 2, //sign -+ 3,4, //scale -+ 9,10,11,12,13,14,15,16,17, //magnitude -+ 21,22,23,24,25,26,27,28,29,30, //delta matrix -+ 94,95,96 -+ }; -+ const u16 value[][26]= -+ { -+ //default -+ { -+ -+ 0, -+ 0x6e, -+ 0x2923,0x0524, -+ 146,22,8,171,147,88,77,169,160, -+ 373,22,67,12,0,21,31,22,152,76, -+ 26684,12296,2 -+ /* -+ 0, -+ 110, -+ 10531,1316, -+ 125,108,58,129,141,112,95,128,138, -+ 145,6,231,221,15,65,208,72,59,43, -+ 26953,11283,2 -+ */ -+ }, -+ //direct sun -+ { -+ /* -+ 128, -+ 0xea, -+ 0x3922,0x4e4, -+ 0x8d,0x71,0xc5,0x9d,0xf8,0x53,0x0d,0xa7,0x90, -+ 0,0,0,0,0,0,0,0,0,0 -+ */ -+ 128, -+ 174, -+ 14627,1828, -+ 128,7,52,122,215,7,59,99,232, -+ 0,0,0,0,0,0,0,0,0,0, -+ 21331,0,0 -+ -+ }, -+ //incandescent -+ { -+ /* -+ 128, -+ 0xee, -+ 0x2922,0x4a4, -+ 0x8c,0xcc,0x6e,0xa6,0x86,0x72,0x06,0x85,0xc6, -+ 0,0,0,0,0,0,0,0,0,0 -+ */ -+ 128, -+ 110, -+ 10532,1316, -+ 245,244,168,137,174,216,131,158,160, -+ 0,0,0,0,0,0,0,0,0,0, -+ 32832,0,0 -+ }, -+ //fluorescent -+ { -+ /* -+ 0, -+ 0xea, -+ 0x3922,0x4e4, -+ 0x8d,0xba,0x7b,0x9c,0xfe,0x61,0x08,0xb9,0x9a, -+ 0,0,0,0,0,0,0,0,0,0 -+ */ -+ 128, -+ 166, -+ 10531,1316, -+ 197,160,77,230,132,3,122,91,131, -+ 0,0,0,0,0,0,0,0,0,0, -+ 32844,0,0 -+ -+ }, -+ //sepia -+ { -+ 128, -+ 36, -+ 10516,2276, -+ 9,142,17,24,134,43,10,147,17, -+ 0,0,0,0,0,0,0,0,0,0, -+ 20560,0,0 -+ }, -+ }; -+ -+ for(i=0; i<26; i++) -+ { -+ mt9v111_write_ifp_reg(regs[i],value[index][i]); -+ } -+ -+ r6=mt9v111_read_ifp_reg(0x06); -+ r6 |= 1<<15; -+ mt9v111_write_ifp_reg(0x06,r6); -+ r6 &= ~(1<<15); -+ mt9v111_write_ifp_reg(0x06,r6); -+ return 0; -+} -+static int mt9v111_set_gamma(int index) -+{ -+ const u16 regs[]= -+ { -+ 0x58,0x53,0x54,0x55,0x56,0x57, -+ }; -+ const u16 value[][11]= -+ { -+ //default -+ { -+ //0x0,0x09,0x0f,0x1b,0x2f,0x52,0x71,0x8f,0xab,0xc6,0xe0 -+ 0,10,18,31,54,94,130,164,196,226,255 -+ }, -+ //solarize -+ { -+ // 224,23,17,128,220,175,105,53,33,8,0 -+ 0,4,8,16,32,64,96,128,160,192,224 -+ }, -+ //neg art -+ { -+ // 224,204,194,178,174,118,89,64,41,20,0 -+ 0,4,8,16,32,64,96,128,160,192,224 -+ } -+ }; -+ int i; -+ dbg_print("mt9v111_set_gamma to index :%d \n",index); -+ mt9v111_write_ifp_reg(regs[0],value[index][0]); -+ for(i=0; i<5; i++) -+ { -+ mt9v111_write_ifp_reg(regs[i+1],value[index][2*i+1]|(value[index][2*i+2]<<8)); -+ } -+ return 0; -+} -+static int mt9v111_set_light(V4l_PIC_WB light) -+{ -+ int index; -+ switch(light) -+ { -+ case V4l_WB_DIRECT_SUN: -+ index = 1; -+ break; -+ case V4l_WB_INCANDESCENT: -+ index = 2; -+ break; -+ case V4l_WB_FLUORESCENT: -+ index = 3; -+ break; -+ case V4l_WB_AUTO: -+ index = 0; -+ break; -+ default: -+ dbg_print("incorrect light type!\n"); -+ return -EFAULT; -+ } -+ return mt9v111_set_ccm(index); -+} -+static int mt9v111_set_style(V4l_PIC_STYLE style) -+{ -+ if(style != V4l_STYLE_BLACK_WHITE) -+ { -+ mt9v111_set_blackwhite(0); -+ } -+ switch(style) -+ { -+ case V4l_STYLE_BLACK_WHITE: -+ mt9v111_set_gamma(0); -+ mt9v111_set_blackwhite(1); -+ break; -+ case V4l_STYLE_SEPIA: -+ mt9v111_set_gamma(0); -+ mt9v111_set_ccm(4); -+ break; -+ case V4l_STYLE_SOLARIZE: -+ mt9v111_set_gamma(1); -+ break; -+ case V4l_STYLE_NEG_ART: -+ mt9v111_set_gamma(2); -+ break; -+ default: -+ mt9v111_set_gamma(0); -+ break; -+ } -+ return 0; -+} -+ -+static inline int mt9v111_set_effects(p_camera_context_t cam_ctx) -+{ -+ mt9v111_set_light(cam_ctx->capture_light); -+ mt9v111_set_style(cam_ctx->capture_style); -+ return 0; -+} -+static int mt9v111_reset(void) -+{ -+ //stop and reset -+ mt9v111_write_core_reg(0x07, 0x0); -+ adcm2700_wait(20); -+ mt9v111_write_core_reg(0x0D, 0x1); -+ adcm2700_wait(5); -+ mt9v111_write_core_reg(0x0D, 0x0); -+ adcm2700_wait(5); -+ mt9v111_write_ifp_reg(0x07, 0x1); -+ adcm2700_wait(5); -+ mt9v111_write_ifp_reg(0x07, 0x0); -+ -+ return 0; -+} -+static int mt9v111_set_flicker(int flicker) -+{ -+/* -+ if (flicker == 50) -+ { -+ mt9v111_write(0x5b,0x01); -+ } -+ else if (flicker ==60) -+ { -+ mt9v111_write(0x5b,0x03); -+ } -+ else -+ { -+ return -EFAULT; -+ } -+*/ -+ return 0; -+} -+/*********************************************************************** -+ * -+ * MT9V111 Functions -+ * -+ ***********************************************************************/ -+int camera_func_mt9v111_init( p_camera_context_t cam_ctx ) -+{ -+ u16 addr; -+ u16 reg_value; -+ const u16 values2[] = -+ { -+ 0x0006, 0xCE12, 0x00F0, 0x370D, 0xE20C, 0xFDF5, -+ 0x280B, 0xDE0D, 0x00F4, 0x280A, 0xBD20, 0xF8E4, -+ 0x1E0A, 0x0050, 0xD812, 0xFCEC, 0x1407, 0x0028, -+ 0xD413, 0xFEEC, 0x1405, 0x0028 -+ }; -+ -+ ci_disable(1); -+ cam_ctx->mclk=12; -+ ci_set_clock(cam_ctx->clk_reg_base, 1, 1, cam_ctx->mclk); -+ ci_enable(1); -+ adcm2700_wait(10); -+ mt9v111_reset(); -+ /* lens shading */ -+ for(addr = 0x80; addr <= 0x95; addr++) -+ { -+ mt9v111_write_ifp_reg(addr, values2[addr-0x80]); -+ } -+ //accelerate AE speed -+ //mt9v111_write_ifp_reg(0x2f,0x80); -+ /* 100% sharpening */ -+ //mt9v111_write_ifp_reg(0x05,0x0c); -+//codes from jason -+ //lens shading enable -+ //* -+ reg_value = mt9v111_read_ifp_reg(0x08); -+ reg_value |= 0x0100; -+ mt9v111_write_ifp_reg(0x08,reg_value); -+ //*/ -+ mt9v111_write_core_reg(0x09,280); -+ mt9v111_write_core_reg(0x21,0xe401); -+ reg_value = mt9v111_read_core_reg(0x07); -+ reg_value &= ~(0x0010); -+ mt9v111_write_core_reg(0x07,reg_value); -+ mt9v111_write_core_reg(0x2f,0xe7b6); -+ mt9v111_write_ifp_reg(0x39,282); -+ mt9v111_write_ifp_reg(0x59,280); -+ mt9v111_write_ifp_reg(0x5a,336); -+ mt9v111_write_ifp_reg(0x5c,4624); -+ mt9v111_write_ifp_reg(0x5d,5652); -+ mt9v111_write_ifp_reg(0x25,0x4514); -+ //mt9v111_write_ifp_reg(0x25,0x6d14); -+ mt9v111_write_ifp_reg(0x34,0x0); -+ mt9v111_write_ifp_reg(0x35,0xff00); -+ mt9v111_write_ifp_reg(0x33,0x1411); -+ mt9v111_write_ifp_reg(0x3e,0x0fff); -+ mt9v111_write_ifp_reg(0x3b,0x042c); -+ mt9v111_write_ifp_reg(0x3d,0x01da); -+ mt9v111_write_ifp_reg(0x38,0x0878); -+ mt9v111_write_ifp_reg(0x40,0x1e10); -+ mt9v111_write_ifp_reg(0x41,0x1417); -+ mt9v111_write_ifp_reg(0x42,0x1213); -+ mt9v111_write_ifp_reg(0x43,0x1112); -+ mt9v111_write_ifp_reg(0x44,0x7110); -+ mt9v111_write_ifp_reg(0x45,0x7473); -+ -+ dbg_print("Mt9v111 init success!"); -+ return 0; -+} -+ -+int camera_func_mt9v111_deinit( p_camera_context_t camera_context ) -+{ -+ //stop camera run -+ camera_func_mt9v111_stop_capture(camera_context); -+ ci_disable(1); -+ i2c_mt9v111_cleanup(); -+ return 0; -+} -+ -+int camera_func_mt9v111_set_capture_format(p_camera_context_t camera_context) -+{ -+ adcm_window_size wsize; -+ u16 fmt_v1, fmt_v2; -+ u16 old1, old2; -+ -+ //set sensor input/output window -+ wsize.width = camera_context->capture_width; -+ wsize.height = camera_context->capture_height; -+ mt9v111_output_size(&wsize); -+ dbg_print("output size width=%d, height=%d", wsize.width, wsize.height); -+ /* -+ 0x08 output format contorl bit 12 -+ 1 RGB -+ 0 YCbCr -+ 0x3A output format control 2 bit 6-7 -+ 00 16-bit RGB565 -+ 01 15-bit RGB555 -+ 10 12-bit RGB444x -+ 11 12-bit RGB444 -+ refer to mt9v111-datasheet.pdf page 32 and page 39 -+ */ -+ old1 = mt9v111_read_ifp_reg(0x08); -+ old2 = mt9v111_read_ifp_reg(0x3A); -+ -+ // set sensor format -+ switch(camera_context->capture_input_format) -+ { -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ dbg_print("output format YCBCR422"); -+ fmt_v1 = 0; -+ fmt_v2 = 0; -+ break; -+ -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ dbg_print("output format RGB565"); -+ fmt_v1 = (1<<12); -+ fmt_v2 = 0; -+ break; -+ -+ case CAMERA_IMAGE_FORMAT_RGB444: -+ dbg_print("output format RGB444"); -+ fmt_v1 = (1<<12); -+ fmt_v2 = (0x03<<6); -+ break; -+ -+ case CAMERA_IMAGE_FORMAT_RGB555: -+ dbg_print("output format RGB555"); -+ fmt_v1 = (1<<12); -+ fmt_v2 = (0x01<<6); -+ break; -+ -+ default: -+ dbg_print("unsupported format!"); -+ return -EFAULT; -+ } -+ -+ old1 = (old1 & ~(1<<12)) | fmt_v1; -+ old2 = ((old2 & ~(3<<6)) & (~0x03)) | fmt_v2; // | (2<<3)/*out test ramp*/; -+ mt9v111_write_ifp_reg(0x08, old1); -+ mt9v111_write_ifp_reg(0x3A, old2); -+ return 0; -+} -+ -+int camera_func_mt9v111_start_capture(p_camera_context_t cam_ctx, unsigned int frames) -+{ -+ int cisr; -+ int wait_count = 1; -+ unsigned int start_time; -+ unsigned int flags; -+ int error_count = 0; -+ //mt9v111_restore_property(cam_ctx); -+restart: -+ start_time = 0x1000000; -+ if(frames == 1) -+ { -+ wait_count = 2; -+ } -+ //mt9v111_write_core_reg(0x07, 0x0002); -+ dbg_print("wait for EOF %d time", wait_count); -+ ci_disable(1); -+ ci_enable(1); -+ -+ start_time *= wait_count; -+ CISR|=CI_CISR_EOF; -+ cisr=CISR; -+ //local_irq_save(flags); -+ //mdelay(200); -+ while(wait_count) -+ { -+ if(cisr & CI_CISR_EOF) -+ { -+ wait_count -- ; -+ CISR|=CI_CISR_EOF; -+ } -+ cisr=CISR; -+ if(!(--start_time)) -+ { -+ goto start_error; -+ } -+ } -+ // ci_clear_int_status(0xFFFFFFFF); -+ mdelay(1); -+ ci_reset_fifo(); -+ ci_disable(1); -+ ci_enable(1); -+ start_dma_transfer(cam_ctx, 0); -+ //local_irq_restore(flags); -+ return 0; -+ -+start_error: -+ dbg_print("start error \n"); -+ if(error_count++ > 3) -+ { -+ return -1; -+ } -+ ci_disable(1); -+ ci_enable(1); -+ adcm2700_wait(10); -+ mt9v111_reset(); -+ mt9v111_restore_property(cam_ctx); -+ goto restart; -+ -+} -+ -+int camera_func_mt9v111_stop_capture( p_camera_context_t camera_context ) -+{ -+ /* -+ u16 old = mt9v111_read_core_reg(0x07); -+ old &= ~0x02; -+ mt9v111_write_core_reg(0x07, old); -+ */ -+ // stop_dma_transfer(camera_context); -+ return 0; -+} -+/*set output size*/ -+static int pxa_cam_WCAM_VIDIOCSOSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ adcm_window_size size; -+ CI_MP_TIMING timing; -+ int ret = 0; -+ unsigned int value; -+ memset(&timing, 0, sizeof(timing)); -+ dbg_print("WCAM_VIDIOCSOSIZE"); -+ if(copy_from_user(&size, param, sizeof(adcm_window_size))) -+ { -+ return -EFAULT; -+ } -+ size.height = (size.height+7)/8 * 8; -+ size.width = (size.width +7)/8 * 8; -+ if(size.height != cam_ctx->capture_height || size.width != cam_ctx->capture_width) -+ { -+ cam_ctx->capture_width = size.width; -+ cam_ctx->capture_height = size.height; -+ ret = mt9v111_output_size(&size); -+ timing.BFW = 0; -+ timing.BLW = 0; -+ ci_disable(1); -+ ci_configure_mp(cam_ctx->capture_width-1, cam_ctx->capture_height-1, &timing); -+ camera_ring_buf_init(cam_ctx); -+ ci_enable(1); -+ //mdelay(150); -+ } -+ return ret; -+} -+ -+/*read mt9v111 registers*/ -+static int pxa_camera_WCAM_VIDIOCGCAMREG(p_camera_context_t cam_ctx, void *param) -+{ -+ dbg_print(""); -+ int data, reg_value; -+ if(copy_from_user(&data, param, sizeof(data))) -+ { -+ return -EFAULT; -+ } -+ u16 space = (u16)(data>>16); -+ u16 addr = (u16)data; -+ -+ if(space == ADDRSPACE_CORE) -+ { -+ reg_value = mt9v111_read_core_reg(addr); -+ } -+ else if(space == ADDRSPACE_IFP) -+ { -+ reg_value = mt9v111_read_ifp_reg(addr); -+ } -+ else -+ { -+ return -EFAULT; -+ } -+ -+ if(copy_to_user(param, ®_value, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+/*write mt9v111 registers*/ -+static int pxa_camera_WCAM_VIDIOCSCAMREG(p_camera_context_t cam_ctx, void *param) -+{ -+ dbg_print(""); -+ -+ struct reg_set_s {int val1, val2;}reg_value; -+ -+ if(copy_from_user(®_value, param, sizeof(reg_value))) -+ { -+ return -EFAULT; -+ } -+ -+ u16 space = (u16)(reg_value.val1 >> 16); -+ u16 addr = (u16)(reg_value.val1); -+ -+ if(space == ADDRSPACE_CORE) -+ { -+ mt9v111_write_core_reg(addr, (u16)(reg_value.val2)); -+ } -+ else if(space == ADDRSPACE_IFP) -+ { -+ mt9v111_write_ifp_reg(addr, (u16)(reg_value.val2)); -+ } -+ else -+ { -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*set sensor size*/ -+static int pxa_cam_WCAM_VIDIOCSSSIZE(p_camera_context_t cam_ctx, void *param) -+{ -+ dbg_print(""); -+ adcm_window_size size; -+ int ret = 0; -+ if(copy_from_user(&size, param, sizeof(adcm_window_size))) -+ { -+ return -EFAULT; -+ } -+ size.width = ((size.width+7)/8) * 8; -+ size.height = ((size.height+7)/8) *8; -+ if(size.width != cam_ctx->sensor_width || size.height != cam_ctx->sensor_height) -+ { -+ cam_ctx->sensor_width = size.width; -+ cam_ctx->sensor_height = size.height; -+ -+ if(size.width > MT9V111_SENSOR_WIDTH || size.height > MT9V111_SENSOR_HEIGHT) -+ { -+ dbg_print("error input size width %d height %d",size.width, size.height); -+ return -EFAULT; -+ } -+ -+ ret = mt9v111_input_size(&size); -+ } -+ return ret; -+} -+ -+/*set fps*/ -+static int pxa_cam_WCAM_VIDIOCSFPS(p_camera_context_t cam_ctx, void *param) -+{ -+ dbg_print("WCAM_VIDIOCSFPS"); -+ struct {int fps, minfps;} cam_fps; -+ int ret = 0; -+ -+ if(copy_from_user(&cam_fps, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ -+ if(cam_fps.minfps < 5) -+ { -+ cam_fps.minfps = 5; -+ } -+ if(cam_fps.fps >15) -+ { -+ cam_fps.fps = 15; -+ } -+ -+ if(cam_fps.fps != cam_ctx->fps || cam_fps.minfps != cam_ctx->mini_fps) -+ { -+ cam_ctx->fps = cam_fps.fps; -+ cam_ctx->mini_fps = cam_fps.minfps; -+ ret = mt9v111_set_fps(cam_ctx->fps, cam_ctx->mini_fps); -+ } -+ -+ return ret; -+} -+/*set image style*/ -+static int pxa_cam_WCAM_VIDIOCSSTYLE(p_camera_context_t cam_ctx, void *param) -+{ -+ dbg_print("WCAM_VIDIOCSSTYLE"); -+ int ret=0; -+ if(cam_ctx->capture_style != (V4l_PIC_STYLE)param) -+ { -+ cam_ctx->capture_style = (V4l_PIC_STYLE)param; -+ ret = mt9v111_set_effects(cam_ctx); -+ } -+ return ret; -+} -+/*set video light*/ -+static int pxa_cam_WCAM_VIDIOCSLIGHT(p_camera_context_t cam_ctx, void *param) -+{ -+ dbg_print("WACM_VIDIOCSLIGHT"); -+ int ret=0; -+ if(cam_ctx->capture_light!= (V4l_PIC_WB)param) -+ { -+ cam_ctx->capture_light=(V4l_PIC_WB)param; -+ ret = mt9v111_set_effects(cam_ctx); -+ } -+ return ret; -+} -+/*set picture brightness*/ -+static int pxa_cam_WCAM_VIDIOCSBRIGHT(p_camera_context_t cam_ctx, void *param) -+{ -+ dbg_print("WCAM_VIDIOCSBRIGHT"); -+ int ret =0; -+ if( cam_ctx->capture_bright != (int)param) -+ { -+ cam_ctx->capture_bright = (int)param; -+ ret=mt9v111_set_bright(cam_ctx->capture_bright); -+ } -+ return ret; -+} -+static int pxa_cam_WCAM_VIDIOCSFLICKER(p_camera_context_t cam_ctx, void * param) -+{ -+ dbg_print("WCAM_VIDIOCSFLICKER"); -+ cam_ctx->flicker_freq = (int)param; -+ return mt9v111_set_flicker(cam_ctx->flicker_freq); -+} -+static int mt9v111_restore_property(p_camera_context_t cam_ctx) -+{ -+ adcm_window_size size; -+ -+ size.width = cam_ctx->sensor_width; -+ size.height= cam_ctx->sensor_height; -+ mt9v111_input_size(&size); -+ -+ camera_func_mt9v111_set_capture_format(cam_ctx); -+ -+ mt9v111_set_fps(cam_ctx->fps,cam_ctx->mini_fps); -+ -+ mt9v111_set_bright(cam_ctx->capture_bright); -+ -+ mt9v111_set_effects(cam_ctx); -+ -+ return 0; -+} -+int camera_func_mt9v111_pm_management(p_camera_context_t cam_ctx, int suspend) -+{ -+ static int resume_dma = 0; -+ if(suspend) -+ { -+ if(cam_ctx != NULL ) -+ { -+ if(cam_ctx->dma_started) -+ { -+ dbg_print("camera running, suspended"); -+ stop_dma_transfer(cam_ctx); -+ resume_dma = 1; -+ } -+ } -+ disable_irq(IRQ_CAMERA); -+ pxa_set_cken(CKEN24_CAMERA, 0); -+ } -+ else -+ { -+ pxa_set_cken(CKEN24_CAMERA, 1); -+ if(cam_ctx != NULL) -+ { -+ dbg_print("camera running, resumed"); -+ camera_init(cam_ctx); -+ mt9v111_restore_property(cam_ctx); -+ if(resume_dma == 1) -+ { -+ camera_start_video_capture(cam_ctx, 0); -+ resume_dma = 0; -+ } -+ } -+ enable_irq(IRQ_CAMERA); -+ } -+ return 0; -+} -+ -+int camera_func_mt9v111_docommand(p_camera_context_t cam_ctx, unsigned int cmd, void *param) -+{ -+ switch(cmd) -+ { -+ /*read mt9v111 registers*/ -+ case WCAM_VIDIOCGCAMREG: -+ return pxa_camera_WCAM_VIDIOCGCAMREG(cam_ctx, param); -+ -+ /*write mt9v111 registers*/ -+ case WCAM_VIDIOCSCAMREG: -+ return pxa_camera_WCAM_VIDIOCSCAMREG(cam_ctx, param); -+ -+ /*set sensor size */ -+ case WCAM_VIDIOCSSSIZE: -+ return pxa_cam_WCAM_VIDIOCSSSIZE(cam_ctx, param); -+ -+ /*set output size*/ -+ case WCAM_VIDIOCSOSIZE: -+ return pxa_cam_WCAM_VIDIOCSOSIZE(cam_ctx, param); -+ -+ /*set video mode fps*/ -+ case WCAM_VIDIOCSFPS: -+ return pxa_cam_WCAM_VIDIOCSFPS(cam_ctx, param); -+ -+ /*set picture style*/ -+ case WCAM_VIDIOCSSTYLE: -+ return pxa_cam_WCAM_VIDIOCSSTYLE(cam_ctx, param); -+ -+ /*set picture light*/ -+ case WCAM_VIDIOCSLIGHT: -+ return pxa_cam_WCAM_VIDIOCSLIGHT(cam_ctx, param); -+ -+ /*set picture brightness*/ -+ case WCAM_VIDIOCSBRIGHT: -+ return pxa_cam_WCAM_VIDIOCSBRIGHT(cam_ctx, param); -+ /*set flicker frequency*/ -+ case WCAM_VIDIOCSFLICKER: -+ return pxa_cam_WCAM_VIDIOCSFLICKER(cam_ctx, param); -+ default: -+ { -+ dbg_print("Error cmd=0x%x", cmd); -+ return -EFAULT; -+ } -+ } -+ return 0; -+ -+} -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ov9640.c linux-2.6.16.5-exz/drivers/media/video/ov9640.c ---- linux-2.6.16.5/drivers/media/video/ov9640.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ov9640.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,608 @@ -+/* -+ ov9640 - Omnivision 9640 CMOS sensor driver -+ -+ Copyright (C) 2003, Intel Corporation -+ -+ 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 program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ 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/types.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+#include <linux/videodev.h> -+ -+#include <asm/pgtable.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+ -+#include "camera.h" -+#include "ov9640.h" -+#include "ov9640_hw.h" -+ -+ -+#define MAX_WIDTH 1280 -+#define MAX_HEIGHT 960 -+#define MIN_WIDTH 88 -+#define MIN_HEIGHT 72 -+ -+#define MAX_BPP 16 -+#define WIDTH_DEFT 320 -+#define HEIGHT_DEFT 240 -+#define FRAMERATE_DEFT 0xf -+ -+/* -+ * It is required to have at least 3 frames in buffer -+ * in current implementation -+ */ -+#define FRAMES_IN_BUFFER 3 -+#define MIN_FRAMES_IN_BUFFER 3 -+#define MAX_FRAME_SIZE (MAX_WIDTH * MAX_HEIGHT * (MAX_BPP >> 3)) -+#define BUF_SIZE_DEFT (MAX_FRAME_SIZE ) -+#define SINGLE_DESC_TRANS_MAX PAGE_SIZE -+#define MAX_DESC_NUM ((MAX_FRAME_SIZE / SINGLE_DESC_TRANS_MAX + 1) *\ -+ MIN_FRAMES_IN_BUFFER) -+ -+#define MAX_BLOCK_NUM 20 -+extern ov9640 g_ov; -+ -+camera_function_t ov9640_func = { -+ .init = camera_func_ov9640_init, -+ .deinit = camera_func_ov9640_deinit, -+ .set_capture_format = camera_func_ov9640_set_capture_format, -+ .start_capture = camera_func_ov9640_start_capture, -+ .stop_capture = camera_func_ov9640_stop_capture, -+ .command = camera_func_ov9640_command, -+ .pm_management = camera_func_ov9640_pm, -+}; -+ -+/*********************************************************************** -+ * -+ * OV9640 Functions -+ * -+ ***********************************************************************/ -+static void ov9640_gpio_init() -+{ -+ -+ set_GPIO_mode(27 | GPIO_ALT_FN_3_IN); /* CIF_DD[0] */ -+ set_GPIO_mode(114 | GPIO_ALT_FN_1_IN); /* CIF_DD[1] */ -+ set_GPIO_mode(51 | GPIO_ALT_FN_1_IN); /* CIF_DD[2] */ -+ set_GPIO_mode(115 | GPIO_ALT_FN_2_IN); /* CIF_DD[3] */ -+ set_GPIO_mode(95 | GPIO_ALT_FN_2_IN); /* CIF_DD[4] */ -+ set_GPIO_mode(94 | GPIO_ALT_FN_2_IN); /* CIF_DD[5] */ -+ set_GPIO_mode(17 | GPIO_ALT_FN_2_IN); /* CIF_DD[6] */ -+ set_GPIO_mode(108 | GPIO_ALT_FN_1_IN); /* CIF_DD[7] */ -+ set_GPIO_mode(23 | GPIO_ALT_FN_1_OUT); /* CIF_MCLK */ -+ set_GPIO_mode(54 | GPIO_ALT_FN_3_IN); /* CIF_PCLK */ -+ set_GPIO_mode(85 | GPIO_ALT_FN_3_IN); /* CIF_LV */ -+ set_GPIO_mode(84 | GPIO_ALT_FN_3_IN); /* CIF_FV */ -+ set_GPIO_mode(50 | GPIO_OUT); /*CIF_PD */ -+ set_GPIO_mode(19 | GPIO_IN); /*CIF_RST */ -+ -+ -+ return; -+ -+} -+ -+void ov9640_set_clock(unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz) -+{ -+ unsigned int ciclk = 0, value, div, cccr_l, K; -+ -+ // determine the LCLK frequency programmed into the CCCR. -+ cccr_l = (CCCR & 0x0000001F); -+ -+ if (cccr_l < 8) // L = [2 - 7] -+ ciclk = (13 * cccr_l) * 100; -+ else if (cccr_l < 17) // L = [8 - 16] -+ ciclk = ((13 * cccr_l) * 100) >> 1; -+ else if (cccr_l < 32) // L = [17 - 31] -+ ciclk = ((13 * cccr_l) * 100) >> 2; -+ DPRINTK(KERN_WARNING "the mclk_khz = %d \n", mclk_khz); -+ -+ // want a divisor that gives us a clock rate as close to, but not more than the given mclk. -+ div = (ciclk + mclk_khz) / (2 * mclk_khz) - 1; -+ -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | CI_CICR4_DIV_SMASK << CI_CICR4_DIV_SHIFT); -+ value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0; -+ value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0; -+ value |= div << CI_CICR4_DIV_SHIFT; -+ CICR4 = value; -+ return; -+} -+ -+int camera_func_ov9640_init(p_camera_context_t cam_ctx) -+{ -+ u8 cm_rev, cm_pid; -+ u32 timeout; -+ int status; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ memset(pov, 0, sizeof(ov9640)); -+ -+ pov->pre_size = OV_SIZE_NONE; -+ pov->win.width = cam_ctx->capture_width; -+ pov->win.height = cam_ctx->capture_height; -+ // init context status -+ cam_ctx->dma_channels[0] = 0xFF; -+ cam_ctx->dma_channels[1] = 0xFF; -+ cam_ctx->dma_channels[2] = 0xFF; -+ -+ cam_ctx->capture_width = WIDTH_DEFT; -+ cam_ctx->capture_height = HEIGHT_DEFT; -+ -+ cam_ctx->capture_input_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ cam_ctx->capture_output_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ -+ cam_ctx->frame_rate = cam_ctx->fps = FRAMERATE_DEFT; -+ -+ cam_ctx->mini_fps = FRAMERATE_DEFT - 2; -+ -+ cam_ctx->buf_size = BUF_SIZE_DEFT; -+ cam_ctx->dma_descriptors_size = MAX_DESC_NUM; -+ DPRINTK(KERN_WARNING "dma_descriptors_size =%d,cam_ctx->buf_size=%d\n", cam_ctx->dma_descriptors_size, -+ cam_ctx->buf_size); -+ cam_ctx->vc.maxwidth = 1280; -+ cam_ctx->vc.maxheight = 960; -+ cam_ctx->vc.minwidth = MIN_WIDTH; -+ cam_ctx->vc.minheight = MIN_HEIGHT; -+ //DPRINTK( KERN_WARNING" before ov9640_gpio_init\n"); -+ ov9640_gpio_init(); -+ ci_init(); -+ // Configure CI according to OV9640's hardware -+ // master parallel with 8 data pins -+ ci_set_mode(CI_MODE_MP, CI_DATA_WIDTH8); -+ // enable pixel clock(sensor will provide pclock) and master clock = 26MHZ -+ //ci_set_clock(cam_ctx->clk_reg_base, 1, 1, 26); -+ ov9640_set_clock(cam_ctx->clk_reg_base, 1, 1, 2400); -+ pov->mclock = 24; -+ -+ // data sample on rising and h,vsync active high -+ ci_set_polarity(0, 0, 0); -+ -+ // fifo control -+ // CISetFIFO(cam_ctx->ci_reg_base, 4000, XLLP_CI_FIFO_THL_32, XLLP_TRUE, XLLP_TRUE); -+ ci_set_fifo(0, CI_FIFO_THL_32, 1, 1); -+ -+ // OV9640 Power on sequence -+ // Take out of Power down mode, PWRDWN=1, NORMAL=0 -+ // Assert Reset -+ // Delay -+ // Remove reset -+ // Delay -+ ov9640_power_down(0); -+ ov9640_reset(); -+ mdelay(1); -+ -+ // init I2C. -+ status = i2c_init(); -+ if (status) -+ return status; -+ -+ // 2 Turn on M_CLK using xx MHz and wait for 150 ms. ?? -+ ci_enable(1); -+ mdelay(20); -+ -+ // read out version -+ //timeout = 50; -+ timeout = 5; -+ do { -+ cm_pid = cm_rev = 0; -+ status = ov9640_version_revision(&cm_pid, &cm_rev); -+ -+ // Check to make sure we are working with an OV9640 -+ if (cm_pid == PID_OV && cm_rev == PID_9640) { -+ int ver = (PID_OV << 8) | (PID_9640); -+ pov->version = ver; -+ } -+ else if (cm_pid == PID_OV_v3 || cm_rev == PID_9640_v3) { -+ int ver = (PID_OV_v3 << 8) | (PID_9640_v3); -+ pov->version = ver; -+ } -+ else { -+ ov9640_power_down(1); -+ ov9640_power_down(0); -+ ov9640_reset(); -+ mdelay(1); -+ } -+ printk("in fun camera_func_ov9640_init version=%x\n", pov->version); -+ if (--timeout == 0) -+ return -1; -+ } -+ while (cm_pid != PID_OV); -+ -+ cam_ctx->sensor_type = CAMERA_TYPE_OMNIVISION_9640; -+ // turn sensor output off -+ ov9640_viewfinder_off(); -+ -+ return 0; -+} -+ -+int camera_func_ov9640_deinit(p_camera_context_t cam_ctx) -+{ -+ //init the prev_xx value. -+ ov9640_set_format(OV_SIZE_NONE, OV_FORMAT_NONE); -+ mdelay(20); -+ // power off the external module -+ ov9640_power_down(1); -+ -+ return 0; -+} -+ -+int camera_func_ov9640_sleep(p_camera_context_t cam_ctx) -+{ -+ camera_func_ov9640_deinit(cam_ctx); -+} -+ -+int camera_func_ov9640_wake(p_camera_context_t cam_ctx) -+{ -+ camera_func_ov9640_init(cam_ctx); -+} -+ -+static get_ov_format(p_camera_context_t cam_ctx, u32 * size_format, u32 * color_format) -+{ -+ u32 ovSizeFormat, ovFormat; -+ -+ // Set the current mode -+ switch (cam_ctx->capture_input_format) { -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ ovFormat = OV_FORMAT_YUV_422; -+ printk("in get_ov_format ovFormat = OV_FORMAT_YUV_422\n"); -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ ovFormat = OV_FORMAT_RGB_565; -+ break; -+ default: -+ printk(KERN_INFO "The Format doesn't support by OV9640 Sensor \n"); -+ return -1; -+ } -+ if (cam_ctx->capture_width == 88 && cam_ctx->capture_height == 72) -+ ovSizeFormat = OV_SIZE_QQCIF; -+ else if (cam_ctx->capture_width == 160 && cam_ctx->capture_height == 120) -+ ovSizeFormat = OV_SIZE_QQVGA; -+ else if (cam_ctx->capture_width == 176 && cam_ctx->capture_height == 144) -+ ovSizeFormat = OV_SIZE_QCIF; -+ else if (cam_ctx->capture_width == 320 && cam_ctx->capture_height == 240) -+ ovSizeFormat = OV_SIZE_QVGA; -+ else if (cam_ctx->capture_width == 352 && cam_ctx->capture_height == 288) -+ ovSizeFormat = OV_SIZE_CIF; -+ else if (cam_ctx->capture_width == 640 && cam_ctx->capture_height == 480) -+ ovSizeFormat = OV_SIZE_VGA; -+ else if (cam_ctx->capture_width == 1280 && cam_ctx->capture_height == 960) -+ ovSizeFormat = OV_SIZE_SXGA; -+ else { -+ return -1; -+ } -+ if (ovSizeFormat == OV_SIZE_QVGA) -+ printk("ovSizeFormat =OV_SIZE_QVGA \n"); -+ *size_format = ovSizeFormat; -+ *color_format = ovFormat; -+ return 0; -+} -+ -+int camera_func_ov9640_set_capture_format(p_camera_context_t cam_ctx) -+{ -+ CI_MP_TIMING timing; -+ int status = -1; -+ u32 ovSizeFormat, ovFormat; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ -+ status = get_ov_format(cam_ctx, &ovSizeFormat, &ovFormat); -+ if (status) -+ return -1; -+ -+ status = ov9640_set_format(ovSizeFormat, ovFormat); -+ if (status) -+ return -1; -+ -+ // set capture width/height and timing -+ //timing.BFW = pov->win.x; -+ //timing.BLW = pov->win.y; -+ timing.BFW = 0; -+ timing.BLW = 0; -+ //ci_configure_mp(pov->win.width - 1, pov->win.height - 1, &timing); -+ -+ return status; -+} -+ -+#define COPY_BUFFERS(pdes, p_page, size) \ -+do { \ -+ unsigned int len; \ -+ unsigned int remain_size = size; \ -+ while (remain_size > 0) { \ -+ if (remain_size > PAGE_SIZE) \ -+ len = PAGE_SIZE; \ -+ else \ -+ len = remain_size; \ -+ if (memcpy(page_address(*pdes), page_address(*p_page), len)) \ -+ return -EFAULT; \ -+ remain_size -= len; \ -+ pdes ++;\ -+ p_page++; \ -+ } \ -+} while (0); -+ -+int camera_func_ov9640_start_capture(p_camera_context_t cam_ctx, unsigned int frames) -+{ -+ int status = -1; -+ u32 ovSizeFormat, ovFormat; -+ ov9640 *pov; -+ u8 value; -+ -+ pov = &g_ov; -+ -+ ci_disable(1); -+ mdelay(1); -+ ci_enable(1); -+ // clear ci fifo -+ ci_reset_fifo(); -+ ci_clear_int_status(0xFFFFFFFF); -+ -+ camera_set_int_mask(cam_ctx, 0x3ff | 0x0400); -+ // turn auto function on only doing continues capture -+ if (frames == 0) { -+// CISR |= (1 << 3); -+// while (!(CISR & (1 << 3))); //Wait a EOF then begin start DMA -+ ov9640_auto_function_on(); -+ // start dma -+ start_dma_transfer(cam_ctx, 0); -+ } -+ else { -+ status = get_ov_format(cam_ctx, &ovSizeFormat, &ovFormat); -+ if (status) -+ return -1; -+ if (pov->pre_size == OV_SIZE_NONE) -+ return -1; -+ printk("in function %s, cam_ctx->block_tail == 0\n", __FUNCTION__); -+ if (pov->pre_size == ovSizeFormat) { -+ if (cam_ctx->block_tail == 0) { -+ } -+ else { -+ struct page **p_page; -+ struct page **pdes; -+ -+ printk("in function %s, cam_ctx->block_tail != 0\n", __FUNCTION__); -+ p_page = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ pdes = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ COPY_BUFFERS(pdes, p_page, cam_ctx->fifo0_transfer_size); -+ COPY_BUFFERS(pdes, p_page, cam_ctx->fifo1_transfer_size); -+ COPY_BUFFERS(pdes, p_page, cam_ctx->fifo2_transfer_size); -+ } -+ set_still_image_ready(1); -+ return 0; -+ } -+ else { -+ ov9640_auto_function_off(); -+ cam_ctx->block_tail = cam_ctx->block_header = 0; -+ ov9640_prepare_capture(cam_ctx, ovSizeFormat, ovFormat); -+ } -+ // turn viewfinder on -+ ov9640_viewfinder_on(); -+ } -+ // turn viewfinder on -+ ov9640_viewfinder_on(); -+ ov9640_read(0xc, &value); -+ ov9640_set_start(); -+ return 0; -+} -+ -+int Ov9640AutoFunctionOn() -+{ -+ u8 regValue; -+ -+ printk("in function %s \n", __FUNCTION__); -+ ov9640_read(0x13, ®Value); -+ if ((regValue & 0x7) == 7) -+ return 1; -+ return 0; -+} -+ -+int camera_func_ov9640_stop_capture(p_camera_context_t cam_ctx) -+{ -+ if (ov9640_output_stoped()) -+ return 0; -+ printk("in camera_func_ov9640_stop_capture\n"); -+ //if (Ov9640AutoFunctionOn()) -+ ov9640_save_gains(); -+ // turn auto function off -+ //ov9640_auto_function_off(); -+ -+ // turn viewfinder off -+ ov9640_viewfinder_off(); -+ stop_dma_transfer(cam_ctx); -+ ov9640_set_stop(cam_ctx); -+ return 0; -+} -+ -+int camera_func_ov9640_command(p_camera_context_t cam_ctx, unsigned int cmd, void *param) -+{ -+ int ret = 0; -+ -+ printk("in function %s, param =%d, \n", __FUNCTION__, param); -+ switch (cmd) { -+ /* get capture size */ -+ case VIDIOCGWIN: -+ { -+ struct video_window vw; -+ vw.width = cam_ctx->capture_width; -+ vw.height = cam_ctx->capture_height; -+ ov9640_get_window(&vw); -+ if (copy_to_user(param, &vw, sizeof(struct video_window))) -+ ret = -EFAULT; -+ break; -+ } -+ -+ /* set capture size. */ -+ case VIDIOCSWIN: -+ { -+ struct video_window vw; -+ if (copy_from_user(&vw, param, sizeof(vw))) { -+ ret = -EFAULT; -+ break; -+ } -+ printk("in %s, vw-x =%d, vw-y=%d,vw.width=%d,vw.height=%d\n", -+ __FUNCTION__, vw.x, vw.y, vw.width, vw.height); -+ if (vw.width > 1280 || vw.height > 960 || vw.width < MIN_WIDTH || vw.height < MIN_HEIGHT) { -+ ret = -EFAULT; -+ break; -+ } -+ /* -+ */ -+ ov9640_set_window(&vw); -+ cam_ctx->capture_width = vw.width; -+ cam_ctx->capture_height = vw.height; -+ camera_set_capture_format(cam_ctx); -+ break; -+ } -+ /*set picture style */ -+ case WCAM_VIDIOCSSTYLE: -+ { -+ V4l_PIC_STYLE capture_style; -+ capture_style = (V4l_PIC_STYLE) param; -+ cam_ctx->capture_style = (V4l_PIC_STYLE) param; -+ //ret = ov9640_set_special_effect(capture_style); -+ printk("in camera_func_ov9640_command ret=%d\n", ret); -+ if (cam_ctx->capture_style != V4l_STYLE_BLACK_WHITE && cam_ctx->capture_style != V4l_STYLE_SEPIA) { -+ } -+ } -+ break; -+ /*set picture light */ -+ case WCAM_VIDIOCSLIGHT: -+ cam_ctx->capture_light = (int) param; -+ ret = ov9640_set_white_balance(param); -+ break; -+ /*set picture brightness */ -+ case WCAM_VIDIOCSBRIGHT: -+ cam_ctx->capture_bright = (int) param; -+ //ret = ov9640_set_expose_compensation((int) param); -+ ret = ov9640_set_brightness((int) param); -+ break; -+ /*set sensor size */ -+ case WCAM_VIDIOCSSSIZE: -+ return ov9640_set_sensor_size(cam_ctx, param); -+ -+ /*get sensor size */ -+ case WCAM_VIDIOCGSSIZE: -+ return ov9640_get_sensor_size(cam_ctx, param); -+ -+ /*set output size */ -+ case WCAM_VIDIOCSOSIZE: -+ return ov9640_set_output_size(cam_ctx, param); -+ -+ /*get output size */ -+ case WCAM_VIDIOCGOSIZE: -+ return ov9640_get_output_size(cam_ctx, param); -+#if 0 -+#endif -+ /*set video mode fps */ -+ case WCAM_VIDIOCSFPS: -+ { -+ struct { -+ int fps, minfps; -+ } cam_fps; -+ DPRINTK("WCAM_VIDIOCSFPS"); -+ if (copy_from_user(&cam_fps, param, sizeof(int) * 2)) { -+ return -EFAULT; -+ } -+ cam_ctx->fps = cam_fps.fps; -+ cam_ctx->mini_fps = cam_fps.minfps; -+ return ov9640_set_fps(cam_fps.fps, cam_fps.minfps); -+ } -+ return -1; -+ case WCAM_VIDIOCSNIGHTMODE: -+ { -+ struct { -+ int mode, maxexpottime; -+ } cam_mode; -+ int mode; -+ if (copy_from_user(&cam_mode, param, sizeof(cam_mode))) { -+ return -EFAULT; -+ } -+ mode = cam_mode.mode; -+ if (mode == V4l_NM_NIGHT) -+ ov9640_set_night_mode(); -+ if (mode == V4l_NM_ACTION) -+ ov9640_set_action_mode(); -+ if (mode == V4l_NM_AUTO) -+ ov9640_set_auto_mode(); -+ } -+ break; -+ case WCAM_VIDIOCSCONTRAST: -+ { -+ DPRINTK("WCAM_VIDIOCSCONTRAST parameter=%d",param); -+ ret = ov9640_set_contrast((int)param/50); -+ break; -+ } -+ case WCAM_VIDIOCSFLICKER: -+ { -+ ret = ov9640_set_light_environment(param); -+ break; -+ } -+ default: -+ printk("in %s default case -----------------cmd =%d param=%d\n", __FUNCTION__, cmd, param); -+ ret = -1; -+ } -+ return ret; -+} -+int camera_func_ov9640_pm(p_camera_context_t cam_ctx, int suspend) -+{ -+ static int resume_dma = 0; -+ if (suspend) { -+ if (cam_ctx != NULL) { -+ if (cam_ctx->dma_started) { -+ dbg_print("camera running, suspended"); -+ stop_dma_transfer(cam_ctx); -+ resume_dma = 1; -+ } -+ } -+ -+ disable_irq(IRQ_CAMERA); -+ CKEN &= ~CKEN24_CAMERA; -+ } -+ else { -+ CKEN |= CKEN24_CAMERA; -+ enable_irq(IRQ_CAMERA); -+ -+ if (cam_ctx != NULL) { -+ dbg_print("camera running, resumed"); -+ camera_init(cam_ctx); -+ //ov9640_restore_property(cam_ctx, 0); -+ -+ -+ if (resume_dma == 1) { -+ camera_start_video_capture(cam_ctx, 0); -+ resume_dma = 0; -+ } -+ } -+ } -+ return 0; -+} -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ov9640.h linux-2.6.16.5-exz/drivers/media/video/ov9640.h ---- linux-2.6.16.5/drivers/media/video/ov9640.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ov9640.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,67 @@ -+/* -+ ov9640 - Omnivision 9640 CMOS sensor driver -+ -+ Copyright (C) 2003, Intel Corporation -+ -+ 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 program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ 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 _OV_9640_H_ -+#define _OV_9640_H_ -+ -+#include <linux/videodev.h> -+#include "camera.h" -+typedef struct { -+ u32 version; -+ u32 stoped; -+ u32 mclock; -+ u32 pre_size; -+ u32 exp_value; -+ u32 exp_time; -+ u32 adjusted_exp_value; -+ u32 adjusted_exp_time; -+ u8 pclock; -+ u8 gain; -+ u8 blue_gain; -+ u8 red_gain; -+ u8 y_average; -+ u32 sensor_width; -+ u32 sensor_height; -+ u32 sub_win; -+ u32 night_mode; -+ struct video_window win; -+}ov9640; -+ -+////////////////////////////////////////////////////////////////////////////////////// -+// -+// Prototypes -+// -+////////////////////////////////////////////////////////////////////////////////////// -+ -+int camera_func_ov9640_init( p_camera_context_t ); -+ -+int camera_func_ov9640_deinit( p_camera_context_t ); -+ -+int camera_func_ov9640_sleep( p_camera_context_t camera_context ); -+ -+int camera_func_ov9640_wake( p_camera_context_t camera_context ); -+ -+int camera_func_ov9640_set_capture_format( p_camera_context_t ); -+ -+int camera_func_ov9640_start_capture( p_camera_context_t, unsigned int frames ); -+ -+int camera_func_ov9640_stop_capture( p_camera_context_t ); -+ -+int camera_func_ov9640_pm(p_camera_context_t cam_ctx, int suspend); -+#endif -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ov9640_hw.c linux-2.6.16.5-exz/drivers/media/video/ov9640_hw.c ---- linux-2.6.16.5/drivers/media/video/ov9640_hw.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ov9640_hw.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,3034 @@ -+/* -+ ov9640_hw - Omnivision 9640 CMOS sensor driver -+ -+ Copyright (C) 2003, Intel Corporation -+ -+ 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 program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ 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/types.h> -+#include <linux/mm.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/wrapper.h> -+#include <linux/delay.h> -+#include <linux/videodev.h> -+#include <asm/mach-types.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/mach-types.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+ -+#include <linux/i2c.h> -+#include "camera.h" -+#include "ov9640.h" -+#include "ov9640_hw.h" -+ -+ov9640 g_ov; -+/*********************************************************************** -+* Attention: This is platform related! -+***********************************************************************/ -+static const u32 OV9640_PWRDWN_GPIO[2] = { 1, 50 }; -+//static const u32 OV9640_RESET_GPIO[2] = { 1, xxx }; -+volatile int ov9640_step = 0; -+ -+/*********************************************************************** -+* Register Settings -+***********************************************************************/ -+static u8 gDelta[] = { -+ OV9640_COM7, //0x12 -+ OV9640_COM1, //0x04 -+// OV9640_CLKRC, //0x11 -+ OV9640_COM4, //0x0d -+ OV9640_COM3, //0x0c -+ OV9640_REGEND // End of list delimiter. -+}; -+const static u8 gYUV_QQVGA[] = { -+ OV9640_COM10, 0x20, -+ OV9640_COM7, 0x10, -+ OV9640_COM1, 0x24, -+ OV9640_CLKRC, 0x01, -+ -+ // From OmniVision -+ OV9640_COM8, 0x8D, -+ OV9640_BLUE, 0x80, -+ OV9640_RED, 0x80, -+ OV9640_COM3, 0x5, //0x04 -+ OV9640_COM4, 0xC0, -+ OV9640_COM6, 0x4E, //0x4F -+ OV9640_COM9, 0x4A, //0x0A -+ OV9640_PSHFT, 0x1, -+ OV9640_AEW, 0x78, -+ OV9640_AEB, 0x70, -+ OV9640_BBIAS, 0x90, -+ OV9640_CHLF, 0x8, -+ OV9640_VIDO, 0xC9, -+ OV9640_TSLB, 0x8, -+ OV9640_COM11, 0x8, -+ OV9640_COM12, 0x46, -+ OV9640_COM13, 0x90, -+ OV9640_COM14, 0x2, -+ OV9640_EDGE, 0xA4, -+ OV9640_COM16, 0x2, -+ OV9640_COM17, 0xC8, -+ OV9640_AWBTH1, 0xF0, -+ OV9640_AWBTH2, 0x10, -+ OV9640_AWBTH3, 0x5C, -+ OV9640_AWBTH4, 0x70, -+ OV9640_AWBTH5, 0x46, -+ OV9640_AWBTH6, 0x4D, -+ OV9640_MTX1, 0x63, -+ OV9640_MTX2, 0x4E, -+ OV9640_MTX3, 0x15, -+ OV9640_MTX4, 0x1D, -+ OV9640_MTX5, 0xBE, -+ OV9640_MTX6, 0xDC, -+ OV9640_MTXS, 0xF, -+ OV9640_AWBC1, 0x1F, -+ OV9640_AWBC2, 0x55, -+ OV9640_AWBC3, 0x43, -+ OV9640_AWBC4, 0x7C, -+ OV9640_AWBC5, 0x54, -+ OV9640_AWBC6, 0xA, -+ OV9640_AWBC7, 0x5, -+ OV9640_AWBC8, 0x14, -+ OV9640_AWBC9, 0xCE, -+ OV9640_DBLV, 0x3A, -+ OV9640_GST0, 0x2, -+ OV9640_GSP0, 0x40, -+ OV9640_GSP1, 0x30, -+ OV9640_GSP2, 0x4B, -+ OV9640_GSP3, 0x60, -+ OV9640_GSP4, 0x70, -+ OV9640_GSP5, 0x70, -+ OV9640_GSP6, 0x70, -+ OV9640_GSP7, 0x70, -+ OV9640_GSP8, 0x60, -+ OV9640_GSP9, 0x60, -+ OV9640_GSP10, 0x50, -+ OV9640_GSP11, 0x48, -+ OV9640_GSP12, 0x3A, -+ OV9640_GSP13, 0x2E, -+ OV9640_GSP14, 0x28, -+ OV9640_GSP15, 0x22, -+ OV9640_GST0, 0x4, -+ OV9640_GST1, 0x7, -+ OV9640_GST2, 0x10, -+ OV9640_GST3, 0x28, -+ OV9640_GST4, 0x36, -+ OV9640_GST5, 0x44, -+ OV9640_GST6, 0x52, -+ OV9640_GST7, 0x60, -+ OV9640_GST8, 0x6C, -+ OV9640_GST9, 0x78, -+ OV9640_GST10, 0x8C, -+ OV9640_GST11, 0x9E, -+ OV9640_GST12, 0xBB, -+ OV9640_GST13, 0xD2, -+ OV9640_GST14, 0xE6, -+ OV9640_COM8, 0x8F, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_QQCIF[] = { -+ OV9640_COM10, 0x20, -+ OV9640_COM7, 0x08, -+ OV9640_COM1, 0x24, -+ OV9640_CLKRC, 0x01, -+ -+ // From OmniVision -+ OV9640_COM8, 0x8D, -+ OV9640_BLUE, 0x80, -+ OV9640_RED, 0x80, -+ OV9640_COM3, 0x5, //0x04 -+ OV9640_COM4, 0xC0, -+ OV9640_COM6, 0x4E, //0x4F -+ OV9640_COM9, 0x4A, //0x0A -+ OV9640_PSHFT, 0x1, -+ OV9640_AEW, 0x78, -+ OV9640_AEB, 0x70, -+ OV9640_BBIAS, 0x90, -+ OV9640_CHLF, 0x8, -+ OV9640_VIDO, 0xC9, -+ OV9640_TSLB, 0x8, -+ OV9640_COM11, 0x8, -+ OV9640_COM12, 0x46, -+ OV9640_COM13, 0x90, -+ OV9640_COM14, 0x2, -+ OV9640_EDGE, 0xA4, -+ OV9640_COM16, 0x2, -+ OV9640_COM17, 0xC8, -+ OV9640_AWBTH1, 0xF0, -+ OV9640_AWBTH2, 0x10, -+ OV9640_AWBTH3, 0x5C, -+ OV9640_AWBTH4, 0x70, -+ OV9640_AWBTH5, 0x46, -+ OV9640_AWBTH6, 0x4D, -+ OV9640_MTX1, 0x63, -+ OV9640_MTX2, 0x4E, -+ OV9640_MTX3, 0x15, -+ OV9640_MTX4, 0x1D, -+ OV9640_MTX5, 0xBE, -+ OV9640_MTX6, 0xDC, -+ OV9640_MTXS, 0xF, -+ OV9640_AWBC1, 0x1F, -+ OV9640_AWBC2, 0x55, -+ OV9640_AWBC3, 0x43, -+ OV9640_AWBC4, 0x7C, -+ OV9640_AWBC5, 0x54, -+ OV9640_AWBC6, 0xA, -+ OV9640_AWBC7, 0x5, -+ OV9640_AWBC8, 0x14, -+ OV9640_AWBC9, 0xCE, -+ OV9640_DBLV, 0x3A, -+ OV9640_GST0, 0x2, -+ OV9640_GSP0, 0x40, -+ OV9640_GSP1, 0x30, -+ OV9640_GSP2, 0x4B, -+ OV9640_GSP3, 0x60, -+ OV9640_GSP4, 0x70, -+ OV9640_GSP5, 0x70, -+ OV9640_GSP6, 0x70, -+ OV9640_GSP7, 0x70, -+ OV9640_GSP8, 0x60, -+ OV9640_GSP9, 0x60, -+ OV9640_GSP10, 0x50, -+ OV9640_GSP11, 0x48, -+ OV9640_GSP12, 0x3A, -+ OV9640_GSP13, 0x2E, -+ OV9640_GSP14, 0x28, -+ OV9640_GSP15, 0x22, -+ OV9640_GST0, 0x4, -+ OV9640_GST1, 0x7, -+ OV9640_GST2, 0x10, -+ OV9640_GST3, 0x28, -+ OV9640_GST4, 0x36, -+ OV9640_GST5, 0x44, -+ OV9640_GST6, 0x52, -+ OV9640_GST7, 0x60, -+ OV9640_GST8, 0x6C, -+ OV9640_GST9, 0x78, -+ OV9640_GST10, 0x8C, -+ OV9640_GST11, 0x9E, -+ OV9640_GST12, 0xBB, -+ OV9640_GST13, 0xD2, -+ OV9640_GST14, 0xE6, -+ OV9640_COM8, 0x8F, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_QVGA1[] = { -+ OV9640_COM10, 0x20, -+ OV9640_COM7, 0x10, -+ OV9640_COM1, 0x00, -+ OV9640_CLKRC, 0x01, -+ -+ // From OmniVision -+ OV9640_COM8, 0x8D, -+ OV9640_BLUE, 0x80, -+ OV9640_RED, 0x80, -+ OV9640_COM3, 0x5, //0x04 -+ OV9640_COM4, 0xC0, -+ OV9640_COM6, 0x4E, //0x4F -+ OV9640_COM9, 0x4A, //0x0A -+ OV9640_PSHFT, 0x1, -+ OV9640_AEW, 0x78, -+ OV9640_AEB, 0x70, -+ OV9640_BBIAS, 0x90, -+ OV9640_CHLF, 0x8, -+ OV9640_VIDO, 0xC9, -+ OV9640_TSLB, 0x8, -+ OV9640_COM11, 0x8, -+ OV9640_COM12, 0x46, -+ OV9640_COM13, 0x90, -+ OV9640_COM14, 0x2, -+ OV9640_EDGE, 0xA4, -+ OV9640_COM16, 0x2, -+ OV9640_COM17, 0xC8, -+ OV9640_AWBTH1, 0xF0, -+ OV9640_AWBTH2, 0x10, -+ OV9640_AWBTH3, 0x5C, -+ OV9640_AWBTH4, 0x70, -+ OV9640_AWBTH5, 0x46, -+ OV9640_AWBTH6, 0x4D, -+ OV9640_MTX1, 0x63, -+ OV9640_MTX2, 0x4E, -+ OV9640_MTX3, 0x15, -+ OV9640_MTX4, 0x1D, -+ OV9640_MTX5, 0xBE, -+ OV9640_MTX6, 0xDC, -+ OV9640_MTXS, 0xF, -+ /* -+ OV9640_MTX1 , 0x3c, -+ OV9640_MTX2 , 0x32, -+ OV9640_MTX3 , 0x09, -+ OV9640_MTX4 , 0x13, -+ OV9640_MTX5 , 0x39, -+ OV9640_MTX6 , 0x4c, -+ */ -+ -+ OV9640_AWBC1, 0x1F, -+ OV9640_AWBC2, 0x55, -+ OV9640_AWBC3, 0x43, -+ OV9640_AWBC4, 0x7C, -+ OV9640_AWBC5, 0x54, -+ OV9640_AWBC6, 0xA, -+ OV9640_AWBC7, 0x5, -+ OV9640_AWBC8, 0x14, -+ OV9640_AWBC9, 0xCE, -+ OV9640_DBLV, 0x3A, -+ OV9640_GST0, 0x2, -+ OV9640_GSP0, 0x40, -+ OV9640_GSP1, 0x30, -+ OV9640_GSP2, 0x4B, -+ OV9640_GSP3, 0x60, -+ OV9640_GSP4, 0x70, -+ OV9640_GSP5, 0x70, -+ OV9640_GSP6, 0x70, -+ OV9640_GSP7, 0x70, -+ OV9640_GSP8, 0x60, -+ OV9640_GSP9, 0x60, -+ OV9640_GSP10, 0x50, -+ OV9640_GSP11, 0x48, -+ OV9640_GSP12, 0x3A, -+ OV9640_GSP13, 0x2E, -+ OV9640_GSP14, 0x28, -+ OV9640_GSP15, 0x22, -+ OV9640_GST0, 0x4, -+ OV9640_GST1, 0x7, -+ OV9640_GST2, 0x10, -+ OV9640_GST3, 0x28, -+ OV9640_GST4, 0x36, -+ OV9640_GST5, 0x44, -+ OV9640_GST6, 0x52, -+ OV9640_GST7, 0x60, -+ OV9640_GST8, 0x6C, -+ OV9640_GST9, 0x78, -+ OV9640_GST10, 0x8C, -+ OV9640_GST11, 0x9E, -+ OV9640_GST12, 0xBB, -+ OV9640_GST13, 0xD2, -+ OV9640_GST14, 0xE6, -+ OV9640_COM8, 0x8F, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_VGA[] = { -+ 0x15, 0x20, -+ 0x12, 0x40, -+ 0x04, 0x00, -+ 0x11, 0x83, -+ //0x01 , 0x80, -+ //0x02 , 0x80, -+ 0x0C, 0x05, -+ 0x0D, 0xC0, -+ 0x0E, 0x01, -+ 0x0F, 0x4F, -+ 0x13, 0x82, //0x80 -+ 0x14, 0x4A, -+ 0x1B, 0x01, -+ 0x24, 0x78, -+ 0x25, 0x70, -+ 0x27, 0x90, -+ 0x33, 0x08, -+ 0x36, 0xC9, -+ 0x3A, 0x08, -+ 0x3B, 0x00, -+ 0x3C, 0x46, -+ 0x3D, 0x90, -+ 0x3E, 0x02, -+ 0x3F, 0xF2, -+ 0x41, 0x02, -+ 0x42, 0xC8, -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x5C, -+ 0x46, 0x70, -+ 0x47, 0x46, -+ 0x48, 0x4D, -+ 0x4F, 0x3C, -+ 0x50, 0x32, -+ 0x51, 0x09, -+ 0x52, 0x13, -+ 0x53, 0x39, -+ 0x54, 0x4C, -+ 0x59, 0x1F, -+ 0x5A, 0x55, -+ 0x5B, 0x43, -+ 0x5C, 0x7C, -+ 0x5D, 0x54, -+ 0x5E, 0x0A, -+ 0x5F, 0x01, -+ 0x60, 0x94, -+ 0x61, 0xCE, -+ 0x6B, 0x3A, -+ 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, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+const static u8 gYUV_QVGA[] = { -+ 0x15, 0x20, -+ 0x12, 0x10, -+ 0x04, 0x00, -+ 0x11, 0x81, -+ 0x01, 0x80, -+ 0x02, 0x24, -+ 0x0C, 0x05, -+ 0x0D, 0xC0, -+ 0x0E, 0x01, -+ 0x0F, 0x4F, -+ 0x13, 0x80, //0x82 -+ 0x14, 0x8A, -+ 0x1B, 0x01, -+ 0x24, 0x90, -+ 0x25, 0x80, -+ 0x2A, 0x00, -+ 0x2b, 0x00, -+ 0x27, 0x90, -+ 0x33, 0x08, -+ 0x36, 0xC9, -+ 0x3A, 0x08, -+ 0x3B, 0x00, -+ 0x3C, 0x46, -+ 0x3D, 0x90, -+ 0x3E, 0x02, -+ 0x3F, 0xa4, -+ 0x41, 0x02, -+ 0x42, 0xC8, -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x5C, -+ 0x46, 0x70, -+ 0x47, 0x46, -+ 0x48, 0x4D, -+ 0x4F, 0x3C, -+ 0x50, 0x32, -+ 0x51, 0x09, -+ 0x52, 0x13, -+ 0x53, 0x39, -+ 0x54, 0x4C, -+ 0x59, 0x1F, -+ 0x5A, 0x55, -+ 0x5B, 0x43, -+ 0x5C, 0x7C, -+ 0x5D, 0x54, -+ 0x5E, 0x0A, -+ 0x5F, 0x01, -+ 0x60, 0x94, -+ 0x61, 0xCE, -+ 0x6B, 0x3A, -+ 0x6C, 0x50, -+ 0x6D, 0x60, -+ 0x6E, 0x58, -+ 0x6F, 0x58, -+ 0x70, 0x58, -+ 0x71, 0x50, -+ 0x72, 0x50, -+ 0x73, 0x50, -+ 0x74, 0x50, -+ 0x75, 0x50, -+ 0x76, 0x4c, -+ 0x77, 0x4c, -+ 0x78, 0x45, -+ 0x79, 0x3c, -+ 0x7A, 0x2c, -+ 0x7B, 0x24, -+ 0x7C, 0x05, -+ 0x7D, 0x0b, -+ 0x7E, 0x16, -+ 0x7F, 0x2c, -+ 0x80, 0x37, -+ 0x81, 0x41, -+ 0x82, 0x4b, -+ 0x83, 0x55, -+ 0x84, 0x5f, -+ 0x85, 0x69, -+ 0x86, 0x7C, -+ 0x87, 0x8f, -+ 0x88, 0xB1, -+ 0x89, 0xcf, -+ 0x8A, 0xE5, -+ 0x13, 0xad, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+const static u8 gYUV_CIF[] = { -+ 0x15, 0x20, -+ 0x12, 0x20, -+ 0x04, 0x00, -+ 0x11, 0x87, -+ //0x01 , 0x80, -+ //0x02 , 0x80, -+ 0x0C, 0x05, -+ 0x0D, 0xC0, -+ 0x0E, 0x01, -+ 0x0F, 0x4F, -+ 0x13, 0x80, -+ 0x14, 0x4A, -+ 0x1B, 0x01, -+ 0x24, 0x78, -+ 0x25, 0x70, -+ 0x27, 0x90, -+ 0x33, 0x08, -+ 0x36, 0xC9, -+ 0x3A, 0x08, -+ 0x3B, 0x00, -+ 0x3C, 0x46, -+ 0x3D, 0x90, -+ 0x3E, 0x02, -+ 0x3F, 0xF2, -+ 0x41, 0x02, -+ 0x42, 0xC8, -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x5C, -+ 0x46, 0x70, -+ 0x47, 0x46, -+ 0x48, 0x4D, -+ 0x4F, 0x3C, -+ 0x50, 0x32, -+ 0x51, 0x09, -+ 0x52, 0x13, -+ 0x53, 0x39, -+ 0x54, 0x4C, -+ 0x59, 0x1F, -+ 0x5A, 0x55, -+ 0x5B, 0x43, -+ 0x5C, 0x7C, -+ 0x5D, 0x54, -+ 0x5E, 0x0A, -+ 0x5F, 0x01, -+ 0x60, 0x94, -+ 0x61, 0xCE, -+ 0x6B, 0x3A, -+ 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, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+#if 0 -+#endif -+const static u8 gYUV_QCIF[] = { -+ 0x15, 0x20, -+ 0x12, 0x08, -+ 0x04, 0x00, -+ 0x11, 0x87, -+ //0x01 , 0x80, -+ //0x02 , 0x80, -+ 0x0C, 0x05, -+ 0x0D, 0xC0, -+ 0x0E, 0x01, -+ 0x0F, 0x4F, -+ 0x13, 0x80, -+ 0x14, 0x4A, -+ 0x1B, 0x01, -+ 0x24, 0x78, -+ 0x25, 0x70, -+ 0x27, 0x90, -+ 0x33, 0x08, -+ 0x36, 0xC9, -+ 0x3A, 0x08, -+ 0x3B, 0x00, -+ 0x3C, 0x46, -+ 0x3D, 0x90, -+ 0x3E, 0x02, -+ 0x3F, 0xF2, -+ 0x41, 0x02, -+ 0x42, 0xC8, -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x5C, -+ 0x46, 0x70, -+ 0x47, 0x46, -+ 0x48, 0x4D, -+ 0x4F, 0x3C, -+ 0x50, 0x32, -+ 0x51, 0x09, -+ 0x52, 0x13, -+ 0x53, 0x39, -+ 0x54, 0x4C, -+ 0x59, 0x1F, -+ 0x5A, 0x55, -+ 0x5B, 0x43, -+ 0x5C, 0x7C, -+ 0x5D, 0x54, -+ 0x5E, 0x0A, -+ 0x5F, 0x01, -+ 0x60, 0x94, -+ 0x61, 0xCE, -+ 0x6B, 0x3A, -+ 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, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+const static u8 gYUV_QCIF1[] = { -+ OV9640_COM10, 0x20, -+ OV9640_COM7, 0x08, -+ OV9640_COM1, 0x00, -+ OV9640_CLKRC, 0x01, -+ -+ // From OmniVision -+ OV9640_COM8, 0x8D, -+ OV9640_BLUE, 0x80, -+ OV9640_RED, 0x80, -+ OV9640_COM3, 0x5, //0x04 -+ OV9640_COM4, 0xC0, -+ OV9640_COM6, 0x4E, //0x4F -+ OV9640_COM9, 0x4A, //0x0A -+ OV9640_PSHFT, 0x1, -+ OV9640_AEW, 0x78, -+ OV9640_AEB, 0x70, -+ OV9640_BBIAS, 0x90, -+ OV9640_CHLF, 0x8, -+ OV9640_VIDO, 0xC9, -+ OV9640_TSLB, 0x8, -+ OV9640_COM11, 0x8, -+ OV9640_COM12, 0x46, -+ OV9640_COM13, 0x90, -+ OV9640_COM14, 0x2, -+ OV9640_EDGE, 0xA4, -+ OV9640_COM16, 0x2, -+ OV9640_COM17, 0xC8, -+ OV9640_AWBTH1, 0xF0, -+ OV9640_AWBTH2, 0x10, -+ OV9640_AWBTH3, 0x5C, -+ OV9640_AWBTH4, 0x70, -+ OV9640_AWBTH5, 0x46, -+ OV9640_AWBTH6, 0x4D, -+ OV9640_MTX1, 0x63, -+ OV9640_MTX2, 0x4E, -+ OV9640_MTX3, 0x15, -+ OV9640_MTX4, 0x1D, -+ OV9640_MTX5, 0xBE, -+ OV9640_MTX6, 0xDC, -+ OV9640_MTXS, 0xF, -+ OV9640_AWBC1, 0x1F, -+ OV9640_AWBC2, 0x55, -+ OV9640_AWBC3, 0x43, -+ OV9640_AWBC4, 0x7C, -+ OV9640_AWBC5, 0x54, -+ OV9640_AWBC6, 0xA, -+ OV9640_AWBC7, 0x5, -+ OV9640_AWBC8, 0x14, -+ OV9640_AWBC9, 0xCE, -+ OV9640_DBLV, 0x3A, -+ OV9640_GST0, 0x2, -+ OV9640_GSP0, 0x40, -+ OV9640_GSP1, 0x30, -+ OV9640_GSP2, 0x4B, -+ OV9640_GSP3, 0x60, -+ OV9640_GSP4, 0x70, -+ OV9640_GSP5, 0x70, -+ OV9640_GSP6, 0x70, -+ OV9640_GSP7, 0x70, -+ OV9640_GSP8, 0x60, -+ OV9640_GSP9, 0x60, -+ OV9640_GSP10, 0x50, -+ OV9640_GSP11, 0x48, -+ OV9640_GSP12, 0x3A, -+ OV9640_GSP13, 0x2E, -+ OV9640_GSP14, 0x28, -+ OV9640_GSP15, 0x22, -+ OV9640_GST0, 0x4, -+ OV9640_GST1, 0x7, -+ OV9640_GST2, 0x10, -+ OV9640_GST3, 0x28, -+ OV9640_GST4, 0x36, -+ OV9640_GST5, 0x44, -+ OV9640_GST6, 0x52, -+ OV9640_GST7, 0x60, -+ OV9640_GST8, 0x6C, -+ OV9640_GST9, 0x78, -+ OV9640_GST10, 0x8C, -+ OV9640_GST11, 0x9E, -+ OV9640_GST12, 0xBB, -+ OV9640_GST13, 0xD2, -+ OV9640_GST14, 0xE6, -+ OV9640_COM8, 0x8F, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+ -+const static u8 gYUV_VGA1[] = { -+ OV9640_COM10, 0x20, -+ OV9640_COM7, 0x40, -+ OV9640_COM1, 0x00, -+ OV9640_CLKRC, 0x00, -+ -+ // From OmniVision -+ OV9640_COM8, 0x8D, -+ OV9640_BLUE, 0x80, -+ OV9640_RED, 0x80, -+ OV9640_COM3, 0x5, //0x04 -+ OV9640_COM4, 0x40, -+ OV9640_COM6, 0x4E, //0x4F -+ OV9640_COM9, 0x4A, //0x0A -+ OV9640_PSHFT, 0x1, -+ OV9640_AEW, 0x78, -+ OV9640_AEB, 0x70, -+ OV9640_BBIAS, 0x90, -+ OV9640_CHLF, 0x8, -+ OV9640_VIDO, 0xC9, -+ OV9640_TSLB, 0x8, -+ OV9640_COM11, 0x8, -+ OV9640_COM12, 0x46, -+ OV9640_COM13, 0x90, -+ OV9640_COM14, 0x2, -+ OV9640_EDGE, 0xA4, -+ OV9640_COM16, 0x2, -+ OV9640_COM17, 0xC8, -+ OV9640_AWBTH1, 0xF0, -+ OV9640_AWBTH2, 0x10, -+ OV9640_AWBTH3, 0x5C, -+ OV9640_AWBTH4, 0x70, -+ OV9640_AWBTH5, 0x46, -+ OV9640_AWBTH6, 0x4D, -+ OV9640_MTX1, 0x63, -+ OV9640_MTX2, 0x4E, -+ OV9640_MTX3, 0x15, -+ OV9640_MTX4, 0x1D, -+ OV9640_MTX5, 0xBE, -+ OV9640_MTX6, 0xDC, -+ OV9640_MTXS, 0xF, -+ OV9640_AWBC1, 0x1F, -+ OV9640_AWBC2, 0x55, -+ OV9640_AWBC3, 0x43, -+ OV9640_AWBC4, 0x7C, -+ OV9640_AWBC5, 0x54, -+ OV9640_AWBC6, 0xA, -+ OV9640_AWBC7, 0x5, -+ OV9640_AWBC8, 0x14, -+ OV9640_AWBC9, 0xCE, -+ OV9640_DBLV, 0x3A, -+ OV9640_GST0, 0x2, -+ OV9640_GSP0, 0x40, -+ OV9640_GSP1, 0x30, -+ OV9640_GSP2, 0x4B, -+ OV9640_GSP3, 0x60, -+ OV9640_GSP4, 0x70, -+ OV9640_GSP5, 0x70, -+ OV9640_GSP6, 0x70, -+ OV9640_GSP7, 0x70, -+ OV9640_GSP8, 0x60, -+ OV9640_GSP9, 0x60, -+ OV9640_GSP10, 0x50, -+ OV9640_GSP11, 0x48, -+ OV9640_GSP12, 0x3A, -+ OV9640_GSP13, 0x2E, -+ OV9640_GSP14, 0x28, -+ OV9640_GSP15, 0x22, -+ OV9640_GST0, 0x4, -+ OV9640_GST1, 0x7, -+ OV9640_GST2, 0x10, -+ OV9640_GST3, 0x28, -+ OV9640_GST4, 0x36, -+ OV9640_GST5, 0x44, -+ OV9640_GST6, 0x52, -+ OV9640_GST7, 0x60, -+ OV9640_GST8, 0x6C, -+ OV9640_GST9, 0x78, -+ OV9640_GST10, 0x8C, -+ OV9640_GST11, 0x9E, -+ OV9640_GST12, 0xBB, -+ OV9640_GST13, 0xD2, -+ OV9640_GST14, 0xE6, -+ OV9640_COM8, 0x8F, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_CIF1[] = { -+ OV9640_COM10, 0x20, -+ OV9640_COM7, 0x20, -+ OV9640_COM1, 0x00, -+ OV9640_CLKRC, 0x00, -+ -+ // From OmniVision -+ OV9640_COM8, 0x8D, -+ OV9640_BLUE, 0x80, -+ OV9640_RED, 0x80, -+ OV9640_COM3, 0x5, //0x04 -+ OV9640_COM4, 0x40, -+ OV9640_COM6, 0x4E, //0x4F -+ OV9640_COM9, 0x4A, //0x0A -+ OV9640_PSHFT, 0x1, -+ OV9640_AEW, 0x78, -+ OV9640_AEB, 0x70, -+ OV9640_BBIAS, 0x90, -+ OV9640_CHLF, 0x8, -+ OV9640_VIDO, 0xC9, -+ OV9640_TSLB, 0x8, -+ OV9640_COM11, 0x8, -+ OV9640_COM12, 0x46, -+ OV9640_COM13, 0x90, -+ OV9640_COM14, 0x2, -+ OV9640_EDGE, 0xA4, -+ OV9640_COM16, 0x2, -+ OV9640_COM17, 0xC8, -+ OV9640_AWBTH1, 0xF0, -+ OV9640_AWBTH2, 0x10, -+ OV9640_AWBTH3, 0x5C, -+ OV9640_AWBTH4, 0x70, -+ OV9640_AWBTH5, 0x46, -+ OV9640_AWBTH6, 0x4D, -+ OV9640_MTX1, 0x63, -+ OV9640_MTX2, 0x4E, -+ OV9640_MTX3, 0x15, -+ OV9640_MTX4, 0x1D, -+ OV9640_MTX5, 0xBE, -+ OV9640_MTX6, 0xDC, -+ OV9640_MTXS, 0xF, -+ OV9640_AWBC1, 0x1F, -+ OV9640_AWBC2, 0x55, -+ OV9640_AWBC3, 0x43, -+ OV9640_AWBC4, 0x7C, -+ OV9640_AWBC5, 0x54, -+ OV9640_AWBC6, 0xA, -+ OV9640_AWBC7, 0x5, -+ OV9640_AWBC8, 0x14, -+ OV9640_AWBC9, 0xCE, -+ OV9640_DBLV, 0x3A, -+ OV9640_GST0, 0x2, -+ OV9640_GSP0, 0x40, -+ OV9640_GSP1, 0x30, -+ OV9640_GSP2, 0x4B, -+ OV9640_GSP3, 0x60, -+ OV9640_GSP4, 0x70, -+ OV9640_GSP5, 0x70, -+ OV9640_GSP6, 0x70, -+ OV9640_GSP7, 0x70, -+ OV9640_GSP8, 0x60, -+ OV9640_GSP9, 0x60, -+ OV9640_GSP10, 0x50, -+ OV9640_GSP11, 0x48, -+ OV9640_GSP12, 0x3A, -+ OV9640_GSP13, 0x2E, -+ OV9640_GSP14, 0x28, -+ OV9640_GSP15, 0x22, -+ OV9640_GST0, 0x4, -+ OV9640_GST1, 0x7, -+ OV9640_GST2, 0x10, -+ OV9640_GST3, 0x28, -+ OV9640_GST4, 0x36, -+ OV9640_GST5, 0x44, -+ OV9640_GST6, 0x52, -+ OV9640_GST7, 0x60, -+ OV9640_GST8, 0x6C, -+ OV9640_GST9, 0x78, -+ OV9640_GST10, 0x8C, -+ OV9640_GST11, 0x9E, -+ OV9640_GST12, 0xBB, -+ OV9640_GST13, 0xD2, -+ OV9640_GST14, 0xE6, -+ OV9640_COM8, 0x8F, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_SXGA[] = { -+ OV9640_COM10, 0x20, -+ OV9640_COM7, 0x00, -+ OV9640_COM1, 0x00, -+ OV9640_CLKRC, 0x80, -+ -+ // From OmniVision -+ OV9640_COM8, 0x8D, -+ OV9640_BLUE, 0x80, -+ OV9640_RED, 0x80, -+ OV9640_COM3, 0x1, //0x04 -+ OV9640_COM4, 0x40, -+ OV9640_COM6, 0x4E, //0x4F -+ OV9640_COM9, 0x4A, //0x0A -+ OV9640_PSHFT, 0x1, -+ OV9640_AEW, 0x78, -+ OV9640_AEB, 0x70, -+ OV9640_BBIAS, 0x90, -+ OV9640_CHLF, 0x8, -+ OV9640_VIDO, 0xC9, -+ OV9640_TSLB, 0x0, //0x8 -+ OV9640_COM11, 0x8, -+ OV9640_COM12, 0x46, -+ OV9640_COM13, 0x90, -+ OV9640_COM14, 0x2, -+ OV9640_EDGE, 0xA4, -+ OV9640_COM16, 0x2, -+ OV9640_COM17, 0xC8, -+ OV9640_AWBTH1, 0xF0, -+ OV9640_AWBTH2, 0x10, -+ OV9640_AWBTH3, 0x5C, -+ OV9640_AWBTH4, 0x70, -+ OV9640_AWBTH5, 0x46, -+ OV9640_AWBTH6, 0x4D, -+ OV9640_MTX1, 0x63, -+ OV9640_MTX2, 0x4E, -+ OV9640_MTX3, 0x15, -+ OV9640_MTX4, 0x1D, -+ OV9640_MTX5, 0xBE, -+ OV9640_MTX6, 0xDC, -+ OV9640_MTXS, 0xF, -+ OV9640_AWBC1, 0x1F, -+ OV9640_AWBC2, 0x55, -+ OV9640_AWBC3, 0x43, -+ OV9640_AWBC4, 0x7C, -+ OV9640_AWBC5, 0x54, -+ OV9640_AWBC6, 0xA, -+ OV9640_AWBC7, 0x5, -+ OV9640_AWBC8, 0x14, -+ OV9640_AWBC9, 0xCE, -+ OV9640_DBLV, 0x3A, -+ OV9640_GST0, 0x2, -+ OV9640_GSP0, 0x40, -+ OV9640_GSP1, 0x30, -+ OV9640_GSP2, 0x4B, -+ OV9640_GSP3, 0x60, -+ OV9640_GSP4, 0x70, -+ OV9640_GSP5, 0x70, -+ OV9640_GSP6, 0x70, -+ OV9640_GSP7, 0x70, -+ OV9640_GSP8, 0x60, -+ OV9640_GSP9, 0x60, -+ OV9640_GSP10, 0x50, -+ OV9640_GSP11, 0x48, -+ OV9640_GSP12, 0x3A, -+ OV9640_GSP13, 0x2E, -+ OV9640_GSP14, 0x28, -+ OV9640_GSP15, 0x22, -+ OV9640_GST0, 0x4, -+ OV9640_GST1, 0x7, -+ OV9640_GST2, 0x10, -+ OV9640_GST3, 0x28, -+ OV9640_GST4, 0x36, -+ OV9640_GST5, 0x44, -+ OV9640_GST6, 0x52, -+ OV9640_GST7, 0x60, -+ OV9640_GST8, 0x6C, -+ OV9640_GST9, 0x78, -+ OV9640_GST10, 0x8C, -+ OV9640_GST11, 0x9E, -+ OV9640_GST12, 0xBB, -+ OV9640_GST13, 0xD2, -+ OV9640_GST14, 0xE6, -+ OV9640_COM8, 0x8F, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+ -+const static u8 gRGB_QQVGA[] = { -+ OV9640_COM7, 0x80, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gRGB_QVGA[] = { -+ OV9640_COM7, 0x80, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gRGB_QCIF[] = { -+ OV9640_COM7, 0x80, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+ -+const static u8 gRGB_VGA[] = { -+ OV9640_COM7, 0x80, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gRGB_CIF[] = { -+ OV9640_COM7, 0x80, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gRGB_SXGA[] = { -+ OV9640_COM7, 0x80, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+const static u8 gYUV_QVGA_v3[] = { -+ 0x11, 0x83, -+ 0x12, 0x10, -+// 0x13, 0xA8, -+ 0x01, 0x80, -+ 0x02, 0x80, -+ 0x04, 0x00, -+ 0x0C, 0x05, -+ 0x0D, 0xC0, -+ 0x0E, 0x81, -+ 0x0F, 0x4F, -+ 0x14, 0x8A, -+ 0x16, 0x02, -+ 0x1B, 0x01, -+ 0x24, 0x70, -+ 0x25, 0x68, -+ 0x26, 0xD1, -+ 0x27, 0x88, -+ 0x2A, 0x00, -+ 0x2B, 0x00, -+ 0x2c, 0x88, -+ 0x33, 0x02, -+ 0x37, 0x05, -+ 0x38, 0x13, -+ 0x39, 0xF0, -+ 0x3A, 0x0C, -+ 0x3B, 0x01, -+ 0x3C, 0x46, -+ 0x3D, 0x90, -+ 0x3E, 0x02, -+ 0x3F, 0xa4, -+ 0x41, 0x02, -+ 0x42, 0xC8, -+ -+ /* -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x5C, -+ 0x46, 0x70, -+ 0x47, 0x46, -+ 0x48, 0x4d, -+ -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x6C, -+ 0x46, 0x6c, -+ 0x47, 0x44, -+ 0x48, 0x44, -+ */ -+ -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x20, -+ 0x46, 0x20, -+ 0x47, 0x20, -+ 0x48, 0x20, -+ -+ 0x49, 0x03, -+ 0x4f, 0x3c, -+ 0x50, 0x32, -+ 0x51, 0x09, -+ 0x52, 0x13, -+ 0x53, 0x39, -+ 0x54, 0x4c, -+ -+ /* -+ 0x59, 0x1f, -+ 0x5A, 0x55, -+ 0x5B, 0x43, -+ 0x5C, 0x7c, -+ 0x5D, 0x54, -+ 0x5E, 0x0a, -+ 0x5F, 0x01, -+ 0x60, 0x94, -+ 0x61, 0xCE, -+ -+ 0x59, 0x49, -+ 0x5A, 0x94, -+ 0x5B, 0x46, -+ 0x5C, 0x84, -+ 0x5D, 0x5c, -+ 0x5E, 0x08, -+ 0x5F, 0x00, -+ 0x60, 0x14, -+ 0x61, 0xCE, -+ */ -+ 0x59, 0x27, -+ 0x5A, 0x72, -+ 0x5B, 0x56, -+ 0x5C, 0x7a, -+ 0x5D, 0x5d, -+ 0x5E, 0x17, -+ 0x5F, 0x00, -+ 0x60, 0x14, -+ 0x61, 0xCE, -+ 0x62, 0x78, -+ 0x63, 0x00, -+ 0x64, 0x04, -+ 0x65, 0x50, -+ 0x66, 0x01, -+ 0x69, 0x00, -+ 0x6A, 0x3d, //for QVGA 3e-->3d, -+ 0x6B, 0x3F, -+ /* -+ 0x6C, 0x50, -+ 0x6D, 0x60, -+ 0x6E, 0x58, -+ 0x6F, 0x58, -+ 0x70, 0x58, -+ 0x71, 0x50, -+ 0x72, 0x50, -+ 0x73, 0x50, -+ 0x74, 0x50, -+ 0x75, 0x50, -+ 0x76, 0x4c, -+ 0x77, 0x4c, -+ 0x78, 0x45, -+ 0x79, 0x3c, -+ 0x7A, 0x2c, -+ 0x7B, 0x24, -+ 0x7C, 0x05, -+ 0x7D, 0x0b, -+ 0x7E, 0x16, -+ 0x7F, 0x2c, -+ 0x80, 0x37, -+ 0x81, 0x41, -+ 0x82, 0x4b, -+ 0x83, 0x55, -+ 0x84, 0x5f, -+ 0x85, 0x69, -+ 0x86, 0x7C, -+ 0x87, 0x8f, -+ 0x88, 0xB1, -+ 0x89, 0xcf, -+ 0x8A, 0xE5, -+ */ -+ 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, -+ OV9640_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gSensorSlaveAddr = 0x30; -+ -+int i2c_init(void) -+{ -+ return i2c_ov9640_init(); -+} -+ -+int i2c_deinit(void) -+{ -+ return i2c_ov9640_cleanup(); -+} -+ -+/*********************************************************************** -+* Private/helper api -+***********************************************************************/ -+static int prv_get_reg_value(u8 * regP, u8 regAddr, u8 * regValueP) -+{ -+ unsigned int index = 0; -+ u8 curReg = 0; -+ while (curReg < OV9640_REGEND) { -+ curReg = regP[index << 1]; -+ if (curReg == regAddr) { -+ *regValueP = regP[(index << 1) + 1]; -+ return 0; -+ } -+ index++; -+ } -+ -+ return -1; -+ -+} -+ -+static int prv_set_reg_value(u8 * regP, u8 regAddr, u8 regValue) -+{ -+ unsigned int index = 0; -+ u8 curReg = 0; -+ -+ while (curReg < OV9640_REGEND) { -+ curReg = regP[index << 1]; -+ if (curReg == regAddr) { -+ regP[(index << 1) + 1] = regValue; -+ return 0; -+ } -+ index++; -+ } -+ -+ return -1; -+ -+} -+ -+/*********************************************************************** -+* Sensor read/write -+***********************************************************************/ -+static int prv_read_sensor_reg(const u8 subAddress, u8 * bufP) -+{ -+ return ov9640_read(subAddress, bufP); -+} -+ -+static int prv_write_sensor_reg(const u8 subAddress, u8 * bufP) -+{ -+ return ov9640_write(subAddress, *bufP); -+} -+ -+static int prv_RMW_sensor_reg(const u8 subAddress, u8 * bufP, u8 andMask, u8 orMask) -+{ -+ int status; -+ status = prv_read_sensor_reg(subAddress, bufP); -+ if (!status) { -+ *bufP &= andMask; -+ *bufP |= orMask; -+ status = prv_write_sensor_reg(subAddress, bufP); -+ } -+ return status; -+} -+ -+int ov9640_read_sensor_reg(const u8 subAddress, u8 * bufP) -+{ -+ return prv_read_sensor_reg(subAddress, bufP); -+} -+ -+int ov9640_write_sensor_reg(const u8 subAddress, u8 * bufP) -+{ -+ return prv_write_sensor_reg(subAddress, bufP); -+} -+ -+int ov9640_set_regs(u8 * regP) -+{ -+ u32 curReg = 0; -+ int status = 0; -+ -+ // The list is a register number followed by the value. -+ while (regP[curReg << 1] < OV9640_REGEND) { -+ status = prv_write_sensor_reg(regP[curReg << 1], ®P[(curReg << 1) + 1]); -+ if (curReg == 0) -+ ov9640_wait(1); -+ -+ curReg++; -+ } -+ return status; -+} -+ -+int ov9640_read_all_regs(u8 * bufP, u32 numRegs) -+{ -+ u32 curReg; -+ -+ for (curReg = 0; curReg < numRegs; curReg++, bufP++) -+ prv_read_sensor_reg(curReg, bufP); -+ -+ return 0; -+} -+ -+/*********************************************************************** -+* Power & Reset -+***********************************************************************/ -+void ov9640_power_down(int powerDown) -+{ -+ // OV9640 PWRDWN, 0 = NORMAL, 1=POWER DOWN -+ //GPDR1 |= GPIO_bit(50); -+ //OV9640 reset CIF_RST, 0 = NORMAL, 1=RESET -+ //GPDR0 |= GPIO_bit(19); -+ if (powerDown == 1) { -+ mdelay(200); -+ ov9640_soft_reset(); -+ ov9640_write(0x39, 0xf4); -+ ov9640_write(0x1e, 0x80); -+ ov9640_write(0x6b, 0x3f); -+ ov9640_write(0x36, 0x49); -+ ov9640_write(0x12, 0x05); -+ mdelay(800); -+ GPSR1 = GPIO_bit(50); -+ } -+ else { -+ ov9640_write(0x39, 0xf0); -+ ov9640_write(0x1e, 0x00); -+ ov9640_write(0x6b, 0x3f); -+ ov9640_write(0x36, 0x49); -+ ov9640_write(0x12, 0x10); -+ GPCR1 = GPIO_bit(50); -+ //GPSR0 = GPIO_bit(19); -+ mdelay(20); -+ //GPCR0 = GPIO_bit(19); -+ } -+ mdelay(100); -+} -+ -+void ov9640_soft_reset(void) -+{ -+ u8 regValue; -+ regValue = 0x80; -+ prv_write_sensor_reg(OV9640_COM7, ®Value); -+ mdelay(10); -+ return; -+} -+ -+void ov9640_reset(void) -+{ -+ // do nothing on Zoar -+ return 0; -+} -+ -+void ov9640_wait(int ms) -+{ -+ mdelay(ms); -+} -+ -+int ov9640_output_stoped() -+{ -+ ov9640 *pov; -+ pov = &g_ov; -+ return pov->stoped; -+} -+ -+void ov9640_set_start() -+{ -+ ov9640 *pov; -+ pov = &g_ov; -+ -+ pov->stoped = 0; -+} -+ -+void ov9640_set_stop(p_camera_context_t cam_ctx) -+{ -+ ov9640 *pov; -+ pov = &g_ov; -+ -+ pov->stoped = 1; -+} -+ -+/*********************************************************************** -+* Settings -+***********************************************************************/ -+int ov9640_version_revision(u8 * pCmRevision, u8 * pSensorRevision) -+{ -+ prv_read_sensor_reg(OV9640_PID, pCmRevision); -+ prv_read_sensor_reg(OV9640_VER, pSensorRevision); -+ return 0; -+} -+ -+void ov9640_set_HSYNC(void) -+{ -+ u8 val; -+ -+ // Makes HREF become HSYNC -+ prv_read_sensor_reg(OV9640_COM10, &val); -+ val |= 0x40; -+ prv_write_sensor_reg(OV9640_COM10, &val); -+} -+ -+void ov9640_auto_function_on(void) -+{ -+ u8 val; -+ DPRINTK("in function %s\n", __FUNCTION__); -+ prv_read_sensor_reg(OV9640_COM8, &val); -+ val |= 0x07; -+ prv_write_sensor_reg(OV9640_COM8, &val); -+} -+ -+void ov9640_auto_function_off(void) -+{ -+ u8 val; -+ DPRINTK("in function %s\n", __FUNCTION__); -+ prv_read_sensor_reg(OV9640_COM8, &val); -+ val &= ~0x07; -+ prv_write_sensor_reg(OV9640_COM8, &val); -+} -+ -+ -+/*********************************************************************** -+* Viewfinder, still -+***********************************************************************/ -+int ov9640_viewfinder_on(void) -+{ -+ u8 com3; -+ -+ prv_read_sensor_reg(OV9640_COM3, &com3); -+ com3 &= ~0x01; -+ prv_write_sensor_reg(OV9640_COM3, &com3); -+ -+ return OV_ERR_NONE; -+} -+ -+ -+int ov9640_viewfinder_off(void) -+{ -+ u8 com3; -+ -+ prv_read_sensor_reg(OV9640_COM3, &com3); -+ com3 |= 0x01; -+ prv_write_sensor_reg(OV9640_COM3, &com3); -+ -+ mdelay(200); -+ return OV_ERR_NONE; -+} -+ -+ -+int ov9640_halt_video_output(void) -+{ -+ u8 com3; -+ -+ // Set the camera to only output 1 frame. -+ prv_read_sensor_reg(OV9640_COM3, &com3); -+ com3 |= 1; -+ prv_write_sensor_reg(OV9640_COM3, &com3); -+ -+ return OV_ERR_NONE; -+} -+ -+int ov9640_resume_to_full_output_mode(void) -+{ -+ u8 mode; -+ -+ // Output still frames continuously -+ // Turn off single capture mode COM3. -+ prv_RMW_sensor_reg(OV9640_COM3, (&mode), ((u8) ~ 1), 0); -+ return OV_ERR_NONE; -+} -+ -+int ov9640_get_single_image(void) -+{ -+ u8 mode; -+ -+ prv_RMW_sensor_reg(OV9640_COM3, &mode, (u8) ~ 1, 1); -+ return OV_ERR_NONE; -+} -+static u8 *ov9640_get_regs_list(u32 captureSizeFormat, u32 colorFormat) -+{ -+ char *formatNameP; -+ u8 *defaultDataP = NULL; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ -+ -+ // Get the default setting. -+ if (colorFormat == OV_FORMAT_YUV_422) { -+ switch (captureSizeFormat) { -+ case OV_SIZE_QQVGA: -+ defaultDataP = gYUV_QQVGA; -+ formatNameP = "QQVGA.422"; -+ break; -+ case OV_SIZE_QQCIF: -+ defaultDataP = gYUV_QQCIF; -+ formatNameP = "QQCIF.422"; -+ break; -+ case OV_SIZE_QVGA: -+ defaultDataP = gYUV_QVGA; -+ formatNameP = "QVGA.422"; -+ //version 3 support: -+ if (pov->version == ((PID_OV_v3 << 8) | (PID_9640_v3))) { -+ DPRINTK("ver 3 sensor!\n"); -+ defaultDataP = gYUV_QVGA_v3; -+ } -+ break; -+ case OV_SIZE_QCIF: -+ defaultDataP = gYUV_QCIF; -+ formatNameP = "QCIF.422"; -+ break; -+ case OV_SIZE_VGA: -+ defaultDataP = gYUV_VGA; -+ formatNameP = "VGA.422"; -+ break; -+ case OV_SIZE_CIF: -+ defaultDataP = gYUV_CIF; -+ formatNameP = "CIF.422"; -+ break; -+ case OV_SIZE_SXGA: -+ defaultDataP = gYUV_SXGA; -+ formatNameP = "SXGA.422"; -+ break; -+ default: -+ return NULL; -+ } -+ } -+ -+ if (colorFormat == OV_FORMAT_RGB_565) { -+ switch (captureSizeFormat) { -+ case OV_SIZE_QQVGA: -+ defaultDataP = gRGB_QQVGA; -+ formatNameP = "QQVGA.RGB"; -+ break; -+ case OV_SIZE_QCIF: -+ defaultDataP = gRGB_QCIF; -+ formatNameP = "QCIF.RGB"; -+ break; -+ -+ case OV_SIZE_QVGA: -+ defaultDataP = gRGB_QVGA; -+ formatNameP = "QVGA.RGB"; -+ break; -+ case OV_SIZE_VGA: -+ defaultDataP = gRGB_VGA; -+ formatNameP = "VGA.RGB"; -+ break; -+ case OV_SIZE_CIF: -+ defaultDataP = gRGB_CIF; -+ formatNameP = "CIF.RGB"; -+ break; -+ case OV_SIZE_SXGA: -+ defaultDataP = gRGB_SXGA; -+ formatNameP = "SXGA.RGB"; -+ break; -+ default: -+ return NULL; -+ } -+ } -+ return defaultDataP; -+} -+ -+/*********************************************************************** -+* Format -+***********************************************************************/ -+int ov9640_set_format(u32 captureSizeFormat, u32 colorFormat) -+{ -+ int status = OV_ERR_PARAMETER; -+ u8 *regsP, regValue; -+ unsigned int index = 0; -+ u8 curReg = 0; -+ static u32 prev_colorFormat = OV_FORMAT_NONE, prev_size = OV_SIZE_NONE; -+ -+ if (prev_colorFormat == colorFormat && captureSizeFormat == prev_size) -+ return 0; -+ if ((captureSizeFormat == OV_SIZE_NONE) && (colorFormat == OV_FORMAT_NONE)) -+ goto no_set; -+ -+ if ((prev_colorFormat == OV_FORMAT_NONE) && (prev_size == OV_SIZE_NONE)) { -+ regsP = (u8 *) ov9640_get_regs_list(captureSizeFormat, colorFormat); -+ // Get the pointer to the basic setting. The pointer must be freed after exiting. -+ -+ if (regsP == NULL) -+ return OV_ERR_PARAMETER; -+ ov9640_soft_reset(); -+ // Blast the entire parameter tree into the part. -+ status = ov9640_set_regs(regsP); -+ } -+ else { -+ status = ov9640_switch_format(captureSizeFormat, colorFormat); -+ } -+ no_set: -+ prev_colorFormat = colorFormat; -+ prev_size = captureSizeFormat; -+ return status; -+} -+ -+void ov9640_save_gains() -+{ -+ u8 gain, aech, aecl, laec, blue, red; -+ ov9640 *pov; -+ u8 regValue; -+ u32 current_size; -+ -+ pov = &g_ov; -+ -+ // Get current size -+ prv_read_sensor_reg(OV9640_COM7, ®Value); -+ switch (regValue) { -+ case 0x00: -+ current_size = OV_SIZE_SXGA; -+ break; -+ case 0x08: -+ prv_read_sensor_reg(OV9640_COM1, ®Value); -+ if (regValue & 0x20) -+ current_size = OV_SIZE_QQCIF; -+ else -+ current_size = OV_SIZE_QCIF; -+ break; -+ case 0x10: -+ prv_read_sensor_reg(OV9640_COM1, ®Value); -+ if (regValue & 0x20) -+ current_size = OV_SIZE_QQVGA; -+ else -+ current_size = OV_SIZE_QVGA; -+ break; -+ case 0x20: -+ current_size = OV_SIZE_CIF; -+ break; -+ case 0x40: -+ current_size = OV_SIZE_VGA; -+ break; -+ default: -+ current_size = OV_SIZE_SXGA; -+ break; -+ } -+ pov->pre_size = current_size; -+ -+ // Get the awb, gain, exposure values -+ prv_read_sensor_reg(OV9640_BLUE, &blue); -+ prv_read_sensor_reg(OV9640_RED, &red); -+ prv_read_sensor_reg(OV9640_GAIN, &gain); -+ gain &= 0x3F; -+ prv_read_sensor_reg(OV9640_AECH, &aech); -+ prv_read_sensor_reg(OV9640_COM1, &aecl); -+ aecl &= 0x3; -+ prv_read_sensor_reg(OV9640_LAEC, &laec); -+ -+ pov->gain = gain; -+ pov->blue_gain = blue; -+ pov->red_gain = red; -+ pov->exp_value = (aech << 2) | aecl; -+ pov->exp_time = laec; -+ -+} -+ -+void ov9640_adjust_gains(u32 prev_size, u32 cur_size) -+{ -+ u8 expMultiple = 1; -+ u8 gain; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ if (prev_size == OV_SIZE_QVGA) { -+ if (cur_size == OV_SIZE_VGA) { -+ if (pov->gain & 0x20) { -+ /* hight gain capture 7.5 fps */ -+ pov->pclock = 0x83; -+ pov->gain = pov->gain & ~0x20; -+ pov->adjusted_exp_value = pov->exp_value * 2; -+ } -+ else { -+ /* capture 15 fps */ -+ pov->pclock = 0x81; -+ pov->adjusted_exp_value = pov->exp_value * 2; -+ } -+ if (pov->night_mode == 1) { -+ //night mode -+ //pov->pclock = 0x87; -+ } -+ else if (pov->night_mode == 2) { //action mode -+ pov->pclock = 0x80; -+ } -+ } -+ else if (cur_size == OV_SIZE_SXGA) { -+ if (pov->gain & 0x20) { -+ /* 8x gain capture 7.5 fps to 4x gain */ -+ pov->pclock = 0x80; -+ pov->gain = pov->gain & ~0x20; -+ pov->adjusted_exp_value = pov->exp_value * 4; -+ } -+ else if (pov->gain & 0x10) { -+ /* 4x gain capture 7.5 fps to 2x gain */ -+ pov->pclock = 0x80; -+ pov->gain = pov->gain & ~0x10; -+ pov->adjusted_exp_value = pov->exp_value * 4; -+ } -+ else { -+ pov->pclock = 0x80; -+ pov->adjusted_exp_value = pov->exp_value * 2; -+ } -+ if (pov->night_mode == 1) { -+ //night mode -+ //pov->pclock = 0x81; -+ } -+ else if (pov->night_mode == 2) { //action mode -+ pov->pclock = 0x80; -+ } -+ } -+ else if (cur_size == OV_SIZE_QVGA) { -+ if (pov->gain & 0x20) { -+ /* hight gain capture 7.5 fps */ -+ pov->pclock = 0x87; -+ pov->gain = pov->gain & ~0x20; -+ pov->adjusted_exp_value = pov->exp_value; -+ } -+ else { -+ /* capture 15 fps */ -+ pov->pclock = 0x83; -+ pov->adjusted_exp_value = pov->exp_value; -+ } -+ if (pov->night_mode == 1) { -+ //night mode -+ //pov->pclock = 0x89; -+ } -+ else if (pov->night_mode == 2) { //action mode -+ pov->pclock = 0x81; -+ } -+ } -+ pov->red_gain=pov->red_gain*9 /10; -+ pov->blue_gain=pov->blue_gain *21 /20; -+ } -+} -+ -+static void ov9640_upload_gains() -+{ -+ ov9640 *pov; -+ u32 expValue; -+ u8 gain, aech, aecl, laec, blue, red; -+ u8 regValue; -+ -+ pov = &g_ov; -+ -+ gain = pov->gain; -+ blue = pov->blue_gain; -+ red = pov->red_gain; -+ expValue = pov->adjusted_exp_value; -+ // Set awb -+ prv_write_sensor_reg(OV9640_BLUE, &blue); -+ prv_write_sensor_reg(OV9640_RED, &red); -+ -+ // Set gain -+ prv_write_sensor_reg(OV9640_GAIN, &gain); -+ // Set exposure -+ prv_read_sensor_reg(OV9640_COM1, ®Value); -+ regValue = (regValue & 0xFC) | (expValue & 0x03); -+ prv_write_sensor_reg(OV9640_COM1, ®Value); -+ expValue >>= 2; -+ if (expValue > 0xFF) -+ regValue = 0xFF; -+ else -+ regValue = expValue; -+ prv_write_sensor_reg(OV9640_AECH, ®Value); -+ prv_write_sensor_reg(OV9640_CLKRC, &pov->pclock); -+} -+ -+int ov9640_switch_format(u32 captureSizeFormat, u32 colorFormat) -+{ -+ int status; -+ u32 index, curReg; -+ u8 *regsP; -+ u8 regValue; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ -+ regsP = (u8 *) ov9640_get_regs_list(captureSizeFormat, colorFormat); -+ // Get the pointer to the basic setting. The pointer must be freed after exiting. -+ -+ if (regsP == NULL) -+ return OV_ERR_PARAMETER; -+ // Apply the delta registers. -+ index = curReg = 0; -+ while ((curReg = gDelta[index]) < OV9640_REGEND) { -+ status = prv_get_reg_value(regsP, curReg, ®Value); -+ if (status == 0) { -+ prv_write_sensor_reg(curReg, ®Value); -+ } -+ else -+ break; -+ index++; -+ } -+ mdelay(50); -+ if (pov->night_mode == 1) { -+ //night mode -+ ov9640_set_night_mode(); -+ } -+ else if (pov->night_mode == 2) { //action mode -+ ov9640_set_action_mode(); -+ } -+ else -+ ov9640_set_auto_mode(); -+ -+ return status; -+} -+ -+int -+ov9640_set_dma_pages(pxa_dma_desc ** pdes, -+ pxa_dma_desc ** des_physical, int num, struct page *array[], int total_size, int dsadr, int flags) -+{ -+ int remain_size, des_transfer_size; -+ int j, target_page_num = num; -+ pxa_dma_desc *cur_des_virtual = *pdes; -+ pxa_dma_desc *cur_des_physical = *des_physical; -+ -+ // in each iteration, generate one dma chain for one frame -+ remain_size = total_size; -+ -+ for (j = 0; j < num; j++) { -+ // set descriptor -+ if (remain_size > PAGE_SIZE) -+ des_transfer_size = PAGE_SIZE; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned) cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = dsadr; // FIFO0 physical address -+ cur_des_virtual->dtadr = page_to_bus(array[j]); -+ cur_des_virtual->dcmd = des_transfer_size | flags; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ *pdes = cur_des_virtual; -+ *des_physical = cur_des_physical; -+} -+ -+int -+ov9640_set_dma_page1(pxa_dma_desc ** pdes, -+ pxa_dma_desc ** des_physical, int num, struct page *page1, int total_size, int dsadr, int flags) -+{ -+ int remain_size, des_transfer_size; -+ int j, target_page_num = num; -+ pxa_dma_desc *cur_des_virtual = *pdes; -+ pxa_dma_desc *cur_des_physical = *des_physical; -+ int dump_page; -+ -+ // in each iteration, generate one dma chain for one frame -+ remain_size = total_size; -+ dump_page = page_to_bus(page1); -+ DPRINTK("dump_page=%x", dump_page); -+ -+ for (j = 0; j < num; j++) { -+ // set descriptor -+ if (remain_size > PAGE_SIZE) -+ des_transfer_size = PAGE_SIZE; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned) cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = dsadr; // FIFO0 physical address -+ cur_des_virtual->dtadr = dump_page; -+ cur_des_virtual->dcmd = des_transfer_size | flags; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ *pdes = cur_des_virtual; -+ *des_physical = cur_des_physical; -+} -+ -+int ov9640_update_still_dma_chain(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL; -+ int des_transfer_size, remain_size; -+ unsigned int i, j; -+ -+ int target_page_num; -+ -+ DPRINTK("ov9640_update_still_dma_chain\n"); -+ // clear descriptor pointers -+ cam_ctx->fifo0_descriptors_virtual = cam_ctx->fifo0_descriptors_physical = 0; -+ cam_ctx->fifo1_descriptors_virtual = cam_ctx->fifo1_descriptors_physical = 0; -+ cam_ctx->fifo2_descriptors_virtual = cam_ctx->fifo2_descriptors_physical = 0; -+ -+ // calculate how many descriptors are needed per frame -+ cam_ctx->fifo0_num_descriptors = cam_ctx->pages_per_fifo0; -+ -+ cam_ctx->fifo1_num_descriptors = cam_ctx->pages_per_fifo1; -+ -+ cam_ctx->fifo2_num_descriptors = cam_ctx->pages_per_fifo2; -+ -+ // check if enough memory to generate descriptors -+ DPRINTK("in %s, cam_ctx->block_number =%d\n", __FUNCTION__, cam_ctx->block_number); -+ if ((cam_ctx->fifo0_num_descriptors + cam_ctx->fifo1_num_descriptors + -+ cam_ctx->fifo2_num_descriptors) * cam_ctx->block_number > cam_ctx->dma_descriptors_size) -+ return -1; -+ -+ // generate fifo0 dma chains -+ cam_ctx->fifo0_descriptors_virtual = (unsigned) cam_ctx->dma_descriptors_virtual; -+ cam_ctx->fifo0_descriptors_physical = (unsigned) cam_ctx->dma_descriptors_physical; -+ cur_des_virtual = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual; -+ cur_des_physical = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_physical; -+ -+ DPRINTK("pages_allocated=%d,fifo0_descriptors_virtual=%x\n", cam_ctx->pages_allocated, cur_des_virtual); -+ -+ for (i = 0; i < 2; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo0_transfer_size; -+ ov9640_set_dma_page1(&cur_des_virtual, &cur_des_physical, -+ cam_ctx->fifo0_num_descriptors, -+ cam_ctx->page_array[cam_ctx-> -+ pages_allocated - -+ 1], remain_size, CIBR0_PHY, DCMD_FLOWSRC | DCMD_BURST32); -+ -+ } -+ DPRINTK("after ov9640_set_dma_page1=%d\n", cam_ctx->pages_allocated); -+ for (i = 0; i < 1; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo0_transfer_size; -+ -+ // assume the blocks are stored consecutively -+ target_page_num = cam_ctx->pages_per_block * i; -+ DPRINTK("target_page_num=%d\n", target_page_num); -+ ov9640_set_dma_pages(&cur_des_virtual, &cur_des_physical, -+ cam_ctx->fifo0_num_descriptors, -+ &cam_ctx->page_array[target_page_num], -+ remain_size, CIBR0_PHY, DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo0_descriptors_physical); -+ last_des_virtual->ddadr |= 0x1; -+ last_des_virtual->dcmd |= DCMD_ENDIRQEN; -+ -+ // generate fifo1 dma chains -+ if (cam_ctx->fifo1_transfer_size) { -+ // record fifo1 descriptors' start address -+ cam_ctx->fifo1_descriptors_virtual = (unsigned) cur_des_virtual; -+ cam_ctx->fifo1_descriptors_physical = (unsigned) cur_des_physical; -+ -+ for (i = 0; i < 2; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo1_transfer_size; -+ ov9640_set_dma_page1(&cur_des_virtual, -+ &cur_des_physical, -+ cam_ctx-> -+ fifo1_num_descriptors, -+ cam_ctx->page_array[cam_ctx-> -+ pages_allocated -+ - 2], -+ remain_size, CIBR1_PHY, DCMD_FLOWSRC | DCMD_BURST32); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ for (i = 0; i < 1; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo1_transfer_size; -+ -+ target_page_num = cam_ctx->pages_per_block * i + cam_ctx->pages_per_fifo0; -+ ov9640_set_dma_pages(&cur_des_virtual, &cur_des_physical, -+ cam_ctx->fifo1_num_descriptors, -+ &cam_ctx->page_array[target_page_num], -+ remain_size, CIBR1_PHY, DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo1_descriptors_physical); -+ last_des_virtual->ddadr |= 0x1; -+ } -+ // generate fifo2 dma chains -+ if (cam_ctx->fifo2_transfer_size) { -+ // record fifo1 descriptors' start address -+ cam_ctx->fifo2_descriptors_virtual = (unsigned) cur_des_virtual; -+ cam_ctx->fifo2_descriptors_physical = (unsigned) cur_des_physical; -+ -+ for (i = 0; i < 2; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo2_transfer_size; -+ ov9640_set_dma_page1(&cur_des_virtual, -+ &cur_des_physical, -+ cam_ctx-> -+ fifo2_num_descriptors, -+ cam_ctx->page_array[cam_ctx-> -+ pages_allocated -+ - 3], -+ remain_size, CIBR2_PHY, DCMD_FLOWSRC | DCMD_BURST32); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ DPRINTK("last target_page_num=%d\n", target_page_num + cam_ctx->fifo2_num_descriptors); -+ for (i = 0; i < 1; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo2_transfer_size; -+ target_page_num = -+ cam_ctx->pages_per_block * i + cam_ctx->pages_per_fifo0 + cam_ctx->pages_per_fifo1; -+ ov9640_set_dma_pages(&cur_des_virtual, &cur_des_physical, -+ cam_ctx->fifo2_num_descriptors, -+ &cam_ctx->page_array[target_page_num], -+ remain_size, CIBR2_PHY, DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ DPRINTK("last target_page_num=%d\n", target_page_num + cam_ctx->fifo2_num_descriptors); -+ } -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo2_descriptors_physical); -+ last_des_virtual->ddadr |= 0x1; -+ } -+ return 0; -+} -+ -+int ov9640_prepare_capture(p_camera_context_t cam_ctx, u32 captureSizeFormat, u32 colorFormat) -+{ -+ static int first = 1; -+ int status; -+ //u32 expMultiple, expValue; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ -+ stop_dma_transfer(cam_ctx); -+ ov9640_switch_format(captureSizeFormat, colorFormat); -+ ov9640_adjust_gains(pov->pre_size, captureSizeFormat); -+ ov9640_upload_gains(); -+ if (captureSizeFormat == OV_SIZE_VGA) { -+ //ov9640_update_still_dma_chain(cam_ctx); -+ ov9640_stop_third_des(cam_ctx); -+ /* -+ */ -+ } -+ else if (captureSizeFormat == OV_SIZE_SXGA) { -+ camera_set_int_mask(cam_ctx, 0x3fd | 0x0400); -+ ov9640_update_still_dma_chain(cam_ctx); -+ //ov9640_halt_video_output(); -+ //ci_clear_int_status(0xFFFFFFFF); -+ //DPRINTK("before camera_sleep \n"); -+ //camera_sleep(); -+ } -+ ci_reset_fifo(); -+ ci_clear_int_status(0xFFFFFFFF); -+ start_dma_transfer(cam_ctx, 1); -+ DPRINTK("after ov9640_prepare_capture \n"); -+} -+ -+int ov9640_set_special_effect(int style) -+{ -+ int ret = 0; -+ u32 index, curReg; -+ u8 *regsP; -+ u8 regValue; -+ -+ DPRINTK("in function %s parameter=%d\n", __FUNCTION__, style); -+ curReg = 0x3a; -+ ov9640_read(0x3a, ®Value); -+ regValue = regValue & 0xf; -+ switch (style) { -+ case V4l_STYLE_NORMAL: -+ DPRINTK("V4l_STYLE_NORMAL\n"); -+ regValue &= 0x7f; -+ //ov9640_write(0x3a, 0x08); -+ ov9640_write(0x3a, regValue); -+ ov9640_write(0x67, 0x80); -+ ov9640_write(0x68, 0x80); -+ break; -+ case V4l_STYLE_BLACK_WHITE: -+ DPRINTK("V4l_STYLE_BLACK_WHITE\n"); -+ regValue |= 0x10; -+ //ov9640_write(0x3a, 0x18); -+ ov9640_write(0x3a, regValue); -+ ov9640_write(0x67, 0x80); -+ ov9640_write(0x68, 0x80); -+ break; -+ case V4l_STYLE_SEPIA: -+ DPRINTK("V4l_STYLE_SEPIA\n"); -+ regValue |= 0x10; -+ //ov9640_write(0x3a, 0x18); -+ ov9640_write(0x3a, regValue); -+ ov9640_write(0x67, 0xa0); -+ ov9640_write(0x68, 0x40); -+ break; -+ //case V4l_STYLE_BULISH: -+ DPRINTK("V4l_STYLE_BULISH\n"); -+ ov9640_write(0x3a, 0x18); -+ ov9640_write(0x67, 0x80); -+ ov9640_write(0x68, 0xc0); -+ break; -+ default: -+ DPRINTK("case default ????????????????????\n"); -+ //ret=OV_ERR_PARAMETER; -+ } -+ return ret; -+ -+} -+ -+int ov9640_set_brightness(int bright) -+{ -+ int ret = 0; -+ const u8 BN[] = { -+ //BN-3 -+ 0x0f, 0x4f, -+ 0x27, 0xe8, -+ 0x28, 0xe0, -+ 0x29, 0xe0, -+ 0x2c, 0xe0, -+ //BN-2 -+ 0x0f, 0x4f, -+ 0x27, 0xc8, -+ 0x28, 0xc0, -+ 0x29, 0xc0, -+ 0x2c, 0xc0, -+ //BN-1 -+ 0x0f, 0x4f, -+ 0x27, 0xa8, -+ 0x28, 0xa0, -+ 0x29, 0xa0, -+ 0x2c, 0xa0, -+ //BN-0 -+ 0x0f, 0x4f, -+ 0x27, 0x88, -+ 0x28, 0x80, -+ 0x29, 0x80, -+ 0x2c, 0x88, -+ //BN+1 -+ 0x0f, 0x4f, -+ 0x27, 0x28, -+ 0x28, 0x20, -+ 0x29, 0x20, -+ 0x2c, 0x20, -+ //BN+2 -+ 0x0f, 0x4f, -+ 0x27, 0x48, -+ 0x28, 0x40, -+ 0x29, 0x40, -+ 0x2c, 0x40, -+ //BN+3 -+ 0x0f, 0x4f, -+ 0x27, 0x68, -+ 0x28, 0x60, -+ 0x29, 0x60, -+ 0x2c, 0x60, -+ }; -+ u8 *regs; -+ int n = 5; -+ int i; -+ -+ DPRINTK("in function %s bright =%d \n", __FUNCTION__, bright); -+ if (bright < -3) -+ bright = -3; -+ if (bright > 3) -+ bright = 3; -+ //bright = -4 .. 4 -+ regs = &BN[(bright + 3) * n * 2]; -+ for (i = 0; i < n * 2; i += 2) -+ ret |= ov9640_write(regs[i], regs[i + 1]); -+ return OV_ERR_NONE; -+ -+} -+int ov9640_set_expose_compensation(int bright) -+{ -+ int ret = 0; -+ const u8 EV[] = { -+ //EV-3 -+ 0x24, 0x1c, -+ 0x25, 0x14, -+ //EV-3 -+ 0x24, 0x28, -+ 0x25, 0x20, -+ //EV-2 -+ 0x24, 0x38, -+ 0x25, 0x30, -+ //EV-1 -+ 0x24, 0x50, -+ 0x25, 0x48, -+ //EV-0 -+ 0x24, 0x70, -+ 0x25, 0x68, -+ //EV+1 -+ 0x24, 0x90, -+ 0x25, 0x88, -+ //EV+2 -+ 0x24, 0xb4, -+ 0x25, 0xac, -+ //EV+3 -+ 0x24, 0xc8, -+ 0x25, 0xc0, -+ //EV+4 -+ 0x24, 0xe0, -+ 0x25, 0xd8, -+ }; -+ u8 *regs; -+ int n = 2; -+ int i; -+ -+ DPRINTK("in function %s bright =%d \n", __FUNCTION__, bright); -+ if (bright < -4) -+ bright = -4; -+ if (bright > 4) -+ bright = 4; -+ //bright = -4 .. 4 -+ regs = &EV[(bright + 4) * n * 2]; -+ for (i = 0; i < n * 2; i += 2) -+ ret |= ov9640_write(regs[i], regs[i + 1]); -+// if ( ret) -+// return OV_ERR_PARAMETER; -+ return OV_ERR_NONE; -+ -+} -+ -+int ov9640_set_white_balance(V4l_PIC_WB light) -+{ -+ int ret = 0; -+ const u8 WB_v3[] = { -+ //V4l_WB_DIRECT_SUN -+ 0x13, 0xad, -+ 0x01, 0x80, -+ 0x02, 0x80, -+ 0x45, 0x20, -+ 0x46, 0x20, -+ 0x47, 0x58, -+ 0x48, 0x58, -+ 0x5C, 0x7a, -+ 0x5D, 0x5d, -+ 0x5F, 0x00, -+ 0x60, 0x14, -+ 0x13, 0xaf, -+ 0x14, 0x4a, -+ //V4l_WB_INCANDESCENT home mode -+ 0x13, 0xad, -+ 0x01, 0x80, -+ 0x02, 0x80, -+ 0x45, 0x64, -+ 0x46, 0x64, -+ 0x47, 0x20, -+ 0x48, 0x20, -+ 0x5C, 0x7a, -+ 0x5D, 0x48, -+ 0x5F, 0x00, -+ 0x60, 0x14, -+ 0x13, 0xaf, -+ 0x14, 0x8a, -+ //V4l_WB_FLUORESCENT office mode -+ 0x13, 0xad, -+ 0x01, 0x80, -+ 0x02, 0x80, -+ 0x45, 0x64, -+ 0x46, 0x64, -+ 0x47, 0x58, -+ 0x48, 0x58, -+ 0x5C, 0x7a, -+ 0x5D, 0x5d, -+ 0x5F, 0x00, -+ 0x60, 0x14, -+ 0x13, 0xaf, -+ 0x14, 0x8a, -+ // auto -+ 0x13, 0xaf, -+ 0x01, 0x80, -+ 0x02, 0x80, -+/* -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x6C, -+ 0x46, 0x6c, -+ 0x47, 0x44, -+ 0x48, 0x44, -+ 0x59, 0x49, -+ 0x5A, 0x94, -+ 0x5B, 0x46, -+ 0x5C, 0x84, -+ 0x5D, 0x5c, -+ 0x5E, 0x08, -+ 0x5F, 0x00, -+ 0x60, 0x14, -+ 0x61, 0xCE, -+ */ -+ 0x43, 0xF0, -+ 0x44, 0x10, -+ 0x45, 0x20, -+ 0x46, 0x20, -+ 0x47, 0x20, -+ 0x48, 0x20, -+ 0x59, 0x27, -+ 0x5A, 0x72, -+ 0x5B, 0x56, -+ 0x5C, 0x7a, -+ 0x5D, 0x5d, -+ 0x5E, 0x17, -+ 0x5F, 0x00, -+ 0x60, 0x14, -+ 0x61, 0xCE, -+ -+ 0x14, 0x8a, -+ }; -+ u8 *regs; -+ int n = 13; -+ int i = 0; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ -+ DPRINTK("in function %s ,parameter=%d\n", __FUNCTION__, light); -+ switch (light) { -+ case V4l_WB_DIRECT_SUN: -+ //ov9640_set_color_saturation(3); -+ DPRINTK("V4l_WB_DIRECT_SUN\n"); -+ i = 0 * n * 2; -+ //ov9640_set_night_mode(); -+ break; -+ case V4l_WB_INCANDESCENT: -+ //ov9640_set_color_saturation(2); -+ DPRINTK("V4l_WB_INCANDESCENT\n"); -+ i = 1 * n * 2; -+ //ov9640_set_action_mode(); -+ break; -+ case V4l_WB_FLUORESCENT: -+ //ov9640_set_color_saturation(2); -+ DPRINTK("V4l_WB_FLUORESCENT\n"); -+ i = 2 * n * 2; -+ break; -+ default: -+ /* auto */ -+ //ov9640_set_color_saturation(2); -+ DPRINTK("case default ????????????????????\n"); -+ i = 3 * n * 2; -+ n = 19; -+ //ov9640_set_auto_mode(); -+ break; -+ } -+ regs = &WB_v3[i]; -+ if (pov->version == ((PID_OV_v3 << 8) | (PID_9640_v3))) { -+ DPRINTK("ver 3 sensor!\n"); -+ regs = &WB_v3[i]; -+ } -+ -+ for (i = 0; i < n * 2; i += 2) -+ ret |= ov9640_write(regs[i], regs[i + 1]); -+ return OV_ERR_NONE; -+} -+ -+int ov9640_set_night_mode() -+{ -+ const u8 NM_v3[] = { -+ //auto -+ 0x11, 0x89, -+ //night mode -+ //action mode -+ }; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ pov->night_mode = 1; -+ //ov9640_write(0x11, 0x89); -+ ov9640_write(0x3b, 0xe1); -+ -+} -+ -+int ov9640_set_action_mode() -+{ -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ pov->night_mode = 2; -+ ov9640_write(0x11, 0x81); -+ ov9640_write(0x3b, 0x01); -+ ov9640_write(0x2d, 0x0); -+ ov9640_write(0x2e, 0x0); -+ -+ -+} -+ -+int ov9640_set_auto_mode() -+{ -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ pov->night_mode = 0; -+ ov9640_write(0x11, 0x83); -+ ov9640_write(0x3b, 0x01); -+ ov9640_write(0x2d, 0x0); -+ ov9640_write(0x2e, 0x0); -+} -+ -+int ov9640_set_light_environment(V4l_PIC_WB light) -+{ -+ int ret = 0; -+ const u8 LE_v3[] = { -+ //OutDoor -+ 0x3b, 0x00, -+ 0x2a, 0, -+ 0x2b, 0, -+ 0x6a, 0x3d, -+ //Indoor 60Hz(Default) -+ 0x3b, 0x01, -+ 0x2a, 0, -+ 0x2b, 0, -+ 0x6a, 0x3d, -+ //Indoor 50Hz -+ 0x3b, 0x01, -+ 0x2a, 0x10, -+ 0x2b, 0x40, -+ 0x6a, 0x3d, -+ }; -+ const u8 LE_v2[] = { -+ //OutDoor -+ 0x13, 0x8d, -+ 0x2a, 0, -+ 0x2b, 0, -+ 0x6a, 0x3d, -+ //Indoor 60Hz(Default) -+ 0x13, 0x8d, -+ 0x2a, 0, -+ 0x2b, 0, -+ 0x6a, 0x3d, -+ //Indoor 50Hz -+ 0x13, 0x8d, -+ 0x2a, 0x10, -+ 0x2b, 0x14, -+ 0x6a, 0x3d, -+ }; -+ u8 *regs; -+ int n = 4; -+ int i = 0; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ DPRINTK("in function %s ,parameter=%d\n", __FUNCTION__, light); -+ switch (light) { -+ case 0: -+ i = 0 * n * 2; -+ break; -+ case 60: -+ i = 1 * n * 2; -+ break; -+ case 50: -+ i = 2 * n * 2; -+ break; -+ default: -+ i = 0; -+ break; -+ } -+ -+ regs = &LE_v2[i]; -+ if (pov->version == ((PID_OV_v3 << 8) | (PID_9640_v3))) { -+ DPRINTK("ver 3 sensor!\n"); -+ regs = &LE_v3[i]; -+ } -+ -+ -+ for (i = 0; i < n * 2; i += 2) -+ ret |= ov9640_write(regs[i], regs[i + 1]); -+ return OV_ERR_NONE; -+} -+ -+int ov9640_set_color_saturation(int saturation) -+{ -+ const u8 CS[] = { -+ //Saturation: 0.25 -+ 0x4f, 0x14, -+ 0x50, 0x10, -+ 0x51, 0x3, -+ 0x52, 0x6, -+ 0x53, 0x13, -+ 0x54, 0x19, -+ //Saturation 0.5 -+ 0x4f, 0x28, -+ 0x50, 0x22, -+ 0x51, 0x6, -+ 0x52, 0xc, -+ 0x53, 0x26, -+ 0x54, 0x33, -+ //Saturation 0.75 (Default) -+ 0x4f, 0x3c, -+ 0x50, 0x32, -+ 0x51, 0x9, -+ 0x52, 0x13, -+ 0x53, 0x39, -+ 0x54, 0x4c, -+ //Saturation 1.0 -+ 0x4f, 0x50, -+ 0x50, 0x43, -+ 0x51, 0xd, -+ 0x52, 0x19, -+ 0x53, 0x4d, -+ 0x54, 0x66, -+ //Saturation 1.25 -+ 0x4f, 0x64, -+ 0x50, 0x53, -+ 0x51, 0x10, -+ 0x52, 0x1f, -+ 0x53, 0x5f, -+ 0x54, 0x7f, -+ }; -+ u8 *regs; -+ int n = 6; -+ int i; -+ -+ DPRINTK("in function %s ,parameter=%d\n", __FUNCTION__, saturation); -+ if (saturation < 0) -+ saturation = 0; -+ if (saturation > 4) -+ saturation = 4; -+ -+ regs = &CS[saturation * n * 2]; -+ for (i = 0; i < n * 2; i += 2) -+ ov9640_write(regs[i], regs[i + 1]); -+ return OV_ERR_NONE; -+ -+} -+ -+int ov9640_set_contrast(int contrast) -+{ -+ const u8 CO[] = { -+ //Low contrast -+ 0x6C, 0x20, -+ 0x6D, 0x50, -+ 0x6E, 0xc0, -+ 0x6F, 0xa8, -+ 0x70, 0x88, -+ 0x71, 0x80, -+ 0x72, 0x78, -+ 0x73, 0x70, -+ 0x74, 0x68, -+ 0x75, 0x58, -+ 0x76, 0x40, -+ 0x77, 0x30, -+ 0x78, 0x28, -+ 0x79, 0x20, -+ 0x7A, 0x1e, -+ 0x7B, 0x18, -+ 0x7C, 0x04, -+ 0x7D, 0x07, -+ 0x7E, 0x1f, -+ 0x7F, 0x49, -+ 0x80, 0x5a, -+ 0x81, 0x6a, -+ 0x82, 0x79, -+ 0x83, 0x87, -+ 0x84, 0x94, -+ 0x85, 0x9f, -+ 0x86, 0xaf, -+ 0x87, 0xbb, -+ 0x88, 0xcf, -+ 0x89, 0xdf, -+ 0x8A, 0xee, -+ //Middle contrast (default) -+ 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, -+ //High contrast -+ 0x6c, 0x50, -+ 0x6d, 0x60, -+ 0x6e, 0x58, -+ 0x6f, 0x58, -+ 0x70, 0x58, -+ 0x71, 0x50, -+ 0x72, 0x50, -+ 0x73, 0x50, -+ 0x74, 0x50, -+ 0x75, 0x50, -+ 0x76, 0x4c, -+ 0x77, 0x4c, -+ 0x78, 0x45, -+ 0x79, 0x3c, -+ 0x7a, 0x2c, -+ 0x7b, 0x24, -+ 0x7c, 0x05, -+ 0x7d, 0x0b, -+ 0x7e, 0x16, -+ 0x7f, 0x2c, -+ 0x80, 0x37, -+ 0x81, 0x41, -+ 0x82, 0x4b, -+ 0x83, 0x55, -+ 0x84, 0x5f, -+ 0x85, 0x69, -+ 0x86, 0x7c, -+ 0x87, 0x8f, -+ 0x88, 0xb1, -+ 0x89, 0xcf, -+ 0x8a, 0xe5, -+ }; -+ -+ u8 *regs; -+ int n = 31; -+ int i; -+ -+ DPRINTK("in function %s parameter=%d \n", __FUNCTION__, contrast); -+ if (contrast < 0) -+ contrast = 0; -+ if (contrast > 2) -+ contrast = 2; -+ -+ regs = &CO[contrast * n * 2]; -+ for (i = 0; i < n * 2; i += 2) -+ ov9640_write(regs[i], regs[i + 1]); -+ return OV_ERR_NONE; -+ -+} -+ -+int ov9640_set_back_light(int b_light) -+{ -+ const u8 BL[] = { -+ 0x3B, 0, -+ 0x3B, 8, -+ 0x3B, 0x10, -+ 0x3B, 0x18, -+ }; -+ u8 *regs; -+ int n = 1; -+ int i; -+ -+ DPRINTK("in function %s parameter=%d\n", __FUNCTION__, b_light); -+ if (b_light < 0) -+ b_light = 0; -+ if (b_light > 3) -+ b_light = 3; -+ -+ regs = &BL[b_light * n * 2]; -+ for (i = 0; i < n * 2; i += 2) -+ ov9640_write(regs[i], regs[i + 1]); -+ return OV_ERR_NONE; -+} -+ -+int ov9640_stop_third_des(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *pdesc, *ptmp; -+ unsigned int phy_addr; -+ int i; -+ -+ // stop the dma transfer on one frame captured -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo0_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo0_num_descriptors * 2; -+ for (i = 0; i < cam_ctx->fifo0_num_descriptors; i++) -+ (ptmp + i)->dtadr = (pdesc + i)->dtadr; -+ -+ pdesc += cam_ctx->fifo0_num_descriptors - 1; -+ pdesc->dcmd = (pdesc->dcmd & DCMD_LENGTH) | DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR; -+ pdesc += cam_ctx->fifo0_num_descriptors; -+ pdesc->dcmd = (pdesc->dcmd & DCMD_LENGTH) | DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR; -+ pdesc += cam_ctx->fifo0_num_descriptors; -+ pdesc->ddadr |= 0x1; -+ -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo1_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo1_num_descriptors * 2; -+ for (i = 0; i < cam_ctx->fifo1_num_descriptors; i++) -+ (ptmp + i)->dtadr = (pdesc + i)->dtadr; -+ pdesc += cam_ctx->fifo1_num_descriptors * 3 - 1; -+ pdesc->ddadr |= 0x1; -+ -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo2_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo2_num_descriptors * 2; -+ for (i = 0; i < cam_ctx->fifo2_num_descriptors; i++) -+ (ptmp + i)->dtadr = (pdesc + i)->dtadr; -+ pdesc += cam_ctx->fifo2_num_descriptors * 3 - 1; -+ pdesc->ddadr |= 0x1; -+} -+ -+int ov9640_stop_third_des1(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *pdesc, *ptmp; -+ unsigned int phy_addr; -+ int i; -+ -+ // stop the dma transfer on one frame captured -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo0_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo0_num_descriptors * 2; -+ /* -+ for (i=0;i<cam_ctx->fifo0_num_descriptors;i++) -+ (ptmp+i)->dtadr = (pdesc+i)->dtadr; -+ */ -+ pdesc += cam_ctx->fifo0_num_descriptors - 1; -+ pdesc->dcmd = DCMD_FLOWSRC | DCMD_BURST32; -+ pdesc += cam_ctx->fifo0_num_descriptors; -+ pdesc->dcmd = DCMD_FLOWSRC | DCMD_BURST32; -+ pdesc += cam_ctx->fifo0_num_descriptors; -+ pdesc->ddadr |= 0x1; -+ -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo1_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo1_num_descriptors * 2; -+ /* -+ for (i=0;i<cam_ctx->fifo1_num_descriptors;i++) -+ (ptmp+i)->dtadr = (pdesc+i)->dtadr; -+ */ -+ pdesc += cam_ctx->fifo1_num_descriptors * 3 - 1; -+ pdesc->ddadr |= 0x1; -+ -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo2_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo2_num_descriptors * 2; -+ /* -+ for (i=0;i<cam_ctx->fifo2_num_descriptors;i++) -+ (ptmp+i)->dtadr = (pdesc+i)->dtadr; -+ */ -+ pdesc += cam_ctx->fifo2_num_descriptors * 3 - 1; -+ pdesc->ddadr |= 0x1; -+} -+ -+int find_window(struct video_window *vw, int *sub_win) -+{ -+ int ret = OV_SIZE_NONE; -+ -+ *sub_win = 1; -+ if (vw->width > 1280 || vw->height > 960 || vw->width < 88 || vw->height < 72) { -+ ret = OV_SIZE_NONE; -+ } -+ else if (vw->width == 1280 && vw->height == 960) { -+ *sub_win = 0; -+ ret = OV_SIZE_SXGA; -+ } -+ else if (vw->width >= 640 && vw->height >= 480) { -+ if (vw->width == 640 && vw->height == 480) -+ *sub_win = 0; -+ ret = OV_SIZE_VGA; -+ } -+ else if (vw->width >= 352 && vw->height >= 288) { -+ if (vw->width == 352 && vw->height == 288) -+ *sub_win = 0; -+ ret = OV_SIZE_CIF; -+ } -+ else if (vw->width >= 320 && vw->height >= 240) { -+ if (vw->width == 320 && vw->height == 240) -+ *sub_win = 0; -+ ret = OV_SIZE_QVGA; -+ } -+ else if (vw->width >= 176 && vw->height >= 144) { -+ if (vw->width == 176 && vw->height == 144) -+ *sub_win = 0; -+ ret = OV_SIZE_QCIF; -+ } -+ else if (vw->width >= 160 && vw->height >= 120) { -+ if (vw->width == 160 && vw->height == 120) -+ *sub_win = 0; -+ ret = OV_SIZE_QQVGA; -+ } -+ else if (vw->width >= 88 && vw->height >= 72) { -+ if (vw->width == 88 && vw->height == 72) -+ *sub_win = 0; -+ ret = OV_SIZE_QQCIF; -+ } -+ DPRINTK("in %s,ret = %d, subwin=%d\n", __FUNCTION__, ret, *sub_win); -+ return ret; -+} -+ -+int ov9640_set_window(struct video_window *vw) -+{ -+ int ret = 0; -+ int x_start, x_end; -+ int y_start, y_end; -+ struct video_window window; -+ int width; -+ int height; -+ int sub_win; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ vw->width = (vw->width + 7) & (~0x7); -+ vw->height = (vw->height + 7) & (~0x7); -+ vw->x = vw->y = 0; -+ x_end = window.width = (vw->width + vw->x); -+ y_end = window.height = (vw->height + vw->y); -+ DPRINTK("in %s, vw-x =%d, vw-y=%d,vw->width=%d,vw->height=%d\n", -+ __FUNCTION__, vw->x, vw->y, vw->width, vw->height); -+ ret = find_window(&window, &sub_win); -+ if (ret <= OV_SIZE_NONE) -+ return -1; -+ -+ ret = ov9640_set_format(ret, OV_FORMAT_YUV_422); -+ if (ret < 0) -+ return -1; -+ -+ /* -+ if ((sub_win == 1) || (vw->x != 0) || (vw->y != 0) || (pov->sub_win != sub_win)) { -+ u8 href = 0; -+ u8 vref = 0; -+ ov9640_read(0x32, &href); -+ href = href & 0xc0 | (vw->width & 0x7) << 3 | (vw->x & 0x7); -+ ov9640_write(0x17, vw->x >> 3); -+ ov9640_write(0x18, x_end >> 3); -+ ov9640_write(0x19, vw->y >> 2); -+ ov9640_write(0x20, y_end >> 2); -+ ov9640_read(0x3, &vref); -+ vref = vref & 0xf0 | (vw->height & 0x3) << 2 | (vw->y & 0x3); -+ pov->sub_win = sub_win; -+ } -+ */ -+ pov->win = *vw; -+ return ret; -+} -+ -+int ov9640_get_window(struct video_window *vw) -+{ -+ ov9640 *pov; -+ pov = &g_ov; -+ *vw = pov->win; -+ return 0; -+} -+ -+struct win_size { -+ int width; -+ int height; -+}; -+int ov9640_set_sensor_size(void *w_size) -+{ -+ struct win_size size; -+ ov9640 *pov; -+ pov = &g_ov; -+ if (copy_from_user(&size, w_size, sizeof(struct win_size))) { -+ return -EFAULT; -+ } -+//make it in an even of multiple of 8 -+ size.height = (size.height + 7) / 8 * 8; -+ pov->sensor_width = size.width; -+ pov->sensor_height = size.height; -+ return 0; -+} -+ -+int ov9640_get_sensor_size(void *w_size) -+{ -+} -+int ov9640_set_output_size(void *w_size) -+{ -+ struct win_size size; -+ ov9640 *pov; -+ pov = &g_ov; -+ if (copy_from_user(&size, w_size, sizeof(struct win_size))) { -+ return -EFAULT; -+ } -+//make it in an even of multiple of 8 -+ size.height = (size.height + 7) / 8 * 8; -+ pov->sensor_width = size.width; -+ pov->sensor_height = size.height; -+ return 0; -+} -+ -+int ov9640_get_output_size(void *w_size) -+{ -+} -+int test_divider(int res, int fps) -+{ -+ int max_hz = 48 * 1000000; -+ int div = 1; -+ int i; -+ int ov_fps[5] = { 3, 7, 15, 30, 60 }; -+ u32 value = 320 * 240; -+ /* -+ switch (prevSize) { -+ case OV_SIZE_QQCIF: -+ value = 88 * 72; -+ break; -+ case OV_SIZE_QQVGA: -+ value = 176 * 144; -+ break; -+ case OV_SIZE_QCIF: -+ value = 160 * 120; -+ break; -+ case OV_SIZE_QVGA: -+ value = 320 * 240; -+ break; -+ case OV_SIZE_CIF: -+ value = 352 * 288; -+ break; -+ case OV_SIZE_VGA: -+ value = 640 * 480; -+ break; -+ case OV_SIZE_SXGA: -+ value = 1280 * 960; -+ break; -+ } -+ -+ while (max_hz / res / div > fps) -+ div++; -+ if (div > 64) -+ div = 64; -+ return (div - 1); -+ -+ for (i =0;i<5;i++) -+ if ( fps < ov_fps[i] ) -+ continue; -+ */ -+ if (fps == 0) -+ return 0; -+ if (fps > 60) -+ fps = 60; -+ return (div = 60 / fps - 1); -+} -+ -+int ov9640_set_fps(int fps, int min_fps) -+{ -+ u32 res = 0; -+ u8 value; -+ if (fps < 0) { -+ DPRINTK("in %s fps = %d divider value =%d\n", __FUNCTION__, fps, res); -+ fps = 15; -+ } -+ res = test_divider(0, fps); -+ ov9640_read(OV9640_CLKRC, &value); -+ value = (value & 0xc0) | res; -+ ov9640_write(OV9640_CLKRC, value); -+ DPRINTK("in %s fps = %d divider value =%d\n", __FUNCTION__, fps, res); -+ /* -+ ov9640_set_night_mode(); -+ ov9640_set_action_mode(); -+ ov9640_set_auto_mode(); -+ */ -+ return 0; -+} -+ -+#ifndef MIN -+#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -+#endif -+#ifndef MAX -+#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -+#endif -+ -+void write_balance() -+{ -+ u8 yav, uav, vav; -+ static int bg = 0x80; -+ static int rg = 0x24; -+ int awb_mode; -+ ov9640 *pov; -+ -+ pov = &g_ov; -+ -+ if (pov->version == ((PID_OV_v3 << 8) | (PID_9640_v3))) { -+ DPRINTK("ver 3 sensor!\n"); -+ return; -+ } -+ -+ -+ prv_read_sensor_reg(0x5, &vav); -+ prv_read_sensor_reg(0x6, &yav); -+ prv_read_sensor_reg(0x8, &uav); -+ DPRINTK("in %s, v =%x ,y =%x,u =%x\n)", __FUNCTION__, vav, yav, uav); -+ if (yav >= 0x20 && yav <= 0xc0) { -+ if (vav < 50) -+ rg = MIN(255, rg + 40); -+ else if (vav < 80) -+ rg = MIN(255, rg + 20); -+ else if (vav < 100) -+ rg = MIN(255, rg + 5); -+ else if (vav < 120) -+ rg = MIN(255, rg + 1); -+ else if (vav > 206) -+ rg = MAX(0, rg - 40); -+ else if (vav > 180) -+ rg = MAX(0, rg - 20); -+ else if (vav > 156) -+ rg = MAX(0, rg - 5); -+ else if (vav > 136) -+ rg = MAX(0, rg - 1); -+ -+ if (uav < 50) -+ bg = MIN(255, bg + 40); -+ else if (uav < 80) -+ bg = MIN(255, bg + 20); -+ else if (uav < 100) -+ bg = MIN(255, bg + 5); -+ else if (uav < 120) -+ bg = MIN(255, bg + 1); -+ else if (uav > 206) -+ bg = MAX(0, bg - 40); -+ else if (uav > 180) -+ bg = MAX(0, bg - 20); -+ else if (uav > 156) -+ bg = MAX(0, bg - 5); -+ else if (uav > 136) -+ bg = MAX(0, bg - 1); -+ } -+ ov9640_write(0x01, bg); -+ ov9640_write(0x2, rg); -+} -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ov9640_hw.h linux-2.6.16.5-exz/drivers/media/video/ov9640_hw.h ---- linux-2.6.16.5/drivers/media/video/ov9640_hw.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ov9640_hw.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,259 @@ -+/* -+ ov9640_hw - Omnivision 9640 CMOS sensor driver -+ -+ Copyright (C) 2003, Intel Corporation -+ -+ 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 program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ 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 _OV_9640_HW_H_ -+#define _OV_9640_HW_H_ -+ -+/*********************************************************************** -+ * -+ * Constants & Structures -+ * -+ ***********************************************************************/ -+// Revision constants -+#define PID_OV 0x96 -+#define PID_9640 0x48 -+ -+#define PID_OV_v3 0x96 -+#define PID_9640_v3 0x49 -+ -+// Return codes -+#define OV_ERR_NONE 0x00 -+#define OV_ERR_TIMEOUT -1 -+#define OV_ERR_PARAMETER -2 -+#define OV_COMM_ERR -3 -+ -+#define CIBR0_PHY (0x50000000 + 0x28) -+#define CIBR1_PHY (0x50000000 + 0x30) -+#define CIBR2_PHY (0x50000000 + 0x38) -+#define DEBUG 1 -+#define DPRINTK(fmt,args...) do { if (DEBUG) printk("in function %s "fmt,__FUNCTION__,##args);} while(0) -+ -+// Output Size & Format -+/* -+#define OV_SIZE_NONE 0 -+#define OV_SIZE_QQVGA 0x01 -+#define OV_SIZE_QVGA ( OV_SIZE_QQVGA << 1 ) -+#define OV_SIZE_VGA ( OV_SIZE_QQVGA << 2 ) -+#define OV_SIZE_SXGA ( OV_SIZE_QQVGA << 3 ) -+#define OV_SIZE_QQCIF 0x10 -+#define OV_SIZE_QCIF ( OV_SIZE_QQCIF << 1 ) -+#define OV_SIZE_CIF ( OV_SIZE_QQCIF << 2 ) -+#define OV_FORMAT_NONE 0 -+#define OV_FORMAT_YUV_422 1 -+#define OV_FORMAT_RGB_565 2 -+*/ -+enum OV_SIZE { -+ OV_SIZE_NONE=0 , -+ OV_SIZE_QQVGA , -+ OV_SIZE_QVGA , -+ OV_SIZE_VGA , -+ OV_SIZE_SXGA , -+ OV_SIZE_QQCIF , -+ OV_SIZE_QCIF , -+ OV_SIZE_CIF -+}; -+enum OV_FORMAT { -+ OV_FORMAT_NONE=0 , -+ OV_FORMAT_YUV_422, -+ OV_FORMAT_RGB_565, -+}; -+ -+// Camera Mode -+#define VIEWFINDER_MODE 0x10 -+#define STILLFRAME_MODE 0x20 -+ -+// Others -+#define OV9640_TIMEOUT 1000 // ms to timeout. -+ -+// OV9640 Register Definitions -+#define OV9640_GAIN 0x0000 -+#define OV9640_BLUE 0x0001 -+#define OV9640_RED 0x0002 -+#define OV9640_VREF 0x0003 -+#define OV9640_COM1 0x0004 -+#define OV9640_BAVE 0x0005 // U/B Average Level -+#define OV9640_GEAVE 0x0006 // Y/Ge Average Level -+#define OV9640_GOAVE 0x0007 // Y/Go Average Level -+#define OV9640_RAVE 0x0008 // V/R Average level -+#define OV9640_COM2 0x0009 // Common control 2 -+#define OV9640_PID 0x000A // Product ID -+#define OV9640_VER 0x000B // Version -+#define OV9640_COM3 0x000C -+#define OV9640_COM4 0x000D -+#define OV9640_COM5 0x000E -+#define OV9640_COM6 0x000F -+#define OV9640_AECH 0x0010 -+#define OV9640_CLKRC 0x0011 -+#define OV9640_COM7 0x0012 -+#define OV9640_COM8 0x0013 -+#define OV9640_COM9 0x0014 -+#define OV9640_COM10 0x0015 -+#define OV9640_WS 0x0016 -+#define OV9640_HSTART 0x0017 -+#define OV9640_HSTOP 0x0018 -+#define OV9640_VSTRT 0x0019 -+#define OV9640_VSTOP 0x001A -+#define OV9640_PSHFT 0x001B -+#define OV9640_MIDH 0x001C -+#define OV9640_MIDL 0x001D -+#define OV9640_DLY 0x001E -+#define OV9640_LAEC 0x001F -+#define OV9640_BOS 0x0020 -+#define OV9640_GBOS 0x0021 -+#define OV9640_GROS 0x0022 -+#define OV9640_ROS 0x0023 -+#define OV9640_AEW 0x0024 -+#define OV9640_AEB 0x0025 -+#define OV9640_VPT 0x0026 -+#define OV9640_BBIAS 0x0027 -+#define OV9640_GbBIAS 0x0028 -+#define OV9640_GrBIAS 0x0029 -+#define OV9640_EXHCH 0x002A -+#define OV9640_EXHCL 0x002B -+#define OV9640_RBIAS 0x002C -+#define OV9640_ADVFL 0x002D -+#define OV9640_ADVFH 0x002E -+#define OV9640_YAVE 0x002F -+#define OV9640_HSYST 0x0030 -+#define OV9640_HSYEN 0x0031 -+#define OV9640_HREF 0x0032 -+#define OV9640_CHLF 0x0033 -+#define OV9640_ARBLM 0x0034 -+#define OV9640_VRHL 0x0035 -+#define OV9640_VIDO 0x0036 -+#define OV9640_ADC 0x0037 -+#define OV9640_ACOM 0x0038 -+#define OV9640_OFON 0x0039 -+#define OV9640_TSLB 0x003A -+#define OV9640_COM11 0x003B -+#define OV9640_COM12 0x003C -+#define OV9640_COM13 0x003D -+#define OV9640_COM14 0x003E -+#define OV9640_EDGE 0x003F -+#define OV9640_COM15 0x0040 -+#define OV9640_COM16 0x0041 -+#define OV9640_COM17 0x0042 -+#define OV9640_AWBTH1 0x0043 -+#define OV9640_AWBTH2 0x0044 -+#define OV9640_AWBTH3 0x0045 -+#define OV9640_AWBTH4 0x0046 -+#define OV9640_AWBTH5 0x0047 -+#define OV9640_AWBTH6 0x0048 -+#define OV9640_MTX1 0x004F -+#define OV9640_MTX2 0x0050 -+#define OV9640_MTX3 0x0051 -+#define OV9640_MTX4 0x0052 -+#define OV9640_MTX5 0x0053 -+#define OV9640_MTX6 0x0054 -+#define OV9640_MTX7 0x0055 -+#define OV9640_MTX8 0x0056 -+#define OV9640_MTX9 0x0057 -+#define OV9640_MTXS 0x0058 -+#define OV9640_AWBC1 0x0059 -+#define OV9640_AWBC2 0x005A -+#define OV9640_AWBC3 0x005B -+#define OV9640_AWBC4 0x005C -+#define OV9640_AWBC5 0x005D -+#define OV9640_AWBC6 0x005E -+#define OV9640_AWBC7 0x005F -+#define OV9640_AWBC8 0x0060 -+#define OV9640_AWBC9 0x0061 -+#define OV9640_LCC1 0x0062 -+#define OV9640_LCC2 0x0063 -+#define OV9640_LCC3 0x0064 -+#define OV9640_LCC4 0x0065 -+#define OV9640_LCC5 0x0066 -+#define OV9640_MANU 0x0067 -+#define OV9640_MANV 0x0068 -+#define OV9640_HV 0x0069 -+#define OV9640_MBD 0x006A -+#define OV9640_DBLV 0x006B -+#define OV9640_GSP0 0x006C -+#define OV9640_GSP1 0x006D -+#define OV9640_GSP2 0x006E -+#define OV9640_GSP3 0x006F -+#define OV9640_GSP4 0x0070 -+#define OV9640_GSP5 0x0071 -+#define OV9640_GSP6 0x0072 -+#define OV9640_GSP7 0x0073 -+#define OV9640_GSP8 0x0074 -+#define OV9640_GSP9 0x0075 -+#define OV9640_GSP10 0x0076 -+#define OV9640_GSP11 0x0077 -+#define OV9640_GSP12 0x0078 -+#define OV9640_GSP13 0x0079 -+#define OV9640_GSP14 0x007A -+#define OV9640_GSP15 0x007B -+#define OV9640_GST0 0x007C -+#define OV9640_GST1 0x007D -+#define OV9640_GST2 0x007E -+#define OV9640_GST3 0x007F -+#define OV9640_GST4 0x0080 -+#define OV9640_GST5 0x0081 -+#define OV9640_GST6 0x0082 -+#define OV9640_GST7 0x0083 -+#define OV9640_GST8 0x0084 -+#define OV9640_GST9 0x0085 -+#define OV9640_GST10 0x0086 -+#define OV9640_GST11 0x0087 -+#define OV9640_GST12 0x0088 -+#define OV9640_GST13 0x0089 -+#define OV9640_GST14 0x008A -+ -+// End of OV9640 register -+#define OV9640_REGEND ( OV9640_GST14 + 1 ) -+ -+ -+ -+/*********************************************************************** -+ * -+ * Function Prototype -+ * -+ ***********************************************************************/ -+int ov9640_set_regs( u8 *regP ); -+int ov9640_read_all_regs( u8 *bufP, u32 numRegs ); -+ -+void ov9640_power_down( int powerDown ); -+void ov9640_reset( void ); -+void ov9640_wait( int ms ); -+ -+int ov9640_version_revision(u8 * pCmRevision, u8 *pSensorRevision); -+void ov9640_set_HSYNC(void); -+void ov9640_auto_fucntion_on(void); -+void ov9640_auto_fucntion_off(void); -+ -+int ov9640_viewfinder_on(void); -+int ov9640_viewfinder_off(void); -+int ov9640_halt_video_output(void); -+int ov9640_resume_to_full_output_mode(void); -+int ov9640_get_single_image(void); -+ -+int ov9640_set_format( u32 captureSizeFormat, u32 colorFormat ); -+ -+int i2c_init(void); -+int i2c_deinit(void); -+ -+extern int i2c_ov9640_init(void); -+extern int i2c_ov9640_cleanup(void); -+extern int ov9640_read(u8 addr, u8 *pvalue); -+extern int ov9640_write(u8 addr, u8 value); -+ -+ -+#endif -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ov9650.c linux-2.6.16.5-exz/drivers/media/video/ov9650.c ---- linux-2.6.16.5/drivers/media/video/ov9650.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ov9650.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,576 @@ -+/* -+ ov9650 - Omnivision 9650 CMOS sensor driver -+ -+ Copyright (C) 2003, Intel Corporation -+ -+ 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 program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ 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/types.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+#include <linux/ctype.h> -+ -+#include <asm/irq.h> -+#include <asm/hardware.h> -+ -+#include "camera.h" -+#include "ov9650.h" -+#include "ov9650_hw.h" -+ -+ -+#define MAX_WIDTH 1280 -+#define MAX_HEIGHT 1024 -+#define MIN_WIDTH 88 -+#define MIN_HEIGHT 72 -+ -+#define MAX_BPP 16 -+#define WIDTH_DEFT 320 -+#define HEIGHT_DEFT 240 -+#define FRAMERATE_DEFT 0xf -+ -+/* -+ * It is required to have at least 3 frames in buffer -+ * in current implementation -+ */ -+#define FRAMES_IN_BUFFER 3 -+#define MIN_FRAMES_IN_BUFFER 3 -+#define MAX_FRAME_SIZE (MAX_WIDTH * MAX_HEIGHT * (MAX_BPP >> 3)) -+#define BUF_SIZE_DEFT (MAX_FRAME_SIZE ) -+#define SINGLE_DESC_TRANS_MAX PAGE_SIZE -+#define MAX_DESC_NUM ((MAX_FRAME_SIZE / SINGLE_DESC_TRANS_MAX + 1) *\ -+ MIN_FRAMES_IN_BUFFER) -+ -+#define MAX_BLOCK_NUM 20 -+extern ov9650 g_ov9650; -+extern void set_still_image_ready(int); -+ -+camera_function_t camera_ov9650_func = { -+ .init = camera_func_ov9650_init, -+ .deinit = camera_func_ov9650_deinit, -+ .set_capture_format = camera_func_ov9650_set_capture_format, -+ .start_capture = camera_func_ov9650_start_capture, -+ .stop_capture = camera_func_ov9650_stop_capture, -+ .command = camera_func_ov9650_command, -+ .pm_management = camera_func_ov9650_pm, -+}; -+ -+/*********************************************************************** -+ * -+ * OV9650 Functions -+ * -+ ***********************************************************************/ -+static void ov9650_gpio_init(void) -+{ -+ -+ set_GPIO_mode(27 | GPIO_ALT_FN_3_IN); /* CIF_DD[0] */ -+ set_GPIO_mode(114 | GPIO_ALT_FN_1_IN); /* CIF_DD[1] */ -+ set_GPIO_mode(51 | GPIO_ALT_FN_1_IN); /* CIF_DD[2] */ -+ set_GPIO_mode(115 | GPIO_ALT_FN_2_IN); /* CIF_DD[3] */ -+ set_GPIO_mode(95 | GPIO_ALT_FN_2_IN); /* CIF_DD[4] */ -+ set_GPIO_mode(94 | GPIO_ALT_FN_2_IN); /* CIF_DD[5] */ -+ set_GPIO_mode(17 | GPIO_ALT_FN_2_IN); /* CIF_DD[6] */ -+ set_GPIO_mode(108 | GPIO_ALT_FN_1_IN); /* CIF_DD[7] */ -+ set_GPIO_mode(23 | GPIO_ALT_FN_1_OUT); /* CIF_MCLK */ -+ set_GPIO_mode(54 | GPIO_ALT_FN_3_IN); /* CIF_PCLK */ -+ set_GPIO_mode(85 | GPIO_ALT_FN_3_IN); /* CIF_LV */ -+ set_GPIO_mode(84 | GPIO_ALT_FN_3_IN); /* CIF_FV */ -+ set_GPIO_mode(50 | GPIO_OUT); /*CIF_PD */ -+ set_GPIO_mode(19 | GPIO_OUT); /*CIF_RST */ -+ -+ -+ return; -+ -+} -+ -+void ov9650_set_clock(unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz) -+{ -+ unsigned int ciclk = 0, value, div, cccr_l; -+ -+ // determine the LCLK frequency programmed into the CCCR. -+ cccr_l = (CCCR & 0x0000001F); -+ -+ if (cccr_l < 8) // L = [2 - 7] -+ ciclk = (13 * cccr_l) * 100; -+ else if (cccr_l < 17) // L = [8 - 16] -+ ciclk = ((13 * cccr_l) * 100) >> 1; -+ else if (cccr_l < 32) // L = [17 - 31] -+ ciclk = ((13 * cccr_l) * 100) >> 2; -+ DPRINTK(KERN_WARNING "the mclk_khz = %d \n", mclk_khz); -+ -+ // want a divisor that gives us a clock rate as close to, but not more than the given mclk. -+ div = (ciclk + mclk_khz) / (2 * mclk_khz) - 1; -+ -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | CI_CICR4_DIV_SMASK << CI_CICR4_DIV_SHIFT); -+ value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0; -+ value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0; -+ value |= div << CI_CICR4_DIV_SHIFT; -+ CICR4 = value; -+ return; -+} -+ -+int camera_func_ov9650_init(p_camera_context_t cam_ctx) -+{ -+ u8 cm_rev, cm_pid; -+ int status; -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ memset(pov, 0, sizeof(ov9650)); -+ -+ pov->pre_size = OV_SIZE_NONE; -+ pov->win.width = cam_ctx->capture_width; -+ pov->win.height = cam_ctx->capture_height; -+ // init context status -+ cam_ctx->dma_channels[0] = 0xFF; -+ cam_ctx->dma_channels[1] = 0xFF; -+ cam_ctx->dma_channels[2] = 0xFF; -+ -+ cam_ctx->capture_width = WIDTH_DEFT; -+ cam_ctx->capture_height = HEIGHT_DEFT; -+ -+ cam_ctx->capture_input_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ cam_ctx->capture_output_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ -+ cam_ctx->frame_rate = cam_ctx->fps = FRAMERATE_DEFT; -+ -+ cam_ctx->mini_fps = FRAMERATE_DEFT - 2; -+ -+ cam_ctx->buf_size = BUF_SIZE_DEFT; -+ cam_ctx->dma_descriptors_size = MAX_DESC_NUM; -+ DPRINTK(KERN_WARNING "dma_descriptors_size =%d,cam_ctx->buf_size=%d\n", cam_ctx->dma_descriptors_size, -+ cam_ctx->buf_size); -+ cam_ctx->vc.maxwidth = MAX_WIDTH; -+ cam_ctx->vc.maxheight = MAX_HEIGHT; -+ cam_ctx->vc.minwidth = MIN_WIDTH; -+ cam_ctx->vc.minheight = MIN_HEIGHT; -+ //DPRINTK( KERN_WARNING" before ov9650_gpio_init\n"); -+ ov9650_gpio_init(); -+ ci_init(); -+ wmb(); -+ // Configure CI according to OV9650's hardware -+ // master parallel with 8 data pins -+ ci_set_mode(CI_MODE_MP, CI_DATA_WIDTH8); -+ // enable pixel clock(sensor will provide pclock) and master clock = 26MHZ -+ //ci_set_clock(cam_ctx->clk_reg_base, 1, 1, 24); -+ ov9650_set_clock(cam_ctx->clk_reg_base, 1, 1, 2400); -+ pov->mclock = 24; -+ -+ // data sample on rising and h,vsync active high -+ ci_set_polarity(0, 0, 0); -+ -+ // fifo control -+ // CISetFIFO(cam_ctx->ci_reg_base, 4000, XLLP_CI_FIFO_THL_32, XLLP_TRUE, XLLP_TRUE); -+ ci_set_fifo(0, CI_FIFO_THL_32, 1, 1); -+ -+ // OV9650 Power on sequence -+ // Take out of Power down mode, PWRDWN=1, NORMAL=0 -+ // Assert Reset -+ // Delay -+ // Remove reset -+ // Delay -+ ov9650_power_down(0); -+ mdelay(1); -+ -+ // init I2C. -+ status = i2c_ov9650_init(); -+ if (status) -+ return status; -+ -+ // 2 Turn on M_CLK using xx MHz and wait for 150 ms. ?? -+ ci_enable(1); -+ mdelay(1); -+ -+ // read out version -+ { -+ cm_pid = cm_rev = 0; -+ status = ov9650_version_revision(&cm_pid, &cm_rev); -+ -+ // Check to make sure we are working with an OV9650 -+ if (cm_pid == PID_OV) { -+ int ver = (PID_OV << 8) | cm_rev; -+ pov->version = ver; -+ } -+ else { -+ return -1; -+ } -+ printk("in fun camera_func_ov9650_init version=%x\n", pov->version); -+ } -+ -+ cam_ctx->sensor_type = CAMERA_TYPE_OV9650; -+ -+ ov9650_soft_reset(); -+ -+ // turn sensor output off -+ ov9650_viewfinder_off(); -+ -+ return 0; -+} -+ -+int camera_func_ov9650_deinit(p_camera_context_t cam_ctx) -+{ -+ //init the prev_xx value. -+ ov9650_set_format(OV_SIZE_NONE, OV_FORMAT_NONE); -+ // power off the external module -+ ov9650_power_down(1); -+ -+ return 0; -+} -+ -+static int get_ov_format(p_camera_context_t cam_ctx, u32 * size_format, u32 * color_format) -+{ -+ u32 ovSizeFormat, ovFormat; -+ -+ // Set the current mode -+ switch (cam_ctx->capture_input_format) { -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ ovFormat = OV_FORMAT_YUV_422; -+ printk("in get_ov_format ovFormat = OV_FORMAT_YUV_422\n"); -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ ovFormat = OV_FORMAT_RGB_565; -+ break; -+ default: -+ printk(KERN_INFO "The Format doesn't support by OV9650 Sensor \n"); -+ return -1; -+ } -+ if (cam_ctx->capture_width == 88 && cam_ctx->capture_height == 72) -+ ovSizeFormat = OV_SIZE_QQCIF; -+ else if (cam_ctx->capture_width == 160 && cam_ctx->capture_height == 120) -+ ovSizeFormat = OV_SIZE_QQVGA; -+ else if (cam_ctx->capture_width == 176 && cam_ctx->capture_height == 144) -+ ovSizeFormat = OV_SIZE_QCIF; -+ else if (cam_ctx->capture_width == 320 && cam_ctx->capture_height == 240) -+ ovSizeFormat = OV_SIZE_QVGA; -+ else if (cam_ctx->capture_width == 352 && cam_ctx->capture_height == 288) -+ ovSizeFormat = OV_SIZE_CIF; -+ else if (cam_ctx->capture_width == 640 && cam_ctx->capture_height == 480) -+ ovSizeFormat = OV_SIZE_VGA; -+ else if (cam_ctx->capture_width == 1280 && cam_ctx->capture_height == 960) -+ ovSizeFormat = OV_SIZE_SXGA; -+ else if (cam_ctx->capture_width == 1280 && cam_ctx->capture_height == 1024) -+ ovSizeFormat = OV_SIZE_SXGA; -+ else { -+ return -1; -+ } -+ if (ovSizeFormat == OV_SIZE_QVGA) -+ printk("ovSizeFormat =OV_SIZE_QVGA \n"); -+ *size_format = ovSizeFormat; -+ *color_format = ovFormat; -+ return 0; -+} -+ -+int camera_func_ov9650_set_capture_format(p_camera_context_t cam_ctx) -+{ -+ CI_MP_TIMING timing; -+ int status = -1; -+ u32 ovSizeFormat, ovFormat; -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ -+ status = get_ov_format(cam_ctx, &ovSizeFormat, &ovFormat); -+ if (status) -+ return -1; -+ -+ status = ov9650_set_format(ovSizeFormat, ovFormat); -+ if (status) -+ return -1; -+ -+ // set capture width/height and timing -+ //timing.BFW = pov->win.x; -+ //timing.BLW = pov->win.y; -+ timing.BFW = 0; -+ timing.BLW = 0; -+ //ci_configure_mp(pov->win.width - 1, pov->win.height - 1, &timing); -+ -+ return status; -+} -+ -+#define COPY_BUFFERS(pdes, p_page, size) \ -+do { \ -+ unsigned int len; \ -+ unsigned int remain_size = size; \ -+ while (remain_size > 0) { \ -+ if (remain_size > PAGE_SIZE) \ -+ len = PAGE_SIZE; \ -+ else \ -+ len = remain_size; \ -+ if (memcpy(page_address(*pdes), page_address(*p_page), len)) \ -+ return -EFAULT; \ -+ remain_size -= len; \ -+ pdes ++;\ -+ p_page++; \ -+ } \ -+} while (0); -+ -+int camera_func_ov9650_start_capture(p_camera_context_t cam_ctx, unsigned int frames) -+{ -+ int status = -1; -+ u32 ovSizeFormat, ovFormat; -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ -+ ci_disable(1); -+ mdelay(1); -+ ci_enable(1); -+ // clear ci fifo -+ ci_reset_fifo(); -+ ci_clear_int_status(0xFFFFFFFF); -+ -+ camera_set_int_mask(cam_ctx, 0x3ff | 0x0400); -+ // turn auto function on only doing continues capture -+ if (frames == 0) { -+// CISR |= (1 << 3); -+// while (!(CISR & (1 << 3))); //Wait a EOF then begin start DMA -+ ov9650_auto_function_on(); -+ // start dma -+ start_dma_transfer(cam_ctx, 0); -+ } -+ else { -+ status = get_ov_format(cam_ctx, &ovSizeFormat, &ovFormat); -+ if (status) -+ return -1; -+ if (pov->pre_size == OV_SIZE_NONE) -+ return -1; -+ printk("in function %s, cam_ctx->block_tail == 0\n", __FUNCTION__); -+ if (pov->pre_size == ovSizeFormat) { -+ if (cam_ctx->block_tail == 0) { -+ } -+ else { -+ struct page **p_page; -+ struct page **pdes; -+ -+ printk("in function %s, cam_ctx->block_tail != 0\n", __FUNCTION__); -+ p_page = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ pdes = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ COPY_BUFFERS(pdes, p_page, cam_ctx->fifo0_transfer_size); -+ COPY_BUFFERS(pdes, p_page, cam_ctx->fifo1_transfer_size); -+ COPY_BUFFERS(pdes, p_page, cam_ctx->fifo2_transfer_size); -+ } -+ set_still_image_ready(1); -+ return 0; -+ } -+ else { -+ ov9650_auto_function_off(); -+ cam_ctx->block_tail = cam_ctx->block_header = 0; -+ ov9650_prepare_capture(cam_ctx, ovSizeFormat, ovFormat); -+ } -+ // turn viewfinder on -+ ov9650_viewfinder_on(); -+ } -+ // turn viewfinder on -+ ov9650_viewfinder_on(); -+ ov9650_set_start(); -+ return 0; -+} -+ -+int Ov9650AutoFunctionOn(void) -+{ -+ u8 regValue = 0; -+ -+ printk("in function %s \n", __FUNCTION__); -+ //ov9650_read(0x13, ®Value); -+ if ((regValue & 0x7) == 7) -+ return 1; -+ return 0; -+} -+ -+int camera_func_ov9650_stop_capture(p_camera_context_t cam_ctx) -+{ -+ if (ov9650_output_stoped()) -+ return 0; -+ printk("in camera_func_ov9650_stop_capture\n"); -+ //if (Ov9650AutoFunctionOn()) -+ // turn auto function off -+ ov9650_auto_function_off(); -+ ov9650_save_gains(); -+ -+ // turn viewfinder off -+ ov9650_viewfinder_off(); -+ stop_dma_transfer(cam_ctx); -+ ov9650_set_stop(cam_ctx); -+ return 0; -+} -+ -+int camera_func_ov9650_command(p_camera_context_t cam_ctx, unsigned int cmd, void *param) -+{ -+ int ret = 0; -+ -+ printk("in function %s, param =%p, \n", __FUNCTION__, param); -+ switch (cmd) { -+ /* get capture size */ -+ case VIDIOCGWIN: -+ { -+ struct video_window vw; -+ vw.width = cam_ctx->capture_width; -+ vw.height = cam_ctx->capture_height; -+ ov9650_get_window(&vw); -+ if (copy_to_user(param, &vw, sizeof(struct video_window))) -+ ret = -EFAULT; -+ break; -+ } -+ -+ /* set capture size. */ -+ case VIDIOCSWIN: -+ { -+ struct video_window vw; -+ if (copy_from_user(&vw, param, sizeof(vw))) { -+ ret = -EFAULT; -+ break; -+ } -+ printk("in %s, vw-x =%d, vw-y=%d,vw.width=%d,vw.height=%d\n", -+ __FUNCTION__, vw.x, vw.y, vw.width, vw.height); -+ if (vw.width > 1280 || vw.height > 1024 || vw.width < MIN_WIDTH || vw.height < MIN_HEIGHT) { -+ ret = -EFAULT; -+ break; -+ } -+ /* -+ */ -+ ov9650_set_window(&vw); -+ cam_ctx->capture_width = vw.width; -+ cam_ctx->capture_height = vw.height; -+ camera_set_capture_format(cam_ctx); -+ break; -+ } -+ /*set picture style */ -+ case WCAM_VIDIOCSSTYLE: -+ { -+ V4l_PIC_STYLE capture_style; -+ capture_style = (V4l_PIC_STYLE) param; -+ cam_ctx->capture_style = (V4l_PIC_STYLE) param; -+ ret = ov9650_set_special_effect(capture_style); -+ printk("in camera_func_ov9650_command ret=%d\n", ret); -+ if (cam_ctx->capture_style != V4l_STYLE_BLACK_WHITE && cam_ctx->capture_style != V4l_STYLE_SEPIA) { -+ } -+ } -+ break; -+ /*set picture light */ -+ case WCAM_VIDIOCSLIGHT: -+ cam_ctx->capture_light = (int) param; -+ ret = ov9650_set_white_balance((int)param); -+ break; -+ /*set picture brightness */ -+ case WCAM_VIDIOCSBRIGHT: -+ cam_ctx->capture_bright = (int) param; -+ ret = ov9650_set_brightness((int) param); -+ break; -+ /*set sensor size */ -+ case WCAM_VIDIOCSSSIZE: -+ return ov9650_set_sensor_size(param); -+ -+ /*get sensor size */ -+ case WCAM_VIDIOCGSSIZE: -+ return ov9650_get_sensor_size(param); -+ -+ /*set output size */ -+ case WCAM_VIDIOCSOSIZE: -+ return ov9650_set_output_size(param); -+ -+ /*get output size */ -+ case WCAM_VIDIOCGOSIZE: -+ return ov9650_get_output_size(param); -+#if 0 -+#endif -+ /*set video mode fps */ -+ case WCAM_VIDIOCSFPS: -+ { -+ struct { -+ int fps, minfps; -+ } cam_fps; -+ DPRINTK("WCAM_VIDIOCSFPS"); -+ if (copy_from_user(&cam_fps, param, sizeof(int) * 2)) { -+ return -EFAULT; -+ } -+ cam_ctx->fps = cam_fps.fps; -+ cam_ctx->mini_fps = cam_fps.minfps; -+ return ov9650_set_fps(cam_fps.fps, cam_fps.minfps); -+ } -+ return -1; -+ case WCAM_VIDIOCSNIGHTMODE: -+ { -+ struct { -+ int mode, maxexpottime; -+ } cam_mode; -+ int mode; -+ if (copy_from_user(&cam_mode, param, sizeof(cam_mode))) { -+ return -EFAULT; -+ } -+ mode = cam_mode.mode; -+ if (mode == V4l_NM_NIGHT) -+ ov9650_set_night_mode(); -+ if (mode == V4l_NM_ACTION) -+ ov9650_set_action_mode(); -+ if (mode == V4l_NM_AUTO) -+ ov9650_set_auto_mode(); -+ } -+ break; -+ case WCAM_VIDIOCSCONTRAST: -+ { -+ ret = ov9650_set_contrast((int)param/50); -+ break; -+ } -+ case WCAM_VIDIOCSFLICKER: -+ { -+ ret = ov9650_set_flicker((int)param); -+ break; -+ } -+ default: -+ printk("in %s default case -----------------cmd =%d param=%p\n", __FUNCTION__, cmd, param); -+ ret = -1; -+ } -+ return ret; -+} -+int camera_func_ov9650_pm(p_camera_context_t cam_ctx, int suspend) -+{ -+ static int resume_dma = 0; -+ if (suspend) { -+ if (cam_ctx != NULL) { -+ if (cam_ctx->dma_started) { -+ dbg_print("camera running, suspended"); -+ stop_dma_transfer(cam_ctx); -+ resume_dma = 1; -+ } -+ } -+ -+ disable_irq(IRQ_CAMERA); -+ CKEN &= ~CKEN24_CAMERA; -+ } -+ else { -+ CKEN |= CKEN24_CAMERA; -+ enable_irq(IRQ_CAMERA); -+ -+ if (cam_ctx != NULL) { -+ dbg_print("camera running, resumed"); -+ camera_init(cam_ctx); -+ //ov9650_restore_property(cam_ctx, 0); -+ -+ -+ if (resume_dma == 1) { -+ camera_start_video_capture(cam_ctx, 0); -+ resume_dma = 0; -+ } -+ } -+ } -+ return 0; -+} -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ov9650.h linux-2.6.16.5-exz/drivers/media/video/ov9650.h ---- linux-2.6.16.5/drivers/media/video/ov9650.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ov9650.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,71 @@ -+/* -+ ov9650 - Omnivision 9650 CMOS sensor driver -+ -+ Copyright (C) 2003, Intel Corporation -+ -+ 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 program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ 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 _OV_9650_H_ -+#define _OV_9650_H_ -+ -+#include <linux/videodev.h> -+#include "camera.h" -+typedef struct { -+ u32 version; -+ u32 stoped; -+ u32 mclock; -+ u32 pre_size; -+ u32 exp_value; -+ u32 exp_time; -+ u32 adjusted_exp_value; -+ u32 adjusted_exp_time; -+ u8 pclock; -+ u32 gain; -+ u32 gaina; -+ u8 blue_gain; -+ u8 red_gain; -+ u8 y_average; -+ u32 sensor_width; -+ u32 sensor_height; -+ u32 sub_win; -+ u32 night_mode; -+ struct video_window win; -+}ov9650; -+ -+////////////////////////////////////////////////////////////////////////////////////// -+// -+// Prototypes -+// -+////////////////////////////////////////////////////////////////////////////////////// -+ -+int camera_func_ov9650_init( p_camera_context_t ); -+ -+int camera_func_ov9650_deinit( p_camera_context_t ); -+ -+int camera_func_ov9650_sleep( p_camera_context_t camera_context ); -+ -+int camera_func_ov9650_wake( p_camera_context_t camera_context ); -+ -+int camera_func_ov9650_set_capture_format( p_camera_context_t ); -+ -+int camera_func_ov9650_start_capture( p_camera_context_t, unsigned int frames ); -+ -+int camera_func_ov9650_stop_capture( p_camera_context_t ); -+ -+int camera_func_ov9650_pm(p_camera_context_t cam_ctx, int suspend); -+ -+int camera_func_ov9650_command(p_camera_context_t camera_context, unsigned int cmd, void *param); -+ -+#endif // _OV_9650_H_ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ov9650_hw.c linux-2.6.16.5-exz/drivers/media/video/ov9650_hw.c ---- linux-2.6.16.5/drivers/media/video/ov9650_hw.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ov9650_hw.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,1773 @@ -+/* -+ ov9650_hw - Omnivision 9650 CMOS sensor driver -+ -+ Copyright (C) 2003, Intel Corporation -+ -+ 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 program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ 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/types.h> -+#include <linux/delay.h> -+#include <asm/hardware.h> -+#include <asm/dma.h> -+ -+#include "camera.h" -+#include "ov9650.h" -+#include "ov9650_hw.h" -+ -+ov9650 g_ov9650; -+/*********************************************************************** -+* Attention: This is platform related! -+***********************************************************************/ -+static const u32 OV9650_PWRDWN_GPIO[2] = { 1, 50 }; -+//static const u32 OV9650_RESET_GPIO[2] = { 1, xxx }; -+volatile int ov9650_step = 0; -+ -+/*********************************************************************** -+* Register Settings -+***********************************************************************/ -+ -+static u8 gInit_9650[] = { -+ /* -+ //0x12, 0x80, //0x12 -+ 0x11, 0x87, //0x11 -+ 0x39, 0x40, //0x39 -+ 0x13, 0x80, //0x13 -+ 0x01, 0x80, //0x01 -+ 0x02, 0x80, //0x -+ 0x00, 0x00, //0x -+ 0x0c, 0x05, //0x stop frame -+ 0x0d, 0x80, //0x -+ 0x12, 0x10, //0x -+ 0x10, 0xf0, //0x -+ 0xa1, 0x00, //0x -+ 0x3a, 0x0c, //0x ??? -+ 0x8c, 0x23, //0x -+ 0x3d, 0x92, //0x -+ 0x18, 0xc6, //0x -+ 0x17, 0x26, //0x -+ 0x1b, 0x01, //0x -+ 0x16, 0x02, //0x -+ 0x33, 0x10, //0x -+ 0x34, 0x38, //0x -+ 0xa8, 0x81, //0x -+ 0x41, 0x10, //0x -+ 0x96, 0x04, //0x -+*/ -+ //0x12, 0x80, //0x12 -+ 0x11, 0x83, //0x11 -+ 0x39, 0x40, //0x39 -+ 0x0e, 0x01, //0x -+ 0x38, 0x12, //0x -+ 0x13, 0xc7, //0x13 -+ 0x14, 0x2a, //Gain Control -+ 0x1e, 0x04, //0x01 -+ -+ 0x01, 0x80, //0x -+ 0x02, 0x80, //0x -+ 0x00, 0x00, //0x -+ 0x10, 0xf0, //0x -+ -+ 0x12, 0x10, //0x -+ 0x0c, 0x05, //0x stop frame -+ 0x0d, 0x80, //0x -+ //0x3a, 0x0d, //enable Digital BLC, Rev0 0x0c -+ -+ //0x1b, 0x00, //0x -+ 0x16, 0x06, //0x -+ 0x33, 0x10, //0x -+ 0x34, 0xbf, //0x -+ 0xa8, 0x81, //0x -+ 0x41, 0x10, //0x -+ 0x96, 0x04, //0x -+ 0x3d, 0x19, //0x -+ 0x1b, 0x01, //0x -+ -+ 0x18, 0xc6, -+ 0x17, 0x26, -+ 0x32, 0xa4, -+ 0x03, 0x36, -+ //0x1a, 0x1e, -+ //0x19, 0x00, -+ 0x8e, 0x00, -+ -+ 0x3c, 0x60, -+ 0x8f, 0xcf, -+ 0x8b, 0x06, -+ 0x35, 0x91, -+ 0x94, 0x99, -+ 0x95, 0x99, -+ 0x40, 0xc1, -+ 0x29, 0x2f, -+ //0x0f, 0x42, //Rev0 0x4a -+ 0x27, 0x90, -+ 0x28, 0x8c, -+ 0x2c, 0x08, -+ 0xa5, 0x80, -+ -+ 0x41, 0x00, -+ 0x13, 0xc5, -+ 0x26, 0xe2, -+ -+ 0x3d, 0x92, -+ 0x69, 0x80, -+ 0x43, 0xf0, -+ 0x44, 0x10, -+ 0x45, 0x67, -+ 0x46, 0x96, -+ 0x47, 0x4e, -+ 0x48, 0x9a, -+ 0x59, 0x36, -+ 0x5a, 0x73, -+ 0x5b, 0x55, -+ 0x5c, 0xa8, -+ 0x5d, 0x84, -+ 0x5e, 0x0f, -+ 0x5f, 0xf0, -+ 0x60, 0x0c, -+ 0x61, 0x20, -+ -+ 0xa5, 0xd9, -+ 0xa4, 0x74, -+ 0x8d, 0x02, -+ -+ 0x13, 0xc7, -+ -+ 0x4f, 0x32, -+ 0x50, 0x27, -+ 0x51, 0x0b, -+ 0x52, 0x0d, -+ 0x53, 0x48, -+ 0x54, 0x55, -+ 0x41, 0x32, -+ -+ 0x8c, 0x23, -+ 0x3d, 0x92, -+ 0x3e, 0x02, -+ 0xa9, 0x97, -+ -+ 0x8f, 0xcf, -+ 0x90, 0x00, -+ 0x91, 0x00, -+ 0x9f, 0x00, -+ 0xa0, 0x00, -+ 0xff,0, // End of list delimiter. -+ -+ 0xff,0 // End of list delimiter. -+}; -+ -+const static u8 gYUV_QQVGA[] = { -+ OV9650_COM10, 0x20, -+ OV9650_COM7, 0x10, -+ OV9650_COM1, 0x24, -+ OV9650_CLKRC, 0x01, -+ -+ // From OmniVision -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_QQCIF[] = { -+ OV9650_COM10, 0x20, -+ OV9650_COM7, 0x08, -+ OV9650_COM1, 0x24, -+ OV9650_CLKRC, 0x01, -+ -+ // From OmniVision -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_VGA[] = { -+ 0x0d, 0x80, -+ 0x11, 0x81, -+ 0x12, 0x40, -+ 0x18, 0xc6, -+ 0x17, 0x26, -+ 0x32, 0xad, -+ 0x03, 0x00, -+ 0x1a, 0x3d, -+ 0x19, 0x01, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+const static u8 gYUV_QVGA[] = { -+ //0x0c, 0x05, -+ 0x0d, 0x80, -+ 0x11, 0x83, -+ 0x12, 0x10, -+ 0x18, 0xc6, -+ 0x17, 0x26, -+ 0x32, 0xa4, -+ 0x03, 0x36, -+ 0x1a, 0x1e, -+ 0x19, 0x00, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+const static u8 gYUV_CIF[] = { -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_QCIF[] = { -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gYUV_SXGA[] = { -+ // From OmniVision -+ 0x0d, 0x40, -+ 0x11, 0x80, -+ 0x12, 0x00, -+ 0x18, 0xbd, -+ 0x17, 0x1d, -+ 0x32, 0xad, -+ 0x03, 0x12, -+ 0x1a, 0x81, -+ 0x19, 0x01, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+ -+const static u8 gRGB_QQVGA[] = { -+ OV9650_COM7, 0x80, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gRGB_QVGA[] = { -+ OV9650_COM7, 0x80, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gRGB_QCIF[] = { -+ OV9650_COM7, 0x80, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+ -+const static u8 gRGB_VGA[] = { -+ OV9650_COM7, 0x80, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gRGB_CIF[] = { -+ OV9650_COM7, 0x80, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+const static u8 gRGB_SXGA[] = { -+ OV9650_COM7, 0x80, -+ OV9650_REGEND, 0x00 // End of list delimiter. -+}; -+ -+/*********************************************************************** -+* Private/helper api -+***********************************************************************/ -+static void ov9650_wait(int ms) -+{ -+ mdelay(ms); -+} -+ -+/*********************************************************************** -+* Sensor read/write -+***********************************************************************/ -+// TODO: temp -+static int ov9650_read(u8 addr, u8 *pvalue) -+{ -+ return i2c_ov9650_read(addr, pvalue); -+} -+ -+static int ov9650_write(u8 addr, u8 value) -+{ -+ return i2c_ov9650_write(addr, value); -+} -+// end TODO -+ -+static int prv_read_sensor_reg(const u8 subAddress, u8 * bufP) -+{ -+ return ov9650_read(subAddress, bufP); -+} -+ -+static int prv_write_sensor_reg(const u8 subAddress, u8 * bufP) -+{ -+ return ov9650_write(subAddress, *bufP); -+} -+ -+static int ov9650_set_regs(u8 * regP) -+{ -+ u32 curReg = 0; -+ int status = 0; -+ -+ // The list is a register number followed by the value. -+ while (regP[curReg << 1] < OV9650_REGEND) { -+ status = prv_write_sensor_reg(regP[curReg << 1], ®P[(curReg << 1) + 1]); -+ if (curReg == 0) -+ ov9650_wait(1); -+ -+ curReg++; -+ } -+ return status; -+} -+ -+static void ov9650_print_all_regs(void) -+{ -+#if 0 -+ // read all register after power up -+ ov9650 *pov; -+ pov = &g_ov9650; -+ int i, maxreg; -+ maxreg = OV9650_LASTREG; -+ -+ dbg_print("start read all default register (0x%x)", maxreg); -+ for(i=0; i<=maxreg; i++) -+ { -+ char value; -+ ov9650_read(i, &value); -+ //dbg_print("reg addr(0x%x) value(0x%x)", i, value); -+ } -+ dbg_print("end read all default register"); -+#endif -+} -+ -+/*********************************************************************** -+* Power & Reset -+***********************************************************************/ -+void ov9650_power_down(int powerDown) -+{ -+ // OV9650 PWRDWN, 0 = NORMAL, 1=POWER DOWN -+ GPDR1 |= GPIO_bit(50); -+ //OV9650 reset CIF_RST, 0 = NORMAL, 1=RESET -+ GPDR0 |= GPIO_bit(19); -+ if (powerDown == 1) { -+ GPSR1 = GPIO_bit(50); -+ } -+ else { -+ GPCR1 = GPIO_bit(50); -+ GPSR0 = GPIO_bit(19); -+ mdelay(20); -+ GPCR0 = GPIO_bit(19); -+ } -+ mdelay(100); -+} -+ -+void ov9650_soft_reset(void) -+{ -+ ov9650 *pov = &g_ov9650; -+ u8 regValue; -+ regValue = 0x80; -+ prv_write_sensor_reg(OV9650_COM7, ®Value); -+ mdelay(10); -+ -+ ov9650_print_all_regs(); -+ -+ ov9650_set_regs(gInit_9650); -+ -+ //0x3a, 0x0d, //enable Digital BLC, Rev0 0x0c -+ //0x0f, 0x42, //Rev0 0x4a -+ if ( (pov->version&0xff) == PID_9650_0 ) -+ { -+ ov9650_write(0x3a, 0x0c); -+ ov9650_write(0x0f, 0x4a); -+ } -+ else -+ { -+ ov9650_write(0x3a, 0x0d); -+ ov9650_write(0x0f, 0x42); -+ } -+ -+ dbg_print("end initial register"); -+ return; -+} -+ -+int ov9650_output_stoped() -+{ -+ ov9650 *pov; -+ pov = &g_ov9650; -+ return pov->stoped; -+} -+ -+void ov9650_set_start() -+{ -+ ov9650 *pov; -+ pov = &g_ov9650; -+ -+ pov->stoped = 0; -+} -+ -+void ov9650_set_stop(p_camera_context_t cam_ctx) -+{ -+ ov9650 *pov; -+ pov = &g_ov9650; -+ -+ pov->stoped = 1; -+} -+ -+/*********************************************************************** -+* Settings -+***********************************************************************/ -+int ov9650_version_revision(u8 * pCmRevision, u8 * pSensorRevision) -+{ -+ prv_read_sensor_reg(OV9650_PID, pCmRevision); -+ prv_read_sensor_reg(OV9650_VER, pSensorRevision); -+ return 0; -+} -+ -+void ov9650_auto_function_on(void) -+{ -+ u8 val; -+ DPRINTK("in function %s\n", __FUNCTION__); -+ prv_read_sensor_reg(OV9650_COM8, &val); -+ val |= 0x07; -+ prv_write_sensor_reg(OV9650_COM8, &val); -+} -+ -+void ov9650_auto_function_off(void) -+{ -+ u8 val; -+ DPRINTK("in function %s\n", __FUNCTION__); -+ prv_read_sensor_reg(OV9650_COM8, &val); -+ val &= ~0x07; -+ prv_write_sensor_reg(OV9650_COM8, &val); -+} -+ -+ -+/*********************************************************************** -+* Viewfinder, still -+***********************************************************************/ -+int ov9650_viewfinder_on(void) -+{ -+ u8 com3; -+ -+ ov9650_print_all_regs(); -+ -+ prv_read_sensor_reg(OV9650_COM3, &com3); -+ com3 &= ~0x01; -+ prv_write_sensor_reg(OV9650_COM3, &com3); -+ -+ return OV_ERR_NONE; -+} -+ -+ -+int ov9650_viewfinder_off(void) -+{ -+ u8 com3; -+ -+ prv_read_sensor_reg(OV9650_COM3, &com3); -+ com3 |= 0x01; -+ prv_write_sensor_reg(OV9650_COM3, &com3); -+ -+ ov9650_print_all_regs(); -+ -+ mdelay(200); -+ return OV_ERR_NONE; -+} -+ -+ -+static u8 *ov9650_get_regs_list(u32 captureSizeFormat, u32 colorFormat) -+{ -+ char *formatNameP=NULL; -+ u8 *defaultDataP=NULL; -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ -+ // Get the default setting. -+ if (colorFormat == OV_FORMAT_YUV_422) { -+ switch (captureSizeFormat) { -+ case OV_SIZE_QQVGA: -+ defaultDataP = (u8 *)gYUV_QQVGA; -+ formatNameP = "QQVGA.422"; -+ break; -+ case OV_SIZE_QQCIF: -+ defaultDataP = (u8 *)gYUV_QQCIF; -+ formatNameP = "QQCIF.422"; -+ break; -+ case OV_SIZE_QVGA: -+ defaultDataP = (u8 *)gYUV_QVGA; -+ formatNameP = "QVGA.422"; -+ break; -+ case OV_SIZE_QCIF: -+ defaultDataP = (u8 *)gYUV_QCIF; -+ formatNameP = "QCIF.422"; -+ break; -+ case OV_SIZE_VGA: -+ defaultDataP = (u8 *)gYUV_VGA; -+ formatNameP = "VGA.422"; -+ break; -+ case OV_SIZE_CIF: -+ defaultDataP = (u8 *)gYUV_CIF; -+ formatNameP = "CIF.422"; -+ break; -+ case OV_SIZE_SXGA: -+ defaultDataP = (u8 *)gYUV_SXGA; -+ formatNameP = "SXGA.422"; -+ break; -+ default: -+ return NULL; -+ } -+ } -+ -+ if (colorFormat == OV_FORMAT_RGB_565) { -+ switch (captureSizeFormat) { -+ case OV_SIZE_QQVGA: -+ defaultDataP = (u8 *)gRGB_QQVGA; -+ formatNameP = "QQVGA.RGB"; -+ break; -+ case OV_SIZE_QCIF: -+ defaultDataP = (u8 *)gRGB_QCIF; -+ formatNameP = "QCIF.RGB"; -+ break; -+ -+ case OV_SIZE_QVGA: -+ defaultDataP = (u8 *)gRGB_QVGA; -+ formatNameP = "QVGA.RGB"; -+ break; -+ case OV_SIZE_VGA: -+ defaultDataP = (u8 *)gRGB_VGA; -+ formatNameP = "VGA.RGB"; -+ break; -+ case OV_SIZE_CIF: -+ defaultDataP = (u8 *)gRGB_CIF; -+ formatNameP = "CIF.RGB"; -+ break; -+ case OV_SIZE_SXGA: -+ defaultDataP = (u8 *)gRGB_SXGA; -+ formatNameP = "SXGA.RGB"; -+ break; -+ default: -+ return NULL; -+ } -+ } -+ dbg_print("%s", formatNameP); -+ return defaultDataP; -+} -+ -+/*********************************************************************** -+* Format -+***********************************************************************/ -+static int ov9650_switch_format(u32 captureSizeFormat, u32 colorFormat) -+{ -+ int status; -+ u8 *regsP; -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ -+ regsP = (u8 *) ov9650_get_regs_list(captureSizeFormat, colorFormat); -+ // Get the pointer to the basic setting. The pointer must be freed after exiting. -+ -+ if (regsP == NULL) -+ return OV_ERR_PARAMETER; -+ -+ status = ov9650_set_regs(regsP); -+ mdelay(50); -+ if (pov->night_mode == 1) { -+ //night mode -+ ov9650_set_night_mode(); -+ } -+ else if (pov->night_mode == 2) { //action mode -+ ov9650_set_action_mode(); -+ } -+ else -+ ov9650_set_auto_mode(); -+ -+ return status; -+} -+ -+int ov9650_set_format(u32 captureSizeFormat, u32 colorFormat) -+{ -+ int status = OV_ERR_PARAMETER; -+ u8 *regsP; -+ static u32 prev_colorFormat = OV_FORMAT_NONE, prev_size = OV_SIZE_NONE; -+ -+ if (prev_colorFormat == colorFormat && captureSizeFormat == prev_size) -+ return 0; -+ if ((captureSizeFormat == OV_SIZE_NONE) && (colorFormat == OV_FORMAT_NONE)) -+ goto no_set; -+ -+ if ((prev_colorFormat == OV_FORMAT_NONE) && (prev_size == OV_SIZE_NONE)) { -+ regsP = (u8 *) ov9650_get_regs_list(captureSizeFormat, colorFormat); -+ // Get the pointer to the basic setting. The pointer must be freed after exiting. -+ -+ if (regsP == NULL) -+ return OV_ERR_PARAMETER; -+ //ov9650_soft_reset(); -+ // Blast the entire parameter tree into the part. -+ status = ov9650_set_regs(regsP); -+ } -+ else { -+ status = ov9650_switch_format(captureSizeFormat, colorFormat); -+ } -+no_set: -+ prev_colorFormat = colorFormat; -+ prev_size = captureSizeFormat; -+ return status; -+} -+ -+void ov9650_save_gains(void) -+{ -+ u8 gainh, gainl, aech, aechm, aecl, laec, blue, red; -+ u32 gain, gaina, exp_value; -+ ov9650 *pov; -+ u8 regValue; -+ static u32 prevSize; -+ -+ pov = &g_ov9650; -+ -+ // Get current size -+ prv_read_sensor_reg(OV9650_COM7, ®Value); -+ switch (regValue) { -+ case 0x00: -+ prevSize = OV_SIZE_SXGA; -+ break; -+ case 0x08: -+ prv_read_sensor_reg(OV9650_COM1, ®Value); -+ if (regValue & 0x20) -+ prevSize = OV_SIZE_QQCIF; -+ else -+ prevSize = OV_SIZE_QCIF; -+ break; -+ case 0x10: -+ prv_read_sensor_reg(OV9650_COM1, ®Value); -+ if (regValue & 0x20) -+ prevSize = OV_SIZE_QQVGA; -+ else -+ prevSize = OV_SIZE_QVGA; -+ break; -+ case 0x20: -+ prevSize = OV_SIZE_CIF; -+ break; -+ case 0x40: -+ prevSize = OV_SIZE_VGA; -+ break; -+ default: -+ prevSize = OV_SIZE_SXGA; -+ break; -+ } -+ pov->pre_size = prevSize; -+ -+ // Get the awb, gain, exposure values -+ prv_read_sensor_reg(OV9650_BLUE, &blue); -+ prv_read_sensor_reg(OV9650_RED, &red); -+ prv_read_sensor_reg(OV9650_GAIN, &gainl); -+ prv_read_sensor_reg(OV9650_VREF, &gainh); -+ gain = gainl + ((gainh>>6)&0x03); -+ prv_read_sensor_reg(OV9650_AECHM, &aechm); -+ prv_read_sensor_reg(OV9650_AECH, &aech); -+ prv_read_sensor_reg(OV9650_COM1, &aecl); -+ exp_value = (((aechm&0x3f)<<10) + (aech << 2)) | (aecl&0x03); -+ prv_read_sensor_reg(OV9650_LAEC, &laec); -+ -+ pov->gain = gain; -+ pov->blue_gain = blue; -+ pov->red_gain = red; -+ pov->exp_value = exp_value; -+ pov->exp_time = laec; -+ -+ //TODO: -+ gaina = (gainl & 0x0f) + 16; -+ if(gainl&0x20) -+ gaina *= 2; -+ if(gainl&0x10) -+ gaina *= 2; -+ pov->gaina = gaina; -+ -+ DPRINTK("gain=%x gaina=%x blue=%x red=%x, expv=%x expt=%x\n", -+ gain, gaina, blue, red, exp_value, laec); -+} -+ -+static void ov9650_adjust_gains(u32 prev_size, u32 cur_size) -+{ -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ if (prev_size == OV_SIZE_QVGA) { -+ if (cur_size == OV_SIZE_VGA) { -+ { -+ /* capture 15 fps */ -+ pov->pclock = 0x81; -+ pov->adjusted_exp_value = pov->exp_value * 2; -+ } -+ if (pov->night_mode == 1) { -+ //night mode -+ //pov->pclock = 0x87; -+ } -+ else if (pov->night_mode == 2) { //action mode -+ pov->pclock = 0x80; -+ } -+ } -+ else if (cur_size == OV_SIZE_SXGA) { -+ int adjexp = 0; -+ adjexp = pov->exp_value * 2; -+#if 0 -+ if (pov->gain & 0x80) { -+ /* 8x gain capture 7.5 fps to 4x gain */ -+ if(adjexp<500) -+ { -+ //pov->pclock = 0x80; -+ adjexp = adjexp * 2; -+ pov->gain = pov->gain & ~0x80; -+ } -+ } -+ if (pov->gain & 0x40) { -+ /* 4x gain capture 7.5 fps to 2x gain */ -+ if(adjexp<500) -+ { -+ //pov->pclock = 0x80; -+ adjexp = adjexp * 2; -+ pov->gain = pov->gain & ~0x40; -+ } -+ } -+ if (pov->gain & 0x20) { -+ if(adjexp<500) -+ { -+ //pov->pclock = 0x80; -+ adjexp = adjexp * 2; -+ pov->gain = pov->gain & ~0x20; -+ } -+ } -+ if (pov->gain & 0x10) { -+ if(adjexp<500) -+ { -+ //pov->pclock = 0x80; -+ adjexp = adjexp * 2; -+ pov->gain = pov->gain & ~0x10; -+ } -+ } -+#endif -+ if (pov->night_mode == 1) { -+ //night mode -+ //pov->pclock = 0x81; -+ } -+ else if (pov->night_mode == 2) { //action mode -+ pov->pclock = 0x80; -+ } -+ pov->adjusted_exp_value = adjexp; -+ } -+ else if (cur_size == OV_SIZE_QVGA) { -+ if (pov->gain & 0x20) { -+ /* hight gain capture 7.5 fps */ -+ pov->pclock = 0x87; -+ pov->gain = pov->gain & ~0x20; -+ pov->adjusted_exp_value = pov->exp_value; -+ } -+ else { -+ /* capture 15 fps */ -+ pov->pclock = 0x83; -+ pov->adjusted_exp_value = pov->exp_value; -+ } -+ if (pov->night_mode == 1) { -+ //night mode -+ //pov->pclock = 0x89; -+ } -+ else if (pov->night_mode == 2) { //action mode -+ pov->pclock = 0x81; -+ } -+ } -+ } -+} -+ -+static void ov9650_upload_gains(void) -+{ -+ ov9650 *pov; -+ u32 expValue, gain, gaina; -+ u8 gainh, gainl, aechm, aech, aecl, laec, blue, red; -+ u8 regValue; -+ -+ pov = &g_ov9650; -+ -+ gain = pov->gain; -+ gaina = pov->gaina; -+ blue = pov->blue_gain; -+ red = pov->red_gain; -+ expValue = pov->adjusted_exp_value; -+ laec = pov->exp_time; -+ // Set awb -+ prv_write_sensor_reg(OV9650_BLUE, &blue); -+ prv_write_sensor_reg(OV9650_RED, &red); -+ -+ // Set gain -+ gaina = (gaina*5)/7; -+ gain = 0; -+ if(gaina>62) -+ { -+ gain |= 0x20; -+ gaina /= 2; -+ } -+ if(gaina>31) -+ { -+ gain |= 0x10; -+ gaina /= 2; -+ } -+ if( gaina>16 ) -+ gaina -= 16; -+ else -+ gaina = 0; -+ gain = gain | gaina; -+ -+ gainl = gain & 0xff; -+ gainh = (gain&0x0300)>>2; -+ prv_write_sensor_reg(OV9650_GAIN, &gainl); -+ prv_read_sensor_reg(OV9650_VREF, ®Value); -+ regValue = (regValue & 0x3f) | gainh; -+ prv_write_sensor_reg(OV9650_VREF, ®Value); -+ // Set exposure -+ aechm = (expValue>>10)&0x3f; -+ aech = (expValue>>2)&0xff; -+ aecl = expValue&0x03; -+ prv_read_sensor_reg(OV9650_AECHM, ®Value); -+ regValue = (regValue & 0xc0) | aechm; -+ prv_write_sensor_reg(OV9650_AECHM, ®Value); -+ prv_write_sensor_reg(OV9650_AECH, &aech); -+ prv_read_sensor_reg(OV9650_COM1, ®Value); -+ regValue = (regValue & 0xfc) | aecl; -+ prv_write_sensor_reg(OV9650_COM1, ®Value); -+ -+ //prv_write_sensor_reg(OV9650_CLKRC, &pov->pclock); -+ DPRINTK("gain=%x gaina=%x blue=%x red=%x, expv=%x, pclock=%x\n", -+ gain, gaina, blue, red, expValue, pov->pclock); -+} -+ -+static int -+ov9650_set_dma_pages(pxa_dma_desc ** pdes, -+ pxa_dma_desc ** des_physical, int num, struct page *array[], int total_size, int dsadr, int flags) -+{ -+ int remain_size, des_transfer_size; -+ int j, target_page_num = num; -+ pxa_dma_desc *cur_des_virtual = *pdes; -+ pxa_dma_desc *cur_des_physical = *des_physical; -+ -+ // in each iteration, generate one dma chain for one frame -+ remain_size = total_size; -+ -+ for (j = 0; j < num; j++) { -+ // set descriptor -+ if (remain_size > PAGE_SIZE) -+ des_transfer_size = PAGE_SIZE; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned) cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = dsadr; // FIFO0 physical address -+ cur_des_virtual->dtadr = page_to_bus(array[j]); -+ cur_des_virtual->dcmd = des_transfer_size | flags; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ *pdes = cur_des_virtual; -+ *des_physical = cur_des_physical; -+ return 0; -+} -+ -+static int -+ov9650_set_dma_page1(pxa_dma_desc ** pdes, -+ pxa_dma_desc ** des_physical, int num, struct page *page1, int total_size, int dsadr, int flags) -+{ -+ int remain_size, des_transfer_size; -+ int j, target_page_num = num; -+ pxa_dma_desc *cur_des_virtual = *pdes; -+ pxa_dma_desc *cur_des_physical = *des_physical; -+ int dump_page; -+ -+ // in each iteration, generate one dma chain for one frame -+ remain_size = total_size; -+ dump_page = page_to_bus(page1); -+ DPRINTK("dump_page=%x", dump_page); -+ -+ for (j = 0; j < num; j++) { -+ // set descriptor -+ if (remain_size > PAGE_SIZE) -+ des_transfer_size = PAGE_SIZE; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned) cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = dsadr; // FIFO0 physical address -+ cur_des_virtual->dtadr = dump_page; -+ cur_des_virtual->dcmd = des_transfer_size | flags; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ *pdes = cur_des_virtual; -+ *des_physical = cur_des_physical; -+ return 0; -+} -+ -+static int ov9650_update_still_dma_chain(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL; -+ int remain_size; -+ unsigned int i; -+ -+ int target_page_num; -+ -+ DPRINTK("ov9650_update_still_dma_chain\n"); -+ // clear descriptor pointers -+ cam_ctx->fifo0_descriptors_virtual = cam_ctx->fifo0_descriptors_physical = 0; -+ cam_ctx->fifo1_descriptors_virtual = cam_ctx->fifo1_descriptors_physical = 0; -+ cam_ctx->fifo2_descriptors_virtual = cam_ctx->fifo2_descriptors_physical = 0; -+ -+ // calculate how many descriptors are needed per frame -+ cam_ctx->fifo0_num_descriptors = cam_ctx->pages_per_fifo0; -+ -+ cam_ctx->fifo1_num_descriptors = cam_ctx->pages_per_fifo1; -+ -+ cam_ctx->fifo2_num_descriptors = cam_ctx->pages_per_fifo2; -+ -+ // check if enough memory to generate descriptors -+ DPRINTK("in %s, cam_ctx->block_number =%d\n", __FUNCTION__, cam_ctx->block_number); -+ if ((cam_ctx->fifo0_num_descriptors + cam_ctx->fifo1_num_descriptors + -+ cam_ctx->fifo2_num_descriptors) * cam_ctx->block_number > cam_ctx->dma_descriptors_size) -+ return -1; -+ -+ // generate fifo0 dma chains -+ cam_ctx->fifo0_descriptors_virtual = (unsigned) cam_ctx->dma_descriptors_virtual; -+ cam_ctx->fifo0_descriptors_physical = (unsigned) cam_ctx->dma_descriptors_physical; -+ cur_des_virtual = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual; -+ cur_des_physical = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_physical; -+ -+ DPRINTK("pages_allocated=%d,fifo0_descriptors_virtual=%p\n", cam_ctx->pages_allocated, cur_des_virtual); -+ -+ for (i = 0; i < 2; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo0_transfer_size; -+ ov9650_set_dma_page1(&cur_des_virtual, &cur_des_physical, -+ cam_ctx->fifo0_num_descriptors, -+ cam_ctx->page_array[cam_ctx-> -+ pages_allocated - -+ 1], remain_size, CIBR0_PHY, DCMD_FLOWSRC | DCMD_BURST32); -+ -+ } -+ DPRINTK("after ov9650_set_dma_page1=%d\n", cam_ctx->pages_allocated); -+ for (i = 0; i < 1; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo0_transfer_size; -+ -+ // assume the blocks are stored consecutively -+ target_page_num = cam_ctx->pages_per_block * i; -+ DPRINTK("target_page_num=%d\n", target_page_num); -+ ov9650_set_dma_pages(&cur_des_virtual, &cur_des_physical, -+ cam_ctx->fifo0_num_descriptors, -+ &cam_ctx->page_array[target_page_num], -+ remain_size, CIBR0_PHY, DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo0_descriptors_physical); -+ last_des_virtual->ddadr |= 0x1; -+ last_des_virtual->dcmd |= DCMD_ENDIRQEN; -+ -+ // generate fifo1 dma chains -+ if (cam_ctx->fifo1_transfer_size) { -+ // record fifo1 descriptors' start address -+ cam_ctx->fifo1_descriptors_virtual = (unsigned) cur_des_virtual; -+ cam_ctx->fifo1_descriptors_physical = (unsigned) cur_des_physical; -+ -+ for (i = 0; i < 2; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo1_transfer_size; -+ ov9650_set_dma_page1(&cur_des_virtual, -+ &cur_des_physical, -+ cam_ctx-> -+ fifo1_num_descriptors, -+ cam_ctx->page_array[cam_ctx-> -+ pages_allocated -+ - 2], -+ remain_size, CIBR1_PHY, DCMD_FLOWSRC | DCMD_BURST32); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ for (i = 0; i < 1; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo1_transfer_size; -+ -+ target_page_num = cam_ctx->pages_per_block * i + cam_ctx->pages_per_fifo0; -+ ov9650_set_dma_pages(&cur_des_virtual, &cur_des_physical, -+ cam_ctx->fifo1_num_descriptors, -+ &cam_ctx->page_array[target_page_num], -+ remain_size, CIBR1_PHY, DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo1_descriptors_physical); -+ last_des_virtual->ddadr |= 0x1; -+ } -+ // generate fifo2 dma chains -+ if (cam_ctx->fifo2_transfer_size) { -+ // record fifo1 descriptors' start address -+ cam_ctx->fifo2_descriptors_virtual = (unsigned) cur_des_virtual; -+ cam_ctx->fifo2_descriptors_physical = (unsigned) cur_des_physical; -+ -+ for (i = 0; i < 2; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo2_transfer_size; -+ ov9650_set_dma_page1(&cur_des_virtual, -+ &cur_des_physical, -+ cam_ctx-> -+ fifo2_num_descriptors, -+ cam_ctx->page_array[cam_ctx-> -+ pages_allocated -+ - 3], -+ remain_size, CIBR2_PHY, DCMD_FLOWSRC | DCMD_BURST32); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ DPRINTK("last target_page_num=%d\n", target_page_num + cam_ctx->fifo2_num_descriptors); -+ for (i = 0; i < 1; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo2_transfer_size; -+ target_page_num = -+ cam_ctx->pages_per_block * i + cam_ctx->pages_per_fifo0 + cam_ctx->pages_per_fifo1; -+ ov9650_set_dma_pages(&cur_des_virtual, &cur_des_physical, -+ cam_ctx->fifo2_num_descriptors, -+ &cam_ctx->page_array[target_page_num], -+ remain_size, CIBR2_PHY, DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR); -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ DPRINTK("last target_page_num=%d\n", target_page_num + cam_ctx->fifo2_num_descriptors); -+ } -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo2_descriptors_physical); -+ last_des_virtual->ddadr |= 0x1; -+ } -+ return 0; -+} -+ -+static int ov9650_stop_third_des(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *pdesc, *ptmp; -+ int i; -+ -+ // stop the dma transfer on one frame captured -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo0_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo0_num_descriptors * 2; -+ for (i = 0; i < cam_ctx->fifo0_num_descriptors; i++) -+ (ptmp + i)->dtadr = (pdesc + i)->dtadr; -+ -+ pdesc += cam_ctx->fifo0_num_descriptors - 1; -+ pdesc->dcmd = (pdesc->dcmd & DCMD_LENGTH) | DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR; -+ pdesc += cam_ctx->fifo0_num_descriptors; -+ pdesc->dcmd = (pdesc->dcmd & DCMD_LENGTH) | DCMD_FLOWSRC | DCMD_BURST32 | DCMD_INCTRGADDR; -+ pdesc += cam_ctx->fifo0_num_descriptors; -+ pdesc->ddadr |= 0x1; -+ -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo1_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo1_num_descriptors * 2; -+ for (i = 0; i < cam_ctx->fifo1_num_descriptors; i++) -+ (ptmp + i)->dtadr = (pdesc + i)->dtadr; -+ pdesc += cam_ctx->fifo1_num_descriptors * 3 - 1; -+ pdesc->ddadr |= 0x1; -+ -+ pdesc = (pxa_dma_desc *) (cam_ctx->fifo2_descriptors_virtual); -+ ptmp = pdesc + cam_ctx->fifo2_num_descriptors * 2; -+ for (i = 0; i < cam_ctx->fifo2_num_descriptors; i++) -+ (ptmp + i)->dtadr = (pdesc + i)->dtadr; -+ pdesc += cam_ctx->fifo2_num_descriptors * 3 - 1; -+ pdesc->ddadr |= 0x1; -+ return 0; -+} -+ -+int ov9650_prepare_capture(p_camera_context_t cam_ctx, u32 captureSizeFormat, u32 colorFormat) -+{ -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ -+ stop_dma_transfer(cam_ctx); -+ ov9650_switch_format(captureSizeFormat, colorFormat); -+ ov9650_adjust_gains(pov->pre_size, captureSizeFormat); -+ ov9650_upload_gains(); -+ if (captureSizeFormat == OV_SIZE_VGA) { -+ //ov9650_update_still_dma_chain(cam_ctx); -+ ov9650_stop_third_des(cam_ctx); -+ /* -+ */ -+ } -+ else if (captureSizeFormat == OV_SIZE_SXGA) { -+ camera_set_int_mask(cam_ctx, 0x3fd | 0x0400); -+ ov9650_update_still_dma_chain(cam_ctx); -+ //ci_clear_int_status(0xFFFFFFFF); -+ //DPRINTK("before camera_sleep \n"); -+ //camera_sleep(); -+ } -+ ci_reset_fifo(); -+ ci_clear_int_status(0xFFFFFFFF); -+ start_dma_transfer(cam_ctx, 1); -+ DPRINTK("after ov9650_prepare_capture \n"); -+ return 0; -+} -+ -+int ov9650_set_special_effect(int style) -+{ -+#if 0 -+ int ret = 0; -+ u32 index, curReg; -+ u8 *regsP; -+ u8 regValue; -+ -+ DPRINTK("in function %s parameter=%d\n", __FUNCTION__, style); -+ curReg = 0x3a; -+ ov9650_read(0x3a, ®Value); -+ regValue = regValue & 0xf; -+ switch (style) { -+ case V4l_STYLE_NORMAL: -+ DPRINTK("V4l_STYLE_NORMAL\n"); -+ regValue &= 0x7f; -+ //ov9650_write(0x3a, 0x08); -+ ov9650_write(0x3a, regValue); -+ ov9650_write(0x67, 0x80); -+ ov9650_write(0x68, 0x80); -+ break; -+ case V4l_STYLE_BLACK_WHITE: -+ DPRINTK("V4l_STYLE_BLACK_WHITE\n"); -+ regValue |= 0x10; -+ //ov9650_write(0x3a, 0x18); -+ ov9650_write(0x3a, regValue); -+ ov9650_write(0x67, 0x80); -+ ov9650_write(0x68, 0x80); -+ break; -+ case V4l_STYLE_SEPIA: -+ DPRINTK("V4l_STYLE_SEPIA\n"); -+ regValue |= 0x10; -+ //ov9650_write(0x3a, 0x18); -+ ov9650_write(0x3a, regValue); -+ ov9650_write(0x67, 0xa0); -+ ov9650_write(0x68, 0x40); -+ break; -+ //case V4l_STYLE_BULISH: -+ DPRINTK("V4l_STYLE_BULISH\n"); -+ ov9650_write(0x3a, 0x18); -+ ov9650_write(0x67, 0x80); -+ ov9650_write(0x68, 0xc0); -+ break; -+ default: -+ DPRINTK("case default ????????????????????\n"); -+ //ret=OV_ERR_PARAMETER; -+ } -+ return ret; -+#else -+ return 0; -+#endif -+} -+ -+int ov9650_set_brightness(int bright) -+{ -+#if 0 -+ int ret = 0; -+ const u8 BN[] = { -+ //BN-3 -+ 0x0f, 0x4f, -+ 0x27, 0xe8, -+ 0x28, 0xe0, -+ 0x29, 0xe0, -+ 0x2c, 0xe0, -+ //BN-2 -+ 0x0f, 0x4f, -+ 0x27, 0xc8, -+ 0x28, 0xc0, -+ 0x29, 0xc0, -+ 0x2c, 0xc0, -+ //BN-1 -+ 0x0f, 0x4f, -+ 0x27, 0xa8, -+ 0x28, 0xa0, -+ 0x29, 0xa0, -+ 0x2c, 0xa0, -+ //BN-0 -+ 0x0f, 0x4f, -+ 0x27, 0x88, -+ 0x28, 0x80, -+ 0x29, 0x80, -+ 0x2c, 0x80, -+ //BN+1 -+ 0x0f, 0x4f, -+ 0x27, 0x28, -+ 0x28, 0x20, -+ 0x29, 0x20, -+ 0x2c, 0x20, -+ //BN+2 -+ 0x0f, 0x4f, -+ 0x27, 0x48, -+ 0x28, 0x40, -+ 0x29, 0x40, -+ 0x2c, 0x40, -+ //BN+3 -+ 0x0f, 0x4f, -+ 0x27, 0x68, -+ 0x28, 0x60, -+ 0x29, 0x60, -+ 0x2c, 0x60, -+ }; -+ u8 *regs; -+ int n = 5; -+ int i; -+ -+ DPRINTK("in function %s bright =%d \n", __FUNCTION__, bright); -+ if (bright < -3) -+ bright = -3; -+ if (bright > 3) -+ bright = 3; -+ //bright = -4 .. 4 -+ regs = &BN[(bright + 3) * n * 2]; -+ //for (i = 0; i < n * 2; i += 2) -+ // ret |= ov9650_write(regs[i], regs[i + 1]); -+#endif -+ return OV_ERR_NONE; -+} -+ -+#if 0 -+static int ov9650_set_color_saturation(int saturation) -+{ -+ const u8 CS[] = { -+ //Saturation: 0.25 -+ 0x4f, 0x14, -+ 0x50, 0x10, -+ 0x51, 0x3, -+ 0x52, 0x6, -+ 0x53, 0x13, -+ 0x54, 0x19, -+ //Saturation 0.5 -+ 0x4f, 0x28, -+ 0x50, 0x22, -+ 0x51, 0x6, -+ 0x52, 0xc, -+ 0x53, 0x26, -+ 0x54, 0x33, -+ //Saturation 0.75 (Default) -+ 0x4f, 0x3c, -+ 0x50, 0x32, -+ 0x51, 0x9, -+ 0x52, 0x13, -+ 0x53, 0x39, -+ 0x54, 0x4c, -+ //Saturation 1.0 -+ 0x4f, 0x50, -+ 0x50, 0x43, -+ 0x51, 0xd, -+ 0x52, 0x19, -+ 0x53, 0x4d, -+ 0x54, 0x66, -+ //Saturation 1.25 -+ 0x4f, 0x64, -+ 0x50, 0x53, -+ 0x51, 0x10, -+ 0x52, 0x1f, -+ 0x53, 0x5f, -+ 0x54, 0x7f, -+ }; -+ u8 *regs; -+ int n = 6; -+ int i; -+ -+ DPRINTK("in function %s ,parameter=%d\n", __FUNCTION__, saturation); -+ if (saturation < 0) -+ saturation = 0; -+ if (saturation > 4) -+ saturation = 4; -+ -+ regs = &CS[saturation * n * 2]; -+ for (i = 0; i < n * 2; i += 2) -+ ov9650_write(regs[i], regs[i + 1]); -+ return OV_ERR_NONE; -+ -+} -+#endif -+ -+int ov9650_set_white_balance(V4l_PIC_WB light) -+{ -+#if 0 -+ int ret = 0; -+ u8 *regs; -+ int n = 13; -+ int i = 0; -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ -+ DPRINTK("in function %s ,parameter=%d\n", __FUNCTION__, light); -+ switch (light) { -+ case V4l_WB_DIRECT_SUN: -+ //ov9650_set_color_saturation(3); -+ DPRINTK("V4l_WB_DIRECT_SUN\n"); -+ i = 0 * n * 2; -+ //ov9650_set_night_mode(); -+ break; -+ case V4l_WB_INCANDESCENT: -+ //ov9650_set_color_saturation(2); -+ DPRINTK("V4l_WB_INCANDESCENT\n"); -+ i = 1 * n * 2; -+ //ov9650_set_action_mode(); -+ break; -+ case V4l_WB_FLUORESCENT: -+ //ov9650_set_color_saturation(2); -+ DPRINTK("V4l_WB_FLUORESCENT\n"); -+ i = 2 * n * 2; -+ break; -+ default: -+ /* auto */ -+ //ov9650_set_color_saturation(2); -+ DPRINTK("case default ????????????????????\n"); -+ i = 3 * n * 2; -+ n = 19; -+ //ov9650_set_auto_mode(); -+ break; -+ } -+ //TODO: -+#endif -+ -+ return OV_ERR_NONE; -+} -+ -+int ov9650_set_night_mode() -+{ -+#if 0 -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ pov->night_mode = 1; -+ //ov9650_write(0x11, 0x89); -+ ov9650_write(0x3b, 0xe1); -+#endif -+ return 0; -+} -+ -+int ov9650_set_action_mode() -+{ -+#if 0 -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ pov->night_mode = 2; -+ ov9650_write(0x11, 0x81); -+ ov9650_write(0x3b, 0x01); -+ ov9650_write(0x2d, 0x0); -+ ov9650_write(0x2e, 0x0); -+#endif -+ return 0; -+} -+ -+int ov9650_set_auto_mode() -+{ -+#if 0 -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ pov->night_mode = 0; -+ ov9650_write(0x11, 0x83); -+ ov9650_write(0x3b, 0x01); -+ ov9650_write(0x2d, 0x0); -+ ov9650_write(0x2e, 0x0); -+#endif -+ return 0; -+} -+ -+int ov9650_set_flicker(int freq) -+{ -+#if 0 -+ int ret = 0; -+ const u8 LE_v3[] = { -+ //OutDoor -+ 0x3b, 0x00, -+ 0x2a, 0, -+ 0x2b, 0, -+ 0x6a, 0x3d, -+ //Indoor 60Hz(Default) -+ 0x3b, 0x01, -+ 0x2a, 0, -+ 0x2b, 0, -+ 0x6a, 0x3d, -+ //Indoor 50Hz -+ 0x3b, 0x01, -+ 0x2a, 0x10, -+ 0x2b, 0x40, -+ 0x6a, 0x3d, -+ }; -+ const u8 LE_v2[] = { -+ //OutDoor -+ 0x13, 0x8d, -+ 0x2a, 0, -+ 0x2b, 0, -+ 0x6a, 0x3d, -+ //Indoor 60Hz(Default) -+ 0x13, 0x8d, -+ 0x2a, 0, -+ 0x2b, 0, -+ 0x6a, 0x3d, -+ //Indoor 50Hz -+ 0x13, 0x8d, -+ 0x2a, 0x10, -+ 0x2b, 0x14, -+ 0x6a, 0x3d, -+ }; -+ u8 *regs; -+ int n = 4; -+ int i = 0; -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ DPRINTK("in function %s ,parameter=%d\n", __FUNCTION__, freq); -+ switch (freq) { -+ case 0: -+ i = 0 * n * 2; -+ break; -+ case 60: -+ i = 1 * n * 2; -+ break; -+ case 50: -+ i = 2 * n * 2; -+ break; -+ default: -+ i = 0; -+ break; -+ } -+ -+ //regs = &LE_v2[i]; -+ regs = &LE_v3[i]; -+ -+ -+ for (i = 0; i < n * 2; i += 2) -+ ret |= ov9650_write(regs[i], regs[i + 1]); -+#endif -+ return OV_ERR_NONE; -+} -+ -+int ov9650_set_contrast(int contrast) -+{ -+#if 0 -+ const u8 CO[] = { -+ //Low contrast -+ 0x6C, 0x20, -+ 0x6D, 0x50, -+ 0x6E, 0xc0, -+ 0x6F, 0xa8, -+ 0x70, 0x88, -+ 0x71, 0x80, -+ 0x72, 0x78, -+ 0x73, 0x70, -+ 0x74, 0x68, -+ 0x75, 0x58, -+ 0x76, 0x40, -+ 0x77, 0x30, -+ 0x78, 0x28, -+ 0x79, 0x20, -+ 0x7A, 0x1e, -+ 0x7B, 0x18, -+ 0x7C, 0x04, -+ 0x7D, 0x07, -+ 0x7E, 0x1f, -+ 0x7F, 0x49, -+ 0x80, 0x5a, -+ 0x81, 0x6a, -+ 0x82, 0x79, -+ 0x83, 0x87, -+ 0x84, 0x94, -+ 0x85, 0x9f, -+ 0x86, 0xaf, -+ 0x87, 0xbb, -+ 0x88, 0xcf, -+ 0x89, 0xdf, -+ 0x8A, 0xee, -+ //Middle contrast (default) -+ 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, -+ //High contrast -+ 0x6c, 0x50, -+ 0x6d, 0x60, -+ 0x6e, 0x58, -+ 0x6f, 0x58, -+ 0x70, 0x58, -+ 0x71, 0x50, -+ 0x72, 0x50, -+ 0x73, 0x50, -+ 0x74, 0x50, -+ 0x75, 0x50, -+ 0x76, 0x4c, -+ 0x77, 0x4c, -+ 0x78, 0x45, -+ 0x79, 0x3c, -+ 0x7a, 0x2c, -+ 0x7b, 0x24, -+ 0x7c, 0x05, -+ 0x7d, 0x0b, -+ 0x7e, 0x16, -+ 0x7f, 0x2c, -+ 0x80, 0x37, -+ 0x81, 0x41, -+ 0x82, 0x4b, -+ 0x83, 0x55, -+ 0x84, 0x5f, -+ 0x85, 0x69, -+ 0x86, 0x7c, -+ 0x87, 0x8f, -+ 0x88, 0xb1, -+ 0x89, 0xcf, -+ 0x8a, 0xe5, -+ }; -+ -+ u8 *regs; -+ int n = 31; -+ int i; -+ -+ DPRINTK("in function %s parameter=%d \n", __FUNCTION__, contrast); -+ if (contrast < 0) -+ contrast = 0; -+ if (contrast > 2) -+ contrast = 2; -+ -+ regs = &CO[contrast * n * 2]; -+ for (i = 0; i < n * 2; i += 2) -+ ov9650_write(regs[i], regs[i + 1]); -+#endif -+ return OV_ERR_NONE; -+ -+} -+ -+static int ov9650_find_window(struct video_window *vw, int *sub_win) -+{ -+ int ret = OV_SIZE_NONE; -+ -+ *sub_win = 1; -+ if (vw->width > 1280 || vw->height > 1024 || vw->width < 88|| vw->height < 72) { -+ ret = OV_SIZE_NONE; -+ } -+ else if (vw->width == 1280 && ((vw->height == 960)||(vw->height == 1024))) { -+ *sub_win = 0; -+ ret = OV_SIZE_SXGA; -+ } -+ else if (vw->width >= 640 && vw->height >= 480) { -+ if (vw->width == 640 && vw->height == 480) -+ *sub_win = 0; -+ ret = OV_SIZE_VGA; -+ } -+ else if (vw->width >= 352 && vw->height >= 288) { -+ if (vw->width == 352 && vw->height == 288) -+ *sub_win = 0; -+ ret = OV_SIZE_CIF; -+ } -+ else if (vw->width >= 320 && vw->height >= 240) { -+ if (vw->width == 320 && vw->height == 240) -+ *sub_win = 0; -+ ret = OV_SIZE_QVGA; -+ } -+ else if (vw->width >= 176 && vw->height >= 144) { -+ if (vw->width == 176 && vw->height == 144) -+ *sub_win = 0; -+ ret = OV_SIZE_QCIF; -+ } -+ else if (vw->width >= 160 && vw->height >= 120) { -+ if (vw->width == 160 && vw->height == 120) -+ *sub_win = 0; -+ ret = OV_SIZE_QQVGA; -+ } -+ else if (vw->width >= 88 && vw->height >= 72) { -+ if (vw->width == 88 && vw->height == 72) -+ *sub_win = 0; -+ ret = OV_SIZE_QQCIF; -+ } -+ DPRINTK("in %s,ret = %d, subwin=%d\n", __FUNCTION__, ret, *sub_win); -+ return ret; -+} -+ -+int ov9650_set_window(struct video_window *vw) -+{ -+ int ret = 0; -+ int x_end; -+ int y_end; -+ struct video_window window; -+ int sub_win; -+ ov9650 *pov; -+ -+ pov = &g_ov9650; -+ vw->width = (vw->width + 7) & (~0x7); -+ vw->height = (vw->height + 7) & (~0x7); -+ vw->x = vw->y = 0; -+ x_end = window.width = (vw->width + vw->x); -+ y_end = window.height = (vw->height + vw->y); -+ DPRINTK("in %s, vw-x =%d, vw-y=%d,vw->width=%d,vw->height=%d\n", -+ __FUNCTION__, vw->x, vw->y, vw->width, vw->height); -+ ret = ov9650_find_window(&window, &sub_win); -+ if (ret <= OV_SIZE_NONE) -+ return -1; -+ -+ ret = ov9650_set_format(ret, OV_FORMAT_YUV_422); -+ if (ret < 0) -+ return -1; -+ -+ pov->win = *vw; -+ return ret; -+} -+ -+int ov9650_get_window(struct video_window *vw) -+{ -+ ov9650 *pov; -+ pov = &g_ov9650; -+ *vw = pov->win; -+ return 0; -+} -+ -+struct win_size { -+ int width; -+ int height; -+}; -+int ov9650_set_sensor_size(void *w_size) -+{ -+ struct win_size size; -+ ov9650 *pov; -+ pov = &g_ov9650; -+ if (copy_from_user(&size, w_size, sizeof(struct win_size))) { -+ return -EFAULT; -+ } -+//make it in an even of multiple of 8 -+ size.height = (size.height + 7) / 8 * 8; -+ pov->sensor_width = size.width; -+ pov->sensor_height = size.height; -+ return 0; -+} -+ -+int ov9650_get_sensor_size(void *w_size) -+{ -+ return 0; -+} -+ -+int ov9650_set_output_size(void *w_size) -+{ -+ struct win_size size; -+ ov9650 *pov; -+ pov = &g_ov9650; -+ if (copy_from_user(&size, w_size, sizeof(struct win_size))) { -+ return -EFAULT; -+ } -+//make it in an even of multiple of 8 -+ size.height = (size.height + 7) / 8 * 8; -+ pov->sensor_width = size.width; -+ pov->sensor_height = size.height; -+ return 0; -+} -+ -+int ov9650_get_output_size(void *w_size) -+{ -+ return 0; -+} -+ -+#if 0 -+static int test_divider(int res, int fps) -+{ -+ int max_hz = 48 * 1000000; -+ int div = 1; -+ int i; -+ int ov_fps[5] = { 3, 7, 15, 30, 60 }; -+ u32 value = 320 * 240; -+ /* -+ switch (prevSize) { -+ case OV_SIZE_QQCIF: -+ value = 88 * 72; -+ break; -+ case OV_SIZE_QQVGA: -+ value = 176 * 144; -+ break; -+ case OV_SIZE_QCIF: -+ value = 160 * 120; -+ break; -+ case OV_SIZE_QVGA: -+ value = 320 * 240; -+ break; -+ case OV_SIZE_CIF: -+ value = 352 * 288; -+ break; -+ case OV_SIZE_VGA: -+ value = 640 * 480; -+ break; -+ case OV_SIZE_SXGA: -+ value = 1280 * 960; -+ break; -+ } -+ -+ while (max_hz / res / div > fps) -+ div++; -+ if (div > 64) -+ div = 64; -+ return (div - 1); -+ -+ for (i =0;i<5;i++) -+ if ( fps < ov_fps[i] ) -+ continue; -+ */ -+ if (fps == 0) -+ return 0; -+ if (fps > 60) -+ fps = 60; -+ return (div = 60 / fps - 1); -+} -+#endif -+ -+int ov9650_set_fps(int fps, int min_fps) -+{ -+#if 0 -+ u32 res = 0; -+ u8 value; -+ if (fps < 0) { -+ DPRINTK("in %s fps = %d divider value =%d\n", __FUNCTION__, fps, res); -+ fps = 15; -+ } -+ res = test_divider(0, fps); -+ ov9650_read(OV9650_CLKRC, &value); -+ value = (value & 0xc0) | res; -+ ov9650_write(OV9650_CLKRC, value); -+ DPRINTK("in %s fps = %d divider value =%d\n", __FUNCTION__, fps, res); -+ /* -+ ov9650_set_night_mode(); -+ ov9650_set_action_mode(); -+ ov9650_set_auto_mode(); -+ */ -+#endif -+ return 0; -+} -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/ov9650_hw.h linux-2.6.16.5-exz/drivers/media/video/ov9650_hw.h ---- linux-2.6.16.5/drivers/media/video/ov9650_hw.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/ov9650_hw.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,284 @@ -+/* -+ ov9650_hw - Omnivision 9650 CMOS sensor driver -+ -+ Copyright (C) 2003, Intel Corporation -+ -+ 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 program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ 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 _OV_9650_HW_H_ -+#define _OV_9650_HW_H_ -+ -+/*********************************************************************** -+ * -+ * Constants & Structures -+ * -+ ***********************************************************************/ -+// Revision constants -+#define PID_OV 0x96 -+#define PID_9650_0 0x51 -+#define PID_9650 0x52 -+ -+// Return codes -+#define OV_ERR_NONE 0x00 -+#define OV_ERR_TIMEOUT -1 -+#define OV_ERR_PARAMETER -2 -+#define OV_COMM_ERR -3 -+ -+#define CIBR0_PHY (0x50000000 + 0x28) -+#define CIBR1_PHY (0x50000000 + 0x30) -+#define CIBR2_PHY (0x50000000 + 0x38) -+#define DPRINTK(fmt,args...) do { if (DEBUG) printk("in function %s "fmt,__FUNCTION__,##args);} while(0) -+ -+// Output Size & Format -+/* -+#define OV_SIZE_NONE 0 -+#define OV_SIZE_QQVGA 0x01 -+#define OV_SIZE_QVGA ( OV_SIZE_QQVGA << 1 ) -+#define OV_SIZE_VGA ( OV_SIZE_QQVGA << 2 ) -+#define OV_SIZE_SXGA ( OV_SIZE_QQVGA << 3 ) -+#define OV_SIZE_QQCIF 0x10 -+#define OV_SIZE_QCIF ( OV_SIZE_QQCIF << 1 ) -+#define OV_SIZE_CIF ( OV_SIZE_QQCIF << 2 ) -+#define OV_FORMAT_NONE 0 -+#define OV_FORMAT_YUV_422 1 -+#define OV_FORMAT_RGB_565 2 -+*/ -+enum OV_SIZE { -+ OV_SIZE_NONE=0 , -+ OV_SIZE_QQVGA , -+ OV_SIZE_QVGA , -+ OV_SIZE_VGA , -+ OV_SIZE_SXGA , -+ OV_SIZE_QQCIF , -+ OV_SIZE_QCIF , -+ OV_SIZE_CIF -+}; -+enum OV_FORMAT { -+ OV_FORMAT_NONE=0 , -+ OV_FORMAT_YUV_422, -+ OV_FORMAT_RGB_565, -+}; -+ -+// Camera Mode -+#define VIEWFINDER_MODE 0x10 -+#define STILLFRAME_MODE 0x20 -+ -+// Others -+#define OV9650_TIMEOUT 1000 // ms to timeout. -+ -+// OV9650 Register Definitions -+#define OV9650_GAIN 0x0000 -+#define OV9650_BLUE 0x0001 -+#define OV9650_RED 0x0002 -+#define OV9650_VREF 0x0003 -+#define OV9650_COM1 0x0004 -+#define OV9650_BAVE 0x0005 // U/B Average Level -+#define OV9650_GEAVE 0x0006 // Y/Ge Average Level -+#define OV9650_GOAVE 0x0007 // Y/Go Average Level -+#define OV9650_RAVE 0x0008 // V/R Average level -+#define OV9650_COM2 0x0009 // Common control 2 -+#define OV9650_PID 0x000A // Product ID -+#define OV9650_VER 0x000B // Version -+#define OV9650_COM3 0x000C -+#define OV9650_COM4 0x000D -+#define OV9650_COM5 0x000E -+#define OV9650_COM6 0x000F -+#define OV9650_AECH 0x0010 -+#define OV9650_CLKRC 0x0011 -+#define OV9650_COM7 0x0012 -+#define OV9650_COM8 0x0013 -+#define OV9650_COM9 0x0014 -+#define OV9650_COM10 0x0015 -+#define OV9650_WS 0x0016 -+#define OV9650_HSTART 0x0017 -+#define OV9650_HSTOP 0x0018 -+#define OV9650_VSTRT 0x0019 -+#define OV9650_VSTOP 0x001A -+#define OV9650_PSHFT 0x001B -+#define OV9650_MIDH 0x001C -+#define OV9650_MIDL 0x001D -+#define OV9650_MVLP 0x001E -+#define OV9650_LAEC 0x001F -+#define OV9650_BOS 0x0020 -+#define OV9650_GBOS 0x0021 -+#define OV9650_GROS 0x0022 -+#define OV9650_ROS 0x0023 -+#define OV9650_AEW 0x0024 -+#define OV9650_AEB 0x0025 -+#define OV9650_VPT 0x0026 -+#define OV9650_BBIAS 0x0027 -+#define OV9650_GbBIAS 0x0028 -+//#define OV9650_GrBIAS 0x0029 -+#define OV9650_GrCOM 0x0029 -+#define OV9650_EXHCH 0x002A -+#define OV9650_EXHCL 0x002B -+#define OV9650_RBIAS 0x002C -+#define OV9650_ADVFL 0x002D -+#define OV9650_ADVFH 0x002E -+#define OV9650_YAVE 0x002F -+#define OV9650_HSYST 0x0030 -+#define OV9650_HSYEN 0x0031 -+#define OV9650_HREF 0x0032 -+#define OV9650_CHLF 0x0033 -+#define OV9650_ARBLM 0x0034 -+#define OV9650_VRHL 0x0035 -+#define OV9650_VIDO 0x0036 -+#define OV9650_ADC 0x0037 -+#define OV9650_ACOM 0x0038 -+#define OV9650_OFON 0x0039 -+#define OV9650_TSLB 0x003A -+#define OV9650_COM11 0x003B -+#define OV9650_COM12 0x003C -+#define OV9650_COM13 0x003D -+#define OV9650_COM14 0x003E -+#define OV9650_EDGE 0x003F -+#define OV9650_COM15 0x0040 -+#define OV9650_COM16 0x0041 -+#define OV9650_COM17 0x0042 -+#define OV9650_AWBTH1 0x0043 -+#define OV9650_AWBTH2 0x0044 -+#define OV9650_AWBTH3 0x0045 -+#define OV9650_AWBTH4 0x0046 -+#define OV9650_AWBTH5 0x0047 -+#define OV9650_AWBTH6 0x0048 -+#define OV9650_MTX1 0x004F -+#define OV9650_MTX2 0x0050 -+#define OV9650_MTX3 0x0051 -+#define OV9650_MTX4 0x0052 -+#define OV9650_MTX5 0x0053 -+#define OV9650_MTX6 0x0054 -+#define OV9650_MTX7 0x0055 -+#define OV9650_MTX8 0x0056 -+#define OV9650_MTX9 0x0057 -+#define OV9650_MTXS 0x0058 -+#define OV9650_AWBC1 0x0059 -+#define OV9650_AWBC2 0x005A -+#define OV9650_AWBC3 0x005B -+#define OV9650_AWBC4 0x005C -+#define OV9650_AWBC5 0x005D -+#define OV9650_AWBC6 0x005E -+#define OV9650_AWBC7 0x005F -+#define OV9650_AWBC8 0x0060 -+#define OV9650_AWBC9 0x0061 -+#define OV9650_LCC1 0x0062 -+#define OV9650_LCC2 0x0063 -+#define OV9650_LCC3 0x0064 -+#define OV9650_LCC4 0x0065 -+#define OV9650_LCC5 0x0066 -+#define OV9650_MANU 0x0067 -+#define OV9650_MANV 0x0068 -+#define OV9650_HV 0x0069 -+#define OV9650_MBD 0x006A -+#define OV9650_DBLV 0x006B -+#define OV9650_GSP0 0x006C -+#define OV9650_GSP1 0x006D -+#define OV9650_GSP2 0x006E -+#define OV9650_GSP3 0x006F -+#define OV9650_GSP4 0x0070 -+#define OV9650_GSP5 0x0071 -+#define OV9650_GSP6 0x0072 -+#define OV9650_GSP7 0x0073 -+#define OV9650_GSP8 0x0074 -+#define OV9650_GSP9 0x0075 -+#define OV9650_GSP10 0x0076 -+#define OV9650_GSP11 0x0077 -+#define OV9650_GSP12 0x0078 -+#define OV9650_GSP13 0x0079 -+#define OV9650_GSP14 0x007A -+#define OV9650_GSP15 0x007B -+#define OV9650_GST0 0x007C -+#define OV9650_GST1 0x007D -+#define OV9650_GST2 0x007E -+#define OV9650_GST3 0x007F -+#define OV9650_GST4 0x0080 -+#define OV9650_GST5 0x0081 -+#define OV9650_GST6 0x0082 -+#define OV9650_GST7 0x0083 -+#define OV9650_GST8 0x0084 -+#define OV9650_GST9 0x0085 -+#define OV9650_GST10 0x0086 -+#define OV9650_GST11 0x0087 -+#define OV9650_GST12 0x0088 -+#define OV9650_GST13 0x0089 -+#define OV9650_GST14 0x008A -+// OV9650 Register Definitions -+#define OV9650_COM21 0x008B -+#define OV9650_COM22 0x008C -+#define OV9650_COM23 0x008D -+#define OV9650_COM24 0x008E -+#define OV9650_DBLC1 0x008F -+#define OV9650_DBLCB 0x0090 -+#define OV9650_DBLCR 0x0091 -+#define OV9650_DMLNL 0x0092 -+#define OV9650_DMLNH 0x0093 -+ -+#define OV9650_AECHM 0x00A1 -+ -+// End of OV9650 register -+#define OV9650_LASTREG 0x00AA -+ -+// End flag of register -+#define OV9650_REGEND ( 0xff ) -+ -+ -+ -+/*********************************************************************** -+ * -+ * Function Prototype -+ * -+ ***********************************************************************/ -+ -+void ov9650_power_down( int powerDown ); -+void ov9650_soft_reset( void ); -+ -+int ov9650_version_revision(u8 * pCmRevision, u8 *pSensorRevision); -+void ov9650_auto_function_on(void); -+void ov9650_auto_function_off(void); -+ -+int ov9650_viewfinder_on(void); -+int ov9650_viewfinder_off(void); -+ -+int ov9650_set_format( u32 captureSizeFormat, u32 colorFormat ); -+int ov9650_prepare_capture(p_camera_context_t cam_ctx, u32 captureSizeFormat, u32 colorFormat); -+void ov9650_set_start(void); -+int ov9650_output_stoped(void); -+void ov9650_set_stop(p_camera_context_t cam_ctx); -+void ov9650_save_gains(void); -+int ov9650_set_window(struct video_window *vw); -+int ov9650_get_window(struct video_window *vw); -+int ov9650_set_sensor_size(void *w_size); -+int ov9650_get_sensor_size(void *w_size); -+int ov9650_set_output_size(void *w_size); -+int ov9650_get_output_size(void *w_size); -+int ov9650_set_special_effect(int style); -+int ov9650_set_white_balance(V4l_PIC_WB light); -+int ov9650_set_flicker(int freq); -+int ov9650_set_brightness(int); -+int ov9650_set_fps(int fps, int min_fps); -+int ov9650_set_night_mode(void); -+int ov9650_set_auto_mode(void); -+int ov9650_set_action_mode(void); -+int ov9650_set_contrast(int); -+ -+extern int i2c_ov9650_deinit(void); -+ -+extern int i2c_ov9650_init(void); -+extern int i2c_ov9650_cleanup(void); -+extern int i2c_ov9650_read(u8 addr, u8 *pvalue); -+extern int i2c_ov9650_write(u8 addr, u8 value); -+ -+ -+#endif -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/pxa_camera.c linux-2.6.16.5-exz/drivers/media/video/pxa_camera.c ---- linux-2.6.16.5/drivers/media/video/pxa_camera.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/pxa_camera.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,2860 @@ -+/*================================================================================ -+ -+ Module Name: pxa-camera.c -+ -+General Description: Camera module e680 camera source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+Wangfei(w20239) 12/19/2003 LIBdd35749 Created -+ -+WangWenxin(w20158) 1/1/2004 LIBdd35749 Modified -+ -+wangfei(w20239) 02/05/2004 LIBdd74309 Set frame rate in video mode -+ -+wangfei(w20239) 02/26/2004 LIBdd81055 New chip id support -+ Update algorithm for DMA transfer -+ Update strategy for memory management -+ Fix still picture capture failed sometime -+ New Agilent sensor chip ID support -+ Make output height in an even multiple of 8 -+ Dynamic power management feature -+ -+wangfei(w20239) 03/08/2004 LIBdd84578 Photo effects setting -+ Fix segmentation fault in rmmod -+ Adjust default image buffer size -+ -+wangfei(w20239) 04/26/2004 LIBdd97716 Power Management added -+ Photo effects setting bug fix -+ -+wangfei(w20239) 05/28/2004 LIBee13628 add two new interface. -+ 1 get ready frames -+ 2 set frame buffer count -+ -+ 06/10/2004 add mt9v111 support -+ -+Portability: Indicate ifthis module is portable to other compilers or -+platforms. If not, indicate specific reasons why is it not portable. -+ -+================================================================================== -+ INCLUDE FILES -+================================================================================*/ -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/fs.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+#include <linux/videodev.h> -+#include <linux/pci.h> -+#include <linux/pm.h> -+#include <linux/poll.h> -+#include <linux/wait.h> -+ -+#include <linux/types.h> -+#include <asm/mach-types.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/dma.h> -+#include <asm/arch/irqs.h> -+#include <asm/irq.h> -+ -+#include <asm/arch/pxa-regs.h> -+ -+#include "camera.h" -+//#include "adcm2700_hw.h" -+ -+#define CIBR0_PHY (0x50000000 + 0x28) -+#define CIBR1_PHY (0x50000000 + 0x30) -+#define CIBR2_PHY (0x50000000 + 0x38) -+/* -+ * It is required to have at least 3 frames in buffer -+ * in current implementation -+ */ -+#define FRAMES_IN_BUFFER 3 -+#define SINGLE_DESC_TRANS_MAX PAGE_SIZE -+ -+ -+#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */ -+#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */ -+#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */ -+ -+static camera_context_t *g_camera_context; -+#ifdef CONFIG_ARCH_EZX_E680 -+extern camera_function_t e680_camera_func; -+#endif -+#ifdef CONFIG_ARCH_EZX_A780 -+ #ifdef CONFIG_CAMERA_MT9M111 -+ extern camera_function_t mt9m111_func; -+ #endif -+ #ifdef CONFIG_CAMERA_OV9640 -+ extern camera_function_t ov9640_func; -+ #endif -+ #ifdef CONFIG_CAMERA_OV9650 -+ extern camera_function_t camera_ov9650_func; -+ #endif -+ #ifdef CONFIG_CAMERA_ADCM3800 -+ extern camera_function_t camera_adcm3800_func; -+ #endif -+#endif -+wait_queue_head_t camera_wait_q; -+ -+/* /dev/videoX registration number */ -+static int minor = 0; -+static int ci_dma_y = -1; -+static int ci_dma_cb = -1; -+static int ci_dma_cr = -1; -+static int task_waiting = 0; -+static int still_image_mode = 0; -+static int still_image_rdy = 0; -+static int first_video_frame = 0; -+static int detected_sensor_type = 0; -+// map of camera image format (camera.h) ==> capture interface format (ci.h) -+static const CI_IMAGE_FORMAT FORMAT_MAPPINGS[] = -+{ -+ CI_RAW8, //RAW -+ CI_RAW9, -+ CI_RAW10, -+ -+ CI_RGB444, //RGB -+ CI_RGB555, -+ CI_RGB565, -+ CI_RGB666_PACKED, //RGB Packed -+ CI_RGB666, -+ CI_RGB888_PACKED, -+ CI_RGB888, -+ CI_RGBT555_0, //RGB+Transparent bit 0 -+ CI_RGBT888_0, -+ CI_RGBT555_1, //RGB+Transparent bit 1 -+ CI_RGBT888_1, -+ -+ CI_INVALID_FORMAT, -+ CI_YCBCR422, //YCBCR -+ CI_YCBCR422_PLANAR, //YCBCR Planaried -+ CI_INVALID_FORMAT, -+ CI_INVALID_FORMAT -+}; -+ -+ -+void pxa_ci_dma_irq_y(int channel, void *data, struct pt_regs *regs); -+void pxa_ci_dma_irq_cb(int channel, void *data, struct pt_regs *regs); -+void pxa_ci_dma_irq_cr(int channel, void *data, struct pt_regs *regs); -+void stop_dma_transfer(p_camera_context_t camera_context); -+int start_capture(p_camera_context_t camera_context, unsigned int block_id, unsigned int frames); -+int camera_init(p_camera_context_t camera_context); -+static int update_dma_chain(p_camera_context_t camera_context); -+ -+static int pxa_camera_open(struct inode *inode, struct file *file); -+static int pxa_camera_close(struct inode *inode, struct file *file); -+static ssize_t pxa_camera_read(struct file *file, char __user *data, -+ size_t count, loff_t *ppos); -+static ssize_t pxa_camera_write(struct file *file, const char __user *data, -+ size_t count, loff_t *ppos); -+static unsigned int pxa_camera_poll(struct file *file, poll_table *wait); -+static int pxa_camera_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg); -+static int pxa_camera_mmap(struct file *file, struct vm_area_struct *vma); -+int pxa_camera_video_init(struct video_device *vdev); -+ -+void start_dma_transfer(p_camera_context_t camera_context, unsigned block_id); -+void pxa_dma_repeat(camera_context_t *cam_ctx); -+void pxa_dma_continue(camera_context_t *cam_ctx); -+ -+int pxa_camera_mem_deinit(void); -+int pxa_camera_mem_init(void); -+ -+static struct file_operations vd_fops = { -+ .owner = THIS_MODULE, -+ .open = pxa_camera_open, -+ .release = pxa_camera_close, -+ .read = pxa_camera_read, -+ .poll = pxa_camera_poll, -+ .ioctl = pxa_camera_ioctl, -+ .mmap = pxa_camera_mmap, -+ .llseek = no_llseek, -+ .write = pxa_camera_write, -+}; -+ -+static struct video_device vd = { -+ .owner = THIS_MODULE, -+ .name = "E680 camera", -+ .type = VID_TYPE_CAPTURE, -+ .hardware = VID_HARDWARE_PXA_CAMERA, /* FIXME */ -+ .fops = &vd_fops, -+ //FIXME .initialize = pxa_camera_video_init, -+ .minor = -1, -+}; -+ -+ -+/*********************************************************************** -+ * -+ * Declarations -+ * -+ ***********************************************************************/ -+ -+ -+#ifdef CONFIG_PM -+ static struct pm_dev *pm_dev; -+#endif -+ -+#ifdef CONFIG_PM -+static int camera_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ if(g_camera_context == NULL) -+ { -+ return 0; -+ } -+ -+ if(g_camera_context->camera_functions == NULL) -+ { -+ return 0; -+ } -+ -+ switch(req) -+ { -+ case PM_SUSPEND: -+ g_camera_context->camera_functions->pm_management(g_camera_context, 1); -+ break; -+ -+ case PM_RESUME: -+ g_camera_context->camera_functions->pm_management(g_camera_context, 0); -+ break; -+ -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+/*********************************************************************** -+ * -+ * Private functions -+ * -+ ***********************************************************************/ -+ -+static int pxa_dma_buffer_init(p_camera_context_t camera_context) -+{ -+ struct page *page; -+ unsigned int pages; -+ unsigned int page_count; -+ -+ camera_context->pages_allocated = 0; -+ -+ pages = (PAGE_ALIGN(camera_context->buf_size) / PAGE_SIZE); -+ -+ camera_context->page_array = (struct page **) -+ kmalloc(pages * sizeof(struct page *), -+ GFP_KERNEL); -+ -+ if(camera_context->page_array == NULL) -+ { -+ return -ENOMEM; -+ } -+ memset(camera_context->page_array, 0, pages * sizeof(struct page *)); -+ -+ for(page_count = 0; page_count < pages; page_count++) -+ { -+ page = alloc_page(GFP_KERNEL); -+ if(page == NULL) -+ { -+ goto error; -+ } -+ camera_context->page_array[page_count] = page; -+ set_page_count(page, 1); -+ SetPageReserved(page); -+ } -+ camera_context->buffer_virtual = remap_page_array(camera_context->page_array, -+ pages, -+ GFP_KERNEL); -+ if(camera_context->buffer_virtual == NULL) -+ { -+ goto error; -+ } -+ -+ camera_context->pages_allocated = pages; -+ -+ return 0; -+ -+error: -+ for(page_count = 0; page_count < pages; page_count++) -+ { -+ if((page = camera_context->page_array[page_count]) != NULL) -+ { -+ ClearPageReserved(page); -+ set_page_count(page, 1); -+ put_page(page); -+ } -+ } -+ kfree(camera_context->page_array); -+ -+ return -ENOMEM; -+} -+ -+static void pxa_dma_buffer_free(p_camera_context_t camera_context) -+{ -+ struct page *page; -+ int page_count; -+ -+ if(camera_context->buffer_virtual == NULL) -+ return; -+ -+ vfree(camera_context->buffer_virtual); -+ -+ for(page_count = 0; page_count < camera_context->pages_allocated; page_count++) -+ { -+ if((page = camera_context->page_array[page_count]) != NULL) -+ { -+ ClearPageReserved(page); -+ set_page_count(page, 1); -+ put_page(page); -+ } -+ } -+ kfree(camera_context->page_array); -+} -+/* -+Generate dma descriptors -+Pre-condition: these variables must be set properly -+ block_number, fifox_transfer_size -+ dma_descriptors_virtual, dma_descriptors_physical, dma_descirptors_size -+Post-condition: these variables will be set -+ fifox_descriptors_virtual, fifox_descriptors_physical -+ fifox_num_descriptors -+*/ -+//#ifdef CONFIG_ARCH_EZX_E680 -+static int generate_fifo2_dma_chain(p_camera_context_t camera_context, pxa_dma_desc ** cur_vir, pxa_dma_desc ** cur_phy) -+{ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL; -+ int des_transfer_size, remain_size, target_page_num; -+ unsigned int i,j; -+ -+ cur_des_virtual = (pxa_dma_desc *)camera_context->fifo2_descriptors_virtual; -+ cur_des_physical = (pxa_dma_desc *)camera_context->fifo2_descriptors_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo2_transfer_size; -+ -+ target_page_num = camera_context->pages_per_block * i + -+ camera_context->pages_per_fifo0 + -+ camera_context->pages_per_fifo1; -+ -+ if (camera_context->pages_per_fifo1 > 1) -+ { -+ for(j=0; j<camera_context->fifo2_num_descriptors; j++) -+ { -+ // set descriptor -+ if (remain_size > SINGLE_DESC_TRANS_MAX) -+ { -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ } -+ else -+ { -+ des_transfer_size = remain_size; -+ } -+ -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR2_PHY; // FIFO2 physical address -+ cur_des_virtual->dtadr = -+ page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ else -+ { -+ for(j=0; j<camera_context->fifo2_num_descriptors; j++) -+ { -+ // set descriptor -+ if (remain_size > SINGLE_DESC_TRANS_MAX/2) -+ { -+ des_transfer_size = SINGLE_DESC_TRANS_MAX/2; -+ } -+ else -+ { -+ des_transfer_size = remain_size; -+ } -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR2_PHY; // FIFO2 physical address -+ if (!(j % 2)) -+ { -+ cur_des_virtual->dtadr = -+ page_to_bus(camera_context->page_array[target_page_num]); -+ } -+ else -+ { -+ cur_des_virtual->dtadr = -+ page_to_bus(camera_context->page_array[target_page_num]) + (PAGE_SIZE/2); -+ } -+ -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ ddbg_print(" CR: the ddadr = %8x, dtadr = %8x, dcmd = %8x, page = %8x \n", -+ cur_des_virtual->ddadr, -+ cur_des_virtual->dtadr, -+ cur_des_virtual->dcmd, -+ page_to_bus(camera_context->page_array[target_page_num]) ); -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ -+ if (j % 2) -+ { -+ target_page_num++; -+ } -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ } -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo2_descriptors_physical); -+ -+ *cur_vir = cur_des_virtual; -+ *cur_phy = cur_des_physical; -+ return 0; -+} -+static int generate_fifo1_dma_chain(p_camera_context_t camera_context, pxa_dma_desc ** cur_vir, pxa_dma_desc ** cur_phy) -+{ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL; -+ int des_transfer_size, remain_size, target_page_num; -+ unsigned int i,j; -+ -+ cur_des_virtual = (pxa_dma_desc *)camera_context->fifo1_descriptors_virtual; -+ cur_des_physical = (pxa_dma_desc *)camera_context->fifo1_descriptors_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo1_transfer_size; -+ -+ target_page_num = camera_context->pages_per_block * i + -+ camera_context->pages_per_fifo0; -+ -+ if (camera_context->pages_per_fifo1 > 1) -+ { -+ for(j=0; j<camera_context->fifo1_num_descriptors; j++) -+ { -+ // set descriptor -+ if (remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR1_PHY; // FIFO1 physical address -+ cur_des_virtual->dtadr = -+ page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ else -+ { -+ for(j=0; j<camera_context->fifo1_num_descriptors; j++) -+ { -+ // set descriptor -+ if (remain_size > SINGLE_DESC_TRANS_MAX/2) -+ { -+ des_transfer_size = SINGLE_DESC_TRANS_MAX/2; -+ } -+ else -+ { -+ des_transfer_size = remain_size; -+ } -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR1_PHY; // FIFO1 physical address -+ if(!(j % 2)) -+ { -+ cur_des_virtual->dtadr = -+ page_to_bus(camera_context->page_array[target_page_num]); -+ } -+ else -+ { -+ cur_des_virtual->dtadr = -+ page_to_bus(camera_context->page_array[target_page_num]) + (PAGE_SIZE/2); -+ } -+ -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ ddbg_print("CB: the ddadr = %8x, dtadr = %8x, dcmd = %8x, page = %8x \n", -+ cur_des_virtual->ddadr, -+ cur_des_virtual->dtadr, -+ cur_des_virtual->dcmd, -+ page_to_bus(camera_context->page_array[target_page_num])); -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ if (j % 2) -+ { -+ target_page_num++; -+ } -+ }//end of for j... -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ }// end of else -+ }//end of for i... -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo1_descriptors_physical); -+ *cur_vir = cur_des_virtual; -+ *cur_phy = cur_des_physical; -+ -+ return 0; -+} -+static int generate_fifo0_dma_chain(p_camera_context_t camera_context, pxa_dma_desc ** cur_vir, pxa_dma_desc ** cur_phy) -+{ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL; -+ int des_transfer_size, remain_size, target_page_num; -+ unsigned int i,j; -+ -+ cur_des_virtual = (pxa_dma_desc *)camera_context->fifo0_descriptors_virtual; -+ cur_des_physical = (pxa_dma_desc *)camera_context->fifo0_descriptors_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo0_transfer_size; -+ -+ // assume the blocks are stored consecutively -+ target_page_num = camera_context->pages_per_block * i; -+ -+ if (camera_context->pages_per_fifo0 > 2) -+ { -+ for(j=0; j<camera_context->fifo0_num_descriptors; j++) -+ { -+ // set descriptor -+ if (remain_size > SINGLE_DESC_TRANS_MAX) -+ { -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ } -+ else -+ { -+ des_transfer_size = remain_size; -+ } -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR0_PHY; // FIFO0 physical address -+ cur_des_virtual->dtadr = -+ page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ else -+ { -+ for(j=0; j<camera_context->fifo0_num_descriptors; j++) -+ { -+ // set descriptor -+ if(remain_size > SINGLE_DESC_TRANS_MAX/2) -+ { -+ des_transfer_size = SINGLE_DESC_TRANS_MAX/2; -+ } -+ else -+ { -+ des_transfer_size = remain_size; -+ } -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR0_PHY; // FIFO0 physical address -+ if(!(j % 2)) -+ { -+ cur_des_virtual->dtadr = page_to_bus(camera_context->page_array[target_page_num]); -+ } -+ else -+ { -+ cur_des_virtual->dtadr = page_to_bus(camera_context->page_array[target_page_num]) + (PAGE_SIZE / 2); -+ } -+ -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ ddbg_print(" Y: the ddadr = %8x, dtadr = %8x, dcmd = %8x, page = %8x, page_num = %d \n", -+ cur_des_virtual->ddadr, -+ cur_des_virtual->dtadr, -+ cur_des_virtual->dcmd, -+ page_to_bus(camera_context->page_array[target_page_num]), -+ target_page_num); -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ if (j % 2) -+ { -+ target_page_num++; -+ } -+ }//end of for j.. -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ }// end of else -+ } -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo0_descriptors_physical); -+ *cur_vir = cur_des_virtual; -+ *cur_phy = cur_des_physical; -+ return 0; -+} -+ -+int update_dma_chain(p_camera_context_t camera_context) -+{ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical; -+ // clear descriptor pointers -+ camera_context->fifo0_descriptors_virtual = camera_context->fifo0_descriptors_physical = 0; -+ camera_context->fifo1_descriptors_virtual = camera_context->fifo1_descriptors_physical = 0; -+ camera_context->fifo2_descriptors_virtual = camera_context->fifo2_descriptors_physical = 0; -+ -+ // calculate how many descriptors are needed per frame -+ camera_context->fifo0_num_descriptors = -+ camera_context->pages_per_fifo0 > 2 ? camera_context->pages_per_fifo0 : (camera_context->fifo0_transfer_size / (PAGE_SIZE/2) + 1); -+ -+ camera_context->fifo1_num_descriptors = -+ camera_context->pages_per_fifo1 > 1 ? camera_context->pages_per_fifo1 : (camera_context->fifo1_transfer_size / (PAGE_SIZE/2) + 1); -+ -+ camera_context->fifo2_num_descriptors = -+ camera_context->pages_per_fifo2 > 1 ? camera_context->pages_per_fifo2 : (camera_context->fifo2_transfer_size / (PAGE_SIZE/2) + 1); -+ -+ // check if enough memory to generate descriptors -+ if((camera_context->fifo0_num_descriptors + camera_context->fifo1_num_descriptors + -+ camera_context->fifo2_num_descriptors) * camera_context->block_number -+ > camera_context->dma_descriptors_size) -+ { -+ return -1; -+ } -+ -+ // generate fifo0 dma chains -+ camera_context->fifo0_descriptors_virtual = (unsigned)camera_context->dma_descriptors_virtual; -+ camera_context->fifo0_descriptors_physical = (unsigned)camera_context->dma_descriptors_physical; -+ // generate fifo0 dma chains -+ generate_fifo0_dma_chain(camera_context, &cur_des_virtual, &cur_des_physical); -+ -+ // generate fifo1 dma chains -+ if(!camera_context->fifo1_transfer_size) -+ { -+ return 0; -+ } -+ // record fifo1 descriptors' start address -+ camera_context->fifo1_descriptors_virtual = (unsigned)cur_des_virtual; -+ camera_context->fifo1_descriptors_physical = (unsigned)cur_des_physical; -+ // generate fifo1 dma chains -+ generate_fifo1_dma_chain(camera_context, &cur_des_virtual, &cur_des_physical); -+ -+ if(!camera_context->fifo2_transfer_size) -+ { -+ return 0; -+ } -+ // record fifo1 descriptors' start address -+ camera_context->fifo2_descriptors_virtual = (unsigned)cur_des_virtual; -+ camera_context->fifo2_descriptors_physical = (unsigned)cur_des_physical; -+ // generate fifo2 dma chains -+ generate_fifo2_dma_chain(camera_context, &cur_des_virtual, &cur_des_physical); -+ -+ return 0; -+} -+//#else -+#if 0 -+int update_dma_chain(p_camera_context_t camera_context) -+{ -+ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL; -+ int des_transfer_size, remain_size; -+ unsigned int i,j; -+ int target_page_num; -+ -+ dbg_print(""); -+ -+ // clear descriptor pointers -+ camera_context->fifo0_descriptors_virtual = camera_context->fifo0_descriptors_physical = 0; -+ camera_context->fifo1_descriptors_virtual = camera_context->fifo1_descriptors_physical = 0; -+ camera_context->fifo2_descriptors_virtual = camera_context->fifo2_descriptors_physical = 0; -+ -+ // calculate how many descriptors are needed per frame -+ camera_context->fifo0_num_descriptors = -+ camera_context->pages_per_fifo0; -+ -+ camera_context->fifo1_num_descriptors = -+ camera_context->pages_per_fifo1; -+ -+ camera_context->fifo2_num_descriptors = -+ camera_context->pages_per_fifo2; -+ -+ // check if enough memory to generate descriptors -+ if((camera_context->fifo0_num_descriptors + -+ camera_context->fifo1_num_descriptors + -+ camera_context->fifo2_num_descriptors) * camera_context->block_number -+ > camera_context->dma_descriptors_size) -+ { -+ return -1; -+ } -+ -+ dbg_print("1"); -+ // generate fifo0 dma chains -+ camera_context->fifo0_descriptors_virtual = (unsigned)camera_context->dma_descriptors_virtual; -+ camera_context->fifo0_descriptors_physical = (unsigned)camera_context->dma_descriptors_physical; -+ -+ cur_des_virtual = (pxa_dma_desc *)camera_context->fifo0_descriptors_virtual; -+ cur_des_physical = (pxa_dma_desc *)camera_context->fifo0_descriptors_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo0_transfer_size; -+ -+ // assume the blocks are stored consecutively -+ target_page_num = camera_context->pages_per_block * i; -+ -+ for(j=0; j<camera_context->fifo0_num_descriptors; j++) -+ { -+ // set descriptor -+ if(remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR0_PHY; // FIFO0 physical address -+ cur_des_virtual->dtadr = page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo0_descriptors_physical); -+ -+ // generate fifo1 dma chains -+ if(camera_context->fifo1_transfer_size) -+ { -+ // record fifo1 descriptors' start address -+ camera_context->fifo1_descriptors_virtual = (unsigned)cur_des_virtual; -+ camera_context->fifo1_descriptors_physical = (unsigned)cur_des_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo1_transfer_size; -+ -+ target_page_num = camera_context->pages_per_block * i + -+ camera_context->pages_per_fifo0; -+ -+ for(j=0; j<camera_context->fifo1_num_descriptors; j++) -+ { -+ // set descriptor -+ if(remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR1_PHY; // FIFO1 physical address -+ cur_des_virtual->dtadr = page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ // advance pointers -+ -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo1_descriptors_physical); -+ } -+ -+ // generate fifo2 dma chains -+ if(camera_context->fifo2_transfer_size) -+ { -+ // record fifo1 descriptors' start address -+ camera_context->fifo2_descriptors_virtual = (unsigned)cur_des_virtual; -+ camera_context->fifo2_descriptors_physical = (unsigned)cur_des_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo2_transfer_size; -+ -+ target_page_num = camera_context->pages_per_block * i + -+ camera_context->pages_per_fifo0 + -+ camera_context->pages_per_fifo1; -+ -+ for(j=0; j<camera_context->fifo2_num_descriptors; j++) -+ { -+ // set descriptor -+ if(remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR2_PHY; // FIFO2 physical address -+ cur_des_virtual->dtadr = page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo2_descriptors_physical); -+ } -+ -+ dbg_print(" success!"); -+ return 0; -+} -+#endif -+void start_dma_transfer(p_camera_context_t camera_context, unsigned block_id) -+{ -+ pxa_dma_desc *des_virtual, *des_physical; -+ /* -+ if(block_id >= camera_context->block_number) -+ { -+ return; -+ } -+ */ -+ // start channel 0 -+ des_virtual = (pxa_dma_desc *)camera_context->fifo0_descriptors_virtual + -+ block_id * camera_context->fifo0_num_descriptors; -+ -+ des_physical = (pxa_dma_desc *)camera_context->fifo0_descriptors_physical + -+ block_id * camera_context->fifo0_num_descriptors; -+ -+ DDADR(camera_context->dma_channels[0]) = des_physical; -+ DCSR(camera_context->dma_channels[0]) |= DCSR_RUN; -+ -+ // start channel 1 -+ if(camera_context->fifo1_descriptors_virtual) -+ { -+ des_virtual = (pxa_dma_desc *)camera_context->fifo1_descriptors_virtual + -+ block_id * camera_context->fifo1_num_descriptors; -+ -+ des_physical = (pxa_dma_desc *)camera_context->fifo1_descriptors_physical + -+ block_id * camera_context->fifo1_num_descriptors; -+ -+ DDADR(camera_context->dma_channels[1]) = des_physical; -+ DCSR(camera_context->dma_channels[1]) |= DCSR_RUN; -+ } -+ -+ // start channel 2 -+ if(camera_context->fifo2_descriptors_virtual) -+ { -+ des_virtual = (pxa_dma_desc *)camera_context->fifo2_descriptors_virtual + -+ block_id * camera_context->fifo2_num_descriptors; -+ -+ des_physical = (pxa_dma_desc *)camera_context->fifo2_descriptors_physical + -+ block_id * camera_context->fifo2_num_descriptors; -+ -+ DDADR(camera_context->dma_channels[2]) = des_physical; -+ DCSR(camera_context->dma_channels[2]) |= DCSR_RUN; -+ } -+ -+ camera_context->dma_started = 1; -+} -+ -+void set_still_image_ready(int rdy) -+{ -+ still_image_rdy = rdy; -+} -+void stop_dma_transfer(p_camera_context_t camera_context) -+{ -+ int ch0, ch1, ch2; -+ -+ ch0 = camera_context->dma_channels[0]; -+ ch1 = camera_context->dma_channels[1]; -+ ch2 = camera_context->dma_channels[2]; -+ -+ DCSR(ch0) &= ~DCSR_RUN; -+ DCSR(ch1) &= ~DCSR_RUN; -+ DCSR(ch2) &= ~DCSR_RUN; -+ camera_context->dma_started = 0; -+ -+ return; -+} -+ -+int start_capture(p_camera_context_t camera_context, unsigned int block_id, unsigned int frames) -+{ -+ int status; -+ status = camera_context->camera_functions->start_capture(camera_context, frames); -+ -+ return status; -+} -+ -+/*********************************************************************** -+ * -+ * Init/Deinit APIs -+ * -+ ***********************************************************************/ -+int camera_init(p_camera_context_t camera_context) -+{ -+ int ret=0; -+ dbg_print(""); -+ -+ /*init gpio pins*/ -+ //camera_gpio_init(); -+ -+ /*init cif*/ -+ // ci_init(); -+ -+ /*init sensor */ -+ if(detected_sensor_type == 0) { -+ /* test sensor type */ -+#ifdef CONFIG_ARCH_EZX_E680 -+ camera_context->camera_functions = &e680_camera_func; -+ if((ret = camera_context->camera_functions->init(camera_context)) ==0) -+ { -+ goto test_success; -+ } -+#endif -+#ifdef CONFIG_ARCH_EZX_A780 -+ -+ #ifdef CONFIG_CAMERA_MT9M111 -+ camera_context->camera_functions = &mt9m111_func; -+ if((ret = camera_context->camera_functions->init(camera_context)) ==0) -+ { -+ goto test_success; -+ } -+ #endif -+ -+ #ifdef CONFIG_CAMERA_ADCM3800 -+ dbg_print("detect ADCM3800..."); -+ camera_context->camera_functions = &camera_adcm3800_func; -+ if((ret = camera_context->camera_functions->init(camera_context)) ==0) -+ { -+ goto test_success; -+ } -+ #endif -+ -+ #ifdef CONFIG_CAMERA_OV9650 -+ dbg_print("detect OV9650..."); -+ camera_context->camera_functions = &camera_ov9650_func; -+ if((ret = camera_context->camera_functions->init(camera_context)) ==0) -+ { -+ goto test_success; -+ } -+ #endif -+ -+ #ifdef CONFIG_CAMERA_OV9640 -+ camera_context->camera_functions = &ov9640_func; -+ if((ret = camera_context->camera_functions->init(camera_context)) ==0) -+ { -+ goto test_success; -+ } -+ #endif -+ -+#endif -+ -+ camera_context->camera_functions = 0; -+ -+ dbg_print("camera function init error!!"); -+ goto camera_init_err; -+ } -+ else -+ { -+ switch (detected_sensor_type) { -+#ifdef CONFIG_ARCH_EZX_E680 -+ case CAMERA_TYPE_ADCM_2700: -+ camera_context->camera_functions = &e680_camera_func; -+ break; -+ case CAMERA_TYPE_MT9V111: -+ camera_context->camera_functions = &e680_camera_func; -+ break; -+#endif -+#ifdef CONFIG_ARCH_EZX_A780 -+ #ifdef CONFIG_CAMERA_OV9640 -+ case CAMERA_TYPE_OMNIVISION_9640: -+ camera_context->camera_functions = &ov9640_func; -+ break; -+ #endif -+ #ifdef CONFIG_CAMERA_MT9M111 -+ case CAMERA_TYPE_MT9M111: -+ camera_context->camera_functions = &mt9m111_func; -+ break; -+ #endif -+ #ifdef CONFIG_CAMERA_ADCM3800 -+ case CAMERA_TYPE_ADCM3800: -+ camera_context->camera_functions = &camera_adcm3800_func; -+ break; -+ #endif -+ #ifdef CONFIG_CAMERA_OV9650 -+ case CAMERA_TYPE_OV9650: -+ camera_context->camera_functions = &camera_ov9650_func; -+ break; -+ #endif -+#endif -+ } -+ camera_context->camera_functions->init(camera_context); -+ } -+test_success: -+ camera_context->dma_channels[0] = ci_dma_y; -+ camera_context->dma_channels[1] = ci_dma_cb; -+ camera_context->dma_channels[2] = ci_dma_cr; -+ DRCMR68 = ci_dma_y | DRCMR_MAPVLD; -+ DRCMR69 = ci_dma_cb | DRCMR_MAPVLD; -+ DRCMR70 = ci_dma_cr | DRCMR_MAPVLD; -+ -+ detected_sensor_type = camera_context->sensor_type; -+#ifdef DEBUG -+ ci_dump(); -+#endif -+ return 0; -+ -+camera_init_err: -+ camera_deinit(camera_context); -+ return -1; -+} -+ -+void camera_gpio_init() -+{ -+ -+ pxa_gpio_mode( CIF_PD_MD ); /*CIF_PD*/ -+ GPCR(CIF_PD) = GPIO_bit(CIF_PD); /*set to low*/ -+ pxa_gpio_mode( CIF_RST_MD ); /*CIF_RST*/ -+ GPSR(CIF_RST) = GPIO_bit(CIF_RST); /*set to high*/ -+ -+ pxa_gpio_mode( CIF_DD0_MD ); /* CIF_DD[0] */ -+ pxa_gpio_mode( CIF_DD1_MD ); /* CIF_DD[1] */ -+ pxa_gpio_mode( CIF_DD2_MD ); /* CIF_DD[2] */ -+ pxa_gpio_mode( CIF_DD3_MD ); /* CIF_DD[3] */ -+ pxa_gpio_mode( CIF_DD4_MD ); /* CIF_DD[4] */ -+ pxa_gpio_mode( CIF_DD5_MD ); /* CIF_DD[5] */ -+ pxa_gpio_mode( CIF_DD6_MD ); /* CIF_DD[6] */ -+ pxa_gpio_mode( CIF_DD7_MD ); /* CIF_DD[7] */ -+ pxa_gpio_mode( CIF_MCLK_MD ); /* CIF_MCLK */ -+ pxa_gpio_mode( CIF_PCLK_MD ); /* CIF_PCLK */ -+ pxa_gpio_mode( CIF_LV_MD ); /* CIF_LV */ -+ pxa_gpio_mode( CIF_FV_MD ); /* CIF_FV */ -+} -+ -+ -+void camera_gpio_deinit() -+{ -+ /* Turn off M_VCC CIF_PD*/ -+ GPSR(CIF_PD) = GPIO_bit(CIF_PD); /* Set PD to low */ -+ pxa_gpio_mode( CIF_MCLK | GPIO_IN); /*trun off MCLK*/ -+} -+ -+int camera_deinit( p_camera_context_t camera_context ) -+{ -+ // deinit sensor -+ if(camera_context->camera_functions) -+ camera_context->camera_functions->deinit(camera_context); -+ -+ // capture interface deinit -+ ci_deinit(); -+ //camera_gpio_deinit(); -+ return 0; -+} -+ -+int camera_ring_buf_init(p_camera_context_t camera_context) -+{ -+ unsigned frame_size; -+ dbg_print(""); -+ switch(camera_context->capture_output_format) -+ { -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 2; -+ camera_context->fifo0_transfer_size = frame_size; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 2; -+ camera_context->fifo0_transfer_size = frame_size; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 2; -+ camera_context->fifo0_transfer_size = frame_size / 2; -+ camera_context->fifo1_transfer_size = frame_size / 4; -+ camera_context->fifo2_transfer_size = frame_size / 4; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB666_PLANAR: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 4; -+ camera_context->fifo0_transfer_size = frame_size; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB666_PACKED: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 3; -+ camera_context->fifo0_transfer_size = frame_size; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ break; -+ default: -+ return STATUS_WRONG_PARAMETER; -+ break; -+ } -+ -+ camera_context->block_size = frame_size; -+ -+ camera_context->pages_per_fifo0 = -+ (PAGE_ALIGN(camera_context->fifo0_transfer_size) / PAGE_SIZE); -+ camera_context->pages_per_fifo1 = -+ (PAGE_ALIGN(camera_context->fifo1_transfer_size) / PAGE_SIZE); -+ camera_context->pages_per_fifo2 = -+ (PAGE_ALIGN(camera_context->fifo2_transfer_size) / PAGE_SIZE); -+ -+ camera_context->pages_per_block = -+ camera_context->pages_per_fifo0 + -+ camera_context->pages_per_fifo1 + -+ camera_context->pages_per_fifo2; -+ -+ camera_context->page_aligned_block_size = -+ camera_context->pages_per_block * PAGE_SIZE; -+ -+ camera_context->block_number_max = -+ camera_context->pages_allocated / -+ camera_context->pages_per_block; -+ -+ -+ //restrict max block number -+ if(camera_context->block_number_max > FRAMES_IN_BUFFER) -+ { -+ camera_context->block_number = FRAMES_IN_BUFFER; -+ } -+ else -+ { -+ camera_context->block_number = camera_context->block_number_max; -+ } -+ camera_context->block_header = camera_context->block_tail = 0; -+ // generate dma descriptor chain -+ return update_dma_chain(camera_context); -+ -+} -+/*********************************************************************** -+ * -+ * Capture APIs -+ * -+ ***********************************************************************/ -+// Set the image format -+int camera_set_capture_format(p_camera_context_t camera_context) -+{ -+ -+ int status=-1; -+ CI_IMAGE_FORMAT ci_input_format, ci_output_format; -+ CI_MP_TIMING timing; -+ -+ if(camera_context->capture_input_format > CAMERA_IMAGE_FORMAT_MAX || -+ camera_context->capture_output_format > CAMERA_IMAGE_FORMAT_MAX ) -+ { -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ ci_input_format = FORMAT_MAPPINGS[camera_context->capture_input_format]; -+ ci_output_format = FORMAT_MAPPINGS[camera_context->capture_output_format]; -+ -+ if(ci_input_format == CI_INVALID_FORMAT || ci_output_format == CI_INVALID_FORMAT) -+ { -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ ci_set_image_format(ci_input_format, ci_output_format); -+ -+ -+ timing.BFW = 0; -+ timing.BLW = 0; -+ -+ ci_configure_mp(camera_context->capture_width-1, camera_context->capture_height-1, &timing); -+ -+ if(camera_context == NULL || camera_context->camera_functions == NULL || -+ camera_context->camera_functions->set_capture_format == NULL) -+ { -+ dbg_print("camera_context point NULL!!!"); -+ return -1; -+ } -+ status = camera_ring_buf_init(camera_context); -+ // set sensor setting -+ if(camera_context->camera_functions->set_capture_format(camera_context)) -+ { -+ return -1; -+ } -+ -+ // ring buffer init -+ return status; -+ -+} -+ -+// take a picture and copy it into the ring buffer -+int camera_capture_still_image(p_camera_context_t camera_context, unsigned int block_id) -+{ -+ // init buffer status & capture -+ camera_set_int_mask(camera_context, 0x3ff | 0x0400); -+ still_image_mode = 1; -+ first_video_frame = 0; -+ task_waiting = 0; -+ camera_context->block_header = camera_context->block_tail = block_id; -+ camera_context->capture_status = 0; -+ still_image_rdy = 0; -+ return start_capture(camera_context, block_id, 1); -+ -+} -+ -+// capture motion video and copy it to the ring buffer -+int camera_start_video_capture( p_camera_context_t camera_context, unsigned int block_id ) -+{ -+ //init buffer status & capture -+ camera_set_int_mask(camera_context, 0x3ff | 0x0400); -+ still_image_mode = 0; -+ first_video_frame = 1; -+ camera_context->block_header = camera_context->block_tail = block_id; -+ camera_context->capture_status = CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS; -+ return start_capture(camera_context, block_id, 0); -+} -+ -+// disable motion video image capture -+void camera_stop_video_capture( p_camera_context_t camera_context ) -+{ -+ -+ //stop capture -+ camera_context->camera_functions->stop_capture(camera_context); -+ -+ //stop dma -+ stop_dma_transfer(camera_context); -+ -+ //update the flag -+ if(!(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ { -+ camera_context->capture_status &= ~CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS; -+ } -+} -+ -+ -+/*********************************************************************** -+ * -+ * Flow Control APIs -+ * -+ ***********************************************************************/ -+// continue capture image to next available buffer -+void camera_continue_transfer( p_camera_context_t camera_context ) -+{ -+ // don't think we need this either. JR -+ // continue transfer on next block -+ start_dma_transfer( camera_context, camera_context->block_tail ); -+} -+ -+// Return 1: there is available buffer, 0: buffer is full -+int camera_next_buffer_available( p_camera_context_t camera_context ) -+{ -+ camera_context->block_header = (camera_context->block_header + 1) % camera_context->block_number; -+ if(((camera_context->block_header + 1) % camera_context->block_number) != camera_context->block_tail) -+ { -+ return 1; -+ } -+ -+ camera_context->capture_status |= CAMERA_STATUS_RING_BUFFER_FULL; -+ return 0; -+} -+ -+// Application supplies the FrameBufferID to the driver to tell it that the application has completed processing of -+// the given frame buffer, and that buffer is now available for re-use. -+void camera_release_frame_buffer(p_camera_context_t camera_context, unsigned int frame_buffer_id) -+{ -+ -+ camera_context->block_tail = (camera_context->block_tail + 1) % camera_context->block_number; -+ -+ // restart video capture only ifvideo capture is in progress and space is available for image capture -+ if((camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL ) && -+ (camera_context->capture_status & CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS)) -+ { -+ if(((camera_context->block_header + 2) % camera_context->block_number) != camera_context->block_tail) -+ { -+ camera_context->capture_status &= ~CAMERA_STATUS_RING_BUFFER_FULL; -+ start_capture(camera_context, camera_context->block_tail, 0); -+ } -+ } -+} -+ -+// Returns the FrameBufferID for the first filled frame -+// Note: -1 represents buffer empty -+int camera_get_first_frame_buffer_id(p_camera_context_t camera_context) -+{ -+ // not sure ifthis routine makes any sense.. JR -+ -+ // check whether buffer is empty -+ if((camera_context->block_header == camera_context->block_tail) && -+ !(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ { -+ return -1; -+ } -+ -+ // return the block header -+ return camera_context->block_header; -+} -+ -+// Returns the FrameBufferID for the last filled frame, this would be used ifwe were polling for image completion data, -+// or we wanted to make sure there were no frames waiting for us to process. -+// Note: -1 represents buffer empty -+int camera_get_last_frame_buffer_id(p_camera_context_t camera_context) -+{ -+ -+ // check whether buffer is empty -+ if((camera_context->block_header == camera_context->block_tail) && -+ !(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ { -+ return -1; -+ } -+ -+ // return the block before the block_tail -+ return (camera_context->block_tail + camera_context->block_number - 1) % camera_context->block_number; -+} -+ -+ -+/*********************************************************************** -+ * -+ * Buffer Info APIs -+ * -+ ***********************************************************************/ -+// Return: the number of frame buffers allocated for use. -+unsigned int camera_get_num_frame_buffers(p_camera_context_t camera_context) -+{ -+ return camera_context->block_number; -+} -+ -+// FrameBufferID is a number between 0 and N-1, where N is the total number of frame buffers in use. Returns the address of -+// the given frame buffer. The application will call this once for each frame buffer at application initialization only. -+void * camera_get_frame_buffer_addr(p_camera_context_t camera_context, unsigned int frame_buffer_id) -+{ -+ return (void*)((unsigned)camera_context->buffer_virtual + -+ camera_context->page_aligned_block_size * frame_buffer_id); -+} -+ -+// Return the block id -+int camera_get_frame_buffer_id(p_camera_context_t camera_context, void* address) -+{ -+ if(((unsigned)address >= (unsigned)camera_context->buffer_virtual) && -+ ((unsigned)address <= (unsigned)camera_context->buffer_virtual + camera_context->buf_size)) -+ { -+ return ((unsigned)address - -+ (unsigned)camera_context->buffer_virtual) / -+ camera_context->page_aligned_block_size; -+ } -+ -+ return -1; -+} -+ -+ -+/*********************************************************************** -+ * -+ * Frame rate APIs -+ * -+ ***********************************************************************/ -+// Set desired frame rate -+void camera_set_capture_frame_rate(p_camera_context_t camera_context) -+{ -+ ci_set_frame_rate(camera_context->fps); -+} -+ -+// return current setting -+void camera_get_capture_frame_rate(p_camera_context_t camera_context) -+{ -+ camera_context->fps = ci_get_frame_rate(); -+} -+ -+ -+/*********************************************************************** -+ * -+ * Interrupt APIs -+ * -+ ***********************************************************************/ -+// set interrupt mask -+void camera_set_int_mask(p_camera_context_t cam_ctx, unsigned int mask) -+{ -+ pxa_dma_desc * end_des_virtual; -+ int dma_interrupt_on, i; -+ -+ // set CI interrupt -+ ci_set_int_mask( mask & CI_CICR0_INTERRUPT_MASK ); -+ -+ // set dma end interrupt -+ if( mask & CAMERA_INTMASK_END_OF_DMA ) -+ dma_interrupt_on = 1; -+ else -+ dma_interrupt_on = 0; -+ -+ // set fifo0 dma chains' flag -+ end_des_virtual = (pxa_dma_desc*)cam_ctx->fifo0_descriptors_virtual + cam_ctx->fifo0_num_descriptors - 1; -+ -+ for(i=0; i<cam_ctx->block_number; i++) -+ { -+ if(dma_interrupt_on) -+ end_des_virtual->dcmd |= DCMD_ENDIRQEN; -+ else -+ end_des_virtual->dcmd &= ~DCMD_ENDIRQEN; -+ -+ end_des_virtual += cam_ctx->fifo0_num_descriptors; -+ } -+} -+ -+// get interrupt mask -+unsigned int camera_get_int_mask(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *end_des_virtual; -+ unsigned int ret; -+ -+ // get CI mask -+ ret = ci_get_int_mask(); -+ -+ // get dma end mask -+ end_des_virtual = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + cam_ctx->fifo0_num_descriptors - 1; -+ -+ if(end_des_virtual->dcmd & DCMD_ENDIRQEN) -+ { -+ ret |= CAMERA_INTMASK_END_OF_DMA; -+ } -+ return ret; -+} -+ -+// clear interrupt status -+void camera_clear_int_status( p_camera_context_t camera_context, unsigned int status ) -+{ -+ ci_clear_int_status( (status & 0xFFFF) ); -+} -+ -+static void camera_free_dma_irq() -+{ -+ if(ci_dma_y>=0) -+ { -+ pxa_free_dma(ci_dma_y); -+ ci_dma_y = 0; -+ } -+ if(ci_dma_cb>=0) -+ { -+ pxa_free_dma(ci_dma_cb); -+ ci_dma_cb = 0; -+ } -+ if(ci_dma_cr>=0) -+ { -+ pxa_free_dma(ci_dma_cr); -+ ci_dma_cr = 0; -+ } -+ DRCMR68 = 0; -+ DRCMR69 = 0; -+ DRCMR70 = 0; -+} -+/*********************************************************************************** -+* Application interface * -+***********************************************************************************/ -+//static int pxa_camera_open(struct video_device *dev, int flags) -+static int pxa_camera_open(struct inode *inode, struct file *file) -+{ -+ unsigned int minor = iminor(inode); -+ camera_context_t *cam_ctx; -+ dbg_print("start..."); -+ /* -+ According to Peter's suggestion, move the code of request camera IRQ and DMQ channel to here -+ */ -+ /* 1. mapping CI registers, so that we can access the CI */ -+ -+ ci_dma_y = pxa_request_dma("CI_Y",DMA_PRIO_HIGH, pxa_ci_dma_irq_y, &vd); -+ if(ci_dma_y < 0) -+ { -+ camera_free_dma_irq(); -+ dbg_print( "PXA_CAMERA: Cann't request DMA for Y\n"); -+ return -EIO; -+ } -+ dbg_print( "PXA_CAMERA: Request DMA for Y successfully [%d]\n",ci_dma_y); -+ -+ ci_dma_cb = pxa_request_dma("CI_Cb",DMA_PRIO_HIGH, pxa_ci_dma_irq_cb, &vd); -+ if(ci_dma_cb < 0) -+ { -+ camera_free_dma_irq(); -+ dbg_print( "PXA_CAMERA: Cann't request DMA for Cb\n"); -+ return -EIO; -+ } -+ dbg_print( "PXA_CAMERA: Request DMA for Cb successfully [%d]\n",ci_dma_cb); -+ -+ ci_dma_cr = pxa_request_dma("CI_Cr",DMA_PRIO_HIGH, pxa_ci_dma_irq_cr, &vd); -+ if(ci_dma_cr < 0) -+ { -+ camera_free_dma_irq(); -+ dbg_print( "PXA_CAMERA: Cann't request DMA for Cr\n"); -+ return -EIO; -+ } -+ -+ dbg_print( "PXA_CAMERA: Request DMA for Cr successfully [%d]\n",ci_dma_cr); -+ -+ DRCMR68 = ci_dma_y | DRCMR_MAPVLD; -+ DRCMR69 = ci_dma_cb | DRCMR_MAPVLD; -+ DRCMR70 = ci_dma_cr | DRCMR_MAPVLD; -+ -+ -+ init_waitqueue_head(&camera_wait_q); -+ -+ /*alloc memory for camera context*/ -+ if(pxa_camera_mem_init()) -+ { -+ camera_free_dma_irq(); -+ dbg_print("memory allocate failed!"); -+ return -1; -+ } -+ -+ cam_ctx = g_camera_context; -+ -+ /* -+ camera_init call init function for E680 -+ */ -+ if(camera_init(cam_ctx)) -+ { -+ dbg_print("camera_init faile!"); -+ camera_free_dma_irq(); -+ pxa_camera_mem_deinit(); -+ return -1; -+ } -+ -+ /* -+ allocate memory for dma descriptors -+ init function of each sensor should set proper value for cam_ctx->buf_size -+ */ -+ cam_ctx->dma_started = 0; -+ cam_ctx->dma_descriptors_virtual = consistent_alloc(GFP_KERNEL, -+ (cam_ctx->dma_descriptors_size) * sizeof(pxa_dma_desc), -+ (void *)&(cam_ctx->dma_descriptors_physical)); -+ if(cam_ctx->dma_descriptors_virtual == NULL) -+ { -+ dbg_print("consistent alloc memory for dma_descriptors_virtual fail!"); -+ camera_free_dma_irq(); -+ pxa_camera_mem_deinit(); -+ return -1; -+ } -+ -+ -+ /* -+ alloc memory for picture buffer -+ init function of each sensor should set proper value for cam_ctx->buf_size -+ */ -+ if(pxa_dma_buffer_init(cam_ctx) != 0) -+ { -+ dbg_print("alloc memory for buffer_virtual %d bytes fail!", g_camera_context->buf_size); -+ camera_free_dma_irq(); -+ pxa_camera_mem_deinit(); -+ return -1; -+ } -+ -+ /* -+ set default size and capture format -+ init function of each sensor should set proper value -+ for capture_width, capture_height, etc. of camera context -+ */ -+ if(camera_set_capture_format(cam_ctx) != 0) -+ { -+ dbg_print("camera function init error! capture format!"); -+ camera_free_dma_irq(); -+ pxa_camera_mem_deinit(); -+ return -1; -+ } -+ dbg_print("PXA_CAMERA: pxa_camera_open success!"); -+ return 0; -+} -+ -+//static void pxa_camera_close(struct video_device *dev) -+static int pxa_camera_close(struct inode *inode, struct file *file) -+{ -+ camera_deinit(g_camera_context); -+ pxa_camera_mem_deinit(); -+ camera_free_dma_irq(); -+ dbg_print("PXA_CAMERA: pxa_camera_close\n"); -+} -+ -+#define PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, size) \ -+do { \ -+ unsigned int len; \ -+ unsigned int remain_size = size; \ -+ while (remain_size > 0) { \ -+ if(remain_size > PAGE_SIZE) \ -+ len = PAGE_SIZE; \ -+ else \ -+ len = remain_size; \ -+ if(copy_to_user(buf, page_address(*p_page), len)) \ -+ return -EFAULT; \ -+ remain_size -= len; \ -+ buf += len; \ -+ p_page++; \ -+ } \ -+} while (0); -+ -+static ssize_t pxa_camera_write(struct file *file, const char __user *data, -+ size_t count, loff_t *ppos) -+{ -+ return -EINVAL; -+} -+ -+static ssize_t pxa_camera_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ -+ struct page **p_page; -+ -+ camera_context_t *cam_ctx = g_camera_context; -+ -+ if(still_image_mode == 1 && still_image_rdy == 1) -+ { -+ p_page = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo0_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo1_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo2_transfer_size); -+ -+ still_image_rdy = 0; -+ return cam_ctx->block_size; -+ } -+ -+ if(still_image_mode == 0) -+ { -+ if(first_video_frame == 1) -+ cam_ctx->block_tail = cam_ctx->block_header; -+ else -+ cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number; -+ } -+ -+ first_video_frame = 0; -+ -+ if(cam_ctx->block_header == cam_ctx->block_tail) -+ { -+ task_waiting = 1; -+ interruptible_sleep_on (&camera_wait_q); -+ } -+ -+ p_page = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo0_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo1_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo2_transfer_size); -+ -+ return cam_ctx->block_size; -+} -+ -+struct reg_set_s -+{ -+ int val1; -+ int val2; -+}; -+ -+/*ioctl sub functions*/ -+static int pxa_camera_VIDIOCGCAP(p_camera_context_t cam_ctx, void * param) -+{ -+ dbg_print("VIDIOCGCAP"); -+ /* -+ add a vc member to camera context -+ */ -+ if(copy_to_user(param, &(cam_ctx->vc), sizeof(struct video_capability))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+static int pxa_camera_VIDIOCGWIN(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_window vw; -+ dbg_print("VIDIOCGWIN"); -+ vw.width = cam_ctx->capture_width; -+ vw.height = cam_ctx->capture_height; -+ if(copy_to_user(param, &vw, sizeof(struct video_window))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+static int pxa_camera_VIDIOCSWIN(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_window vw; -+ dbg_print("VIDIOCSWIN"); -+ if(copy_from_user(&vw, param, sizeof(vw))) -+ { -+ dbg_print("VIDIOCSWIN get parameter error!"); -+ return -EFAULT; -+ } -+ -+ if(vw.width > cam_ctx->vc.maxwidth || -+ vw.height > cam_ctx->vc.maxheight || -+ vw.width < cam_ctx->vc.minwidth || -+ vw.height < cam_ctx->vc.minheight) -+ { -+ dbg_print("VIDIOCSWIN error parameter!"); -+ dbg_print("vw.width:%d, MAX_WIDTH:%d, MIN_WIDTH:%d", vw.width, cam_ctx->vc.maxwidth, cam_ctx->vc.minwidth); -+ dbg_print("vw.height:%d, MAX_HEIGHT:%d, MIN_HEIGHT:%d", vw.width, cam_ctx->vc.maxheight, cam_ctx->vc.minheight); -+ return -EFAULT; -+ } -+ -+ //make it in an even multiple of 8 -+ -+ cam_ctx->capture_width = (vw.width+7)/8; -+ cam_ctx->capture_width *= 8; -+ -+ cam_ctx->capture_height = (vw.height+7)/8; -+ cam_ctx->capture_height *= 8; -+ -+ return camera_set_capture_format(cam_ctx); -+} -+static int pxa_camera_VIDIOCSPICT(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_picture vp; -+ dbg_print("VIDIOCSPICT"); -+ if(copy_from_user(&vp, param, sizeof(vp))) -+ { -+ return -EFAULT; -+ } -+ cam_ctx->capture_output_format = vp.palette; -+ -+ return camera_set_capture_format(cam_ctx); -+ -+} -+ -+static int pxa_camera_VIDIOCGPICT(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_picture vp; -+ dbg_print("VIDIOCGPICT"); -+ vp.palette = cam_ctx->capture_output_format; -+ if(copy_to_user(param, &vp, sizeof(struct video_picture))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static int pxa_camera_VIDIOCCAPTURE(p_camera_context_t cam_ctx, void * param) -+{ -+ int capture_flag = (int)param; -+ dbg_print("VIDIOCCAPTURE"); -+ if(capture_flag > 0) -+ { -+ dbg_print("Still Image capture!"); -+ camera_capture_still_image(cam_ctx, 0); -+ } -+ else if(capture_flag == 0) -+ { -+ dbg_print("Video Image capture!"); -+ camera_start_video_capture(cam_ctx, 0); -+ } -+ else if(capture_flag == -1) -+ { -+ dbg_print("Capture stop!"); -+ camera_set_int_mask(cam_ctx, 0x3ff); -+ camera_stop_video_capture(cam_ctx); -+ } -+ else -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static int pxa_camera_VIDIOCGMBUF(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_mbuf vm; -+ int i; -+ -+ dbg_print("VIDIOCGMBUF"); -+ -+ memset(&vm, 0, sizeof(vm)); -+ vm.size = cam_ctx->buf_size; -+ vm.frames = cam_ctx->block_number; -+ for(i = 0; i < vm.frames; i++) -+ { -+ vm.offsets[i] = cam_ctx->page_aligned_block_size * i; -+ } -+ if(copy_to_user((void *)param, (void *)&vm, sizeof(vm))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+static int pxa_camera_WCAM_VIDIOCSINFOR(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ struct reg_set_s reg_s; -+ int ret; -+ dbg_print("WCAM_VIDIOCSINFOR"); -+ -+ if(copy_from_user(®_s, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ -+ cam_ctx->capture_input_format = reg_s.val1; -+ cam_ctx->capture_output_format = reg_s.val2; -+ ret=camera_set_capture_format(cam_ctx); -+ return ret; -+} -+static int pxa_camera_WCAM_VIDIOCGINFOR(p_camera_context_t cam_ctx, void * param) -+{ -+ struct reg_set_s reg_s; -+ dbg_print("WCAM_VIDIOCGINFOR"); -+ reg_s.val1 = cam_ctx->capture_input_format; -+ reg_s.val2 = cam_ctx->capture_output_format; -+ if(copy_to_user(param, ®_s, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+static int pxa_camera_WCAM_VIDIOCGCIREG(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ int reg_value, offset; -+ dbg_print("WCAM_VIDIOCGCIREG"); -+ if(copy_from_user(&offset, param, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ reg_value = ci_get_reg_value (offset); -+ if(copy_to_user(param, ®_value, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static int pxa_camera_WCAM_VIDIOCSCIREG(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ struct reg_set_s reg_s; -+ dbg_print("WCAM_VIDIOCSCIREG"); -+ if(copy_from_user(®_s, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ ci_set_reg_value (reg_s.val1, reg_s.val2); -+ return 0; -+ -+} -+ -+/*get sensor size */ -+static int pxa_cam_WCAM_VIDIOCGSSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ struct adcm_window_size{u16 width, height;} size; -+ dbg_print("WCAM_VIDIOCGSSIZE"); -+ size.width = cam_ctx->sensor_width; -+ size.height = cam_ctx->sensor_height; -+ -+ if(copy_to_user(param, &size, sizeof(struct adcm_window_size))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+/*get output size*/ -+static int pxa_cam_WCAM_VIDIOCGOSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ struct adcm_window_size{u16 width, height;}size; -+ dbg_print("WCAM_VIDIOCGOSIZE"); -+ size.width = cam_ctx->capture_width; -+ size.height = cam_ctx->capture_height; -+ if(copy_to_user(param, &size, sizeof(struct adcm_window_size))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+ -+ -+/*set frame buffer count*/ -+static int pxa_cam_WCAM_VIDIOCSBUFCOUNT(p_camera_context_t cam_ctx, void * param) -+{ -+ int count; -+ dbg_print(""); -+ if (copy_from_user(&count, param, sizeof(int))) -+ return -EFAULT; -+ -+ if(cam_ctx->block_number_max == 0) { -+ dbg_print("windows size or format not setting!!"); -+ return -EFAULT; -+ } -+ -+ if(count < FRAMES_IN_BUFFER) -+ { -+ count = FRAMES_IN_BUFFER; -+ } -+ -+ if(count > cam_ctx->block_number_max) -+ { -+ count = cam_ctx->block_number_max; -+ } -+ -+ -+ cam_ctx->block_number = count; -+ cam_ctx->block_header = cam_ctx->block_tail = 0; -+ //generate dma descriptor chain -+ update_dma_chain(cam_ctx); -+ -+ if(copy_to_user(param, &count, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*get cur avaliable frames*/ -+static int pxa_cam_WCAM_VIDIOCGCURFRMS(p_camera_context_t cam_ctx, void * param) -+{ -+ //dbg_print(""); -+ struct {int first, last;}pos; -+ -+ pos.first = cam_ctx->block_tail; -+ pos.last = cam_ctx->block_header; -+ -+ if(copy_to_user(param, &pos, sizeof(pos))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+/*get sensor type*/ -+static int pxa_cam_WCAM_VIDIOCGSTYPE(p_camera_context_t cam_ctx, void * param) -+{ -+ dbg_print(""); -+ if(copy_to_user(param, &(cam_ctx->sensor_type), sizeof(cam_ctx->sensor_type))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static int pxa_camera_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ void *param = (void *) arg; -+ -+ switch (cmd) -+ { -+ /*get capture capability*/ -+ case VIDIOCGCAP: -+ return pxa_camera_VIDIOCGCAP(g_camera_context, param); -+ /* get capture size */ -+ case VIDIOCGWIN: -+ return pxa_camera_VIDIOCGWIN(g_camera_context, param); -+ -+ /* set capture size. */ -+ case VIDIOCSWIN: -+ return pxa_camera_VIDIOCSWIN(g_camera_context, param); -+ /*set capture output format*/ -+ case VIDIOCSPICT: -+ return pxa_camera_VIDIOCSPICT(g_camera_context, param); -+ -+ /*get capture output format*/ -+ case VIDIOCGPICT: -+ return pxa_camera_VIDIOCGPICT(g_camera_context, param); -+ -+ /*start capture */ -+ case VIDIOCCAPTURE: -+ return pxa_camera_VIDIOCCAPTURE(g_camera_context, param); -+ -+ /* mmap interface */ -+ case VIDIOCGMBUF: -+ return pxa_camera_VIDIOCGMBUF(g_camera_context, param); -+ -+ /* Application extended IOCTL. */ -+ /* Register access interface */ -+ case WCAM_VIDIOCSINFOR: -+ return pxa_camera_WCAM_VIDIOCSINFOR(g_camera_context, param); -+ -+ /*get capture format*/ -+ case WCAM_VIDIOCGINFOR: -+ return pxa_camera_WCAM_VIDIOCGINFOR(g_camera_context, param); -+ -+ /*get ci reg value*/ -+ case WCAM_VIDIOCGCIREG: -+ return pxa_camera_WCAM_VIDIOCGCIREG(g_camera_context, param); -+ -+ /*set ci reg*/ -+ case WCAM_VIDIOCSCIREG: -+ return pxa_camera_WCAM_VIDIOCSCIREG(g_camera_context, param); -+ -+ /*get sensor size */ -+ case WCAM_VIDIOCGSSIZE: -+ return pxa_cam_WCAM_VIDIOCGSSIZE(g_camera_context, param); -+ -+ /*get output size*/ -+ case WCAM_VIDIOCGOSIZE: -+ return pxa_cam_WCAM_VIDIOCGOSIZE(g_camera_context, param); -+ -+ /*set frame buffer count*/ -+ case WCAM_VIDIOCSBUFCOUNT: -+ return pxa_cam_WCAM_VIDIOCSBUFCOUNT(g_camera_context, param); -+ -+ /*get cur avaliable frames*/ -+ case WCAM_VIDIOCGCURFRMS: -+ return pxa_cam_WCAM_VIDIOCGCURFRMS(g_camera_context, param); -+ -+ /*get cur sensor type*/ -+ case WCAM_VIDIOCGSTYPE: -+ return pxa_cam_WCAM_VIDIOCGSTYPE(g_camera_context, param); -+ -+ default: -+ return g_camera_context->camera_functions->command(g_camera_context, cmd, param); -+ } -+ -+ return 0; -+} -+ -+//static int pxa_camera_mmap(struct video_device *dev, const char *adr, unsigned long size) -+static int pxa_camera_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ unsigned long start = vma->vm_start; -+ unsigned long size = (vma->vm_end - vma->vm_start); -+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -+ camera_context_t *cam_ctx = g_camera_context; -+ struct page **p_page = cam_ctx->page_array; -+ -+ size = PAGE_ALIGN(size); -+ if (remap_pfn_range(vma, start, page_to_phys(*p_page), size, -+ PAGE_SHARED)) { -+ return -EFAULT; -+ } -+ return 0; -+ } -+ -+static unsigned int pxa_camera_poll(struct file *file, poll_table *wait) -+{ -+ static int waited = 0; -+ camera_context_t *cam_ctx = g_camera_context; -+ -+ poll_wait(file, &camera_wait_q, wait); -+ -+ if(still_image_mode == 1 && still_image_rdy == 1) -+ { -+ still_image_rdy = 0; -+ waited = 0; -+ return POLLIN | POLLRDNORM; -+ } -+ -+ if(first_video_frame == 1) -+ { -+ first_video_frame = 0; -+ } -+ else if(still_image_mode == 0 && waited != 1) -+ { -+ cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number; -+ } -+ -+ if(cam_ctx->block_header == cam_ctx->block_tail) -+ { -+ task_waiting = 1; -+ waited = 1; -+ return 0; -+ } -+ waited = 0; -+ return POLLIN | POLLRDNORM; -+} -+ -+int pxa_camera_mem_deinit(void) -+{ -+ if(g_camera_context) -+ { -+ if(g_camera_context->dma_descriptors_virtual != NULL) -+ { -+ consistent_free(g_camera_context->dma_descriptors_virtual, -+ g_camera_context->dma_descriptors_size * sizeof(pxa_dma_desc), -+ (int)g_camera_context->dma_descriptors_physical); -+ -+ g_camera_context->dma_descriptors_virtual = NULL; -+ -+ } -+ if(g_camera_context->buffer_virtual != NULL) -+ { -+ pxa_dma_buffer_free(g_camera_context); -+ g_camera_context->buffer_virtual = NULL; -+ } -+ kfree(g_camera_context); -+ g_camera_context = NULL; -+ } -+ -+ return 0; -+} -+ -+int pxa_camera_mem_init(void) -+{ -+ g_camera_context = kmalloc(sizeof(struct camera_context_s), GFP_KERNEL); -+ -+ if(g_camera_context == NULL) -+ { -+ dbg_print( "PXA_CAMERA: Cann't allocate buffer for camera control structure \n"); -+ return -1; -+ } -+ -+ memset(g_camera_context, 0, sizeof(struct camera_context_s)); -+ -+ dbg_print("success!"); -+ return 0; -+} -+ -+int pxa_camera_video_init(struct video_device *vdev) -+{ -+ return 0; -+} -+ -+ -+static int __init pxa_camera_init(void) -+{ -+ camera_context_t cam_ctx; -+ -+ if (request_irq(IRQ_CAMERA, pxa_camera_irq, 0, "PXA Camera", &vd)) { -+ dbg_print("Camera interrupt register failed failed number \n"); -+ return -EIO; -+ } -+ dbg_print ("Camera interrupt register successful \n"); -+ -+ minor =0 ; -+ -+ if(video_register_device(&vd, VFL_TYPE_GRABBER, minor) < 0) -+ { -+ dbg_print("PXA_CAMERA: video_register_device failed\n"); -+ return -EIO; -+ } -+#ifdef CONFIG_ARCH_EZX_A780 -+ PGSR1 |= GPIO_bit(50); -+ PGSR0 |= GPIO_bit(19); -+#endif -+ -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, camera_pm_callback); -+#endif -+ -+ dbg_print("PXA_CAMERA: video_register_device successfully. /dev/video%d \n",minor); -+ -+ return 0; -+} -+ -+static void __exit pxa_camera_exit(void) -+{ -+ free_irq(IRQ_CAMERA, &vd); -+ -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+ -+ video_unregister_device(&vd); -+ -+} -+ -+ -+//------------------------------------------------------------------------------------------------------- -+// Configuration APIs -+//------------------------------------------------------------------------------------------------------- -+void ci_set_frame_rate(CI_FRAME_CAPTURE_RATE frate) -+{ -+ unsigned int value; -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_FR_RATE_SMASK << CI_CICR4_FR_RATE_SHIFT); -+ value |= (unsigned)frate << CI_CICR4_FR_RATE_SHIFT; -+ CICR4 = value; -+} -+ -+CI_FRAME_CAPTURE_RATE ci_get_frame_rate(void) -+{ -+ unsigned int value; -+ value = CICR4; -+ return (CI_FRAME_CAPTURE_RATE)((value >> CI_CICR4_FR_RATE_SHIFT) & CI_CICR4_FR_RATE_SMASK); -+} -+ -+void ci_set_image_format(CI_IMAGE_FORMAT input_format, CI_IMAGE_FORMAT output_format) -+{ -+ -+ unsigned int value, tbit, rgbt_conv, rgb_conv, rgb_f, ycbcr_f, rgb_bpp, raw_bpp, cspace; -+ // write cicr1: preserve ppl value and data width value -+ dbg_print("0"); -+ value = CICR1; -+ dbg_print("1"); -+ value &= ( (CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT) | ((CI_CICR1_DW_SMASK) << CI_CICR1_DW_SHIFT)); -+ tbit = rgbt_conv = rgb_conv = rgb_f = ycbcr_f = rgb_bpp = raw_bpp = cspace = 0; -+ switch(input_format) -+ { -+ case CI_RAW8: -+ cspace = 0; -+ raw_bpp = 0; -+ break; -+ case CI_RAW9: -+ cspace = 0; -+ raw_bpp = 1; -+ break; -+ case CI_RAW10: -+ cspace = 0; -+ raw_bpp = 2; -+ break; -+ case CI_YCBCR422: -+ case CI_YCBCR422_PLANAR: -+ cspace = 2; -+ if(output_format == CI_YCBCR422_PLANAR) -+ { -+ ycbcr_f = 1; -+ } -+ break; -+ case CI_RGB444: -+ cspace = 1; -+ rgb_bpp = 0; -+ break; -+ case CI_RGB555: -+ cspace = 1; -+ rgb_bpp = 1; -+ if(output_format == CI_RGBT555_0) -+ { -+ rgbt_conv = 2; -+ tbit = 0; -+ } -+ else if(output_format == CI_RGBT555_1) -+ { -+ rgbt_conv = 2; -+ tbit = 1; -+ } -+ break; -+ case CI_RGB565: -+ cspace = 1; -+ rgb_bpp = 2; -+ rgb_f = 1; -+ break; -+ case CI_RGB666: -+ cspace = 1; -+ rgb_bpp = 3; -+ if(output_format == CI_RGB666_PACKED) -+ { -+ rgb_f = 1; -+ } -+ break; -+ case CI_RGB888: -+ case CI_RGB888_PACKED: -+ cspace = 1; -+ rgb_bpp = 4; -+ switch(output_format) -+ { -+ case CI_RGB888_PACKED: -+ rgb_f = 1; -+ break; -+ case CI_RGBT888_0: -+ rgbt_conv = 1; -+ tbit = 0; -+ break; -+ case CI_RGBT888_1: -+ rgbt_conv = 1; -+ tbit = 1; -+ break; -+ case CI_RGB666: -+ rgb_conv = 1; -+ break; -+ // RGB666 PACKED - JamesL -+ case CI_RGB666_PACKED: -+ rgb_conv = 1; -+ rgb_f = 1; -+ break; -+ // end -+ case CI_RGB565: -+ dbg_print("format : 565"); -+ rgb_conv = 2; -+ break; -+ case CI_RGB555: -+ rgb_conv = 3; -+ break; -+ case CI_RGB444: -+ rgb_conv = 4; -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ dbg_print("2"); -+ value |= (tbit==1) ? CI_CICR1_TBIT : 0; -+ value |= rgbt_conv << CI_CICR1_RGBT_CONV_SHIFT; -+ value |= rgb_conv << CI_CICR1_RGB_CONV_SHIFT; -+ value |= (rgb_f==1) ? CI_CICR1_RBG_F : 0; -+ value |= (ycbcr_f==1) ? CI_CICR1_YCBCR_F : 0; -+ value |= rgb_bpp << CI_CICR1_RGB_BPP_SHIFT; -+ value |= raw_bpp << CI_CICR1_RAW_BPP_SHIFT; -+ value |= cspace << CI_CICR1_COLOR_SP_SHIFT; -+ CICR1 = value; -+ -+} -+ -+void ci_set_mode(CI_MODE mode, CI_DATA_WIDTH data_width) -+{ -+ unsigned int value; -+ -+ // write mode field in cicr0 -+ value = CICR0; -+ value &= ~(CI_CICR0_SIM_SMASK << CI_CICR0_SIM_SHIFT); -+ value |= (unsigned int)mode << CI_CICR0_SIM_SHIFT; -+ CICR0 = value; -+ -+ // write data width cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_DW_SMASK << CI_CICR1_DW_SHIFT); -+ value |= ((unsigned)data_width) << CI_CICR1_DW_SHIFT; -+ CICR1 = value; -+ return; -+} -+ -+void ci_configure_mp(unsigned int ppl, unsigned int lpf, CI_MP_TIMING* timing) -+{ -+ unsigned int value; -+ // write ppl field in cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT); -+ value |= (ppl & CI_CICR1_PPL_SMASK) << CI_CICR1_PPL_SHIFT; -+ CICR1 = value; -+ -+ // write BLW, ELW in cicr2 -+ value = CICR2; -+ value &= ~(CI_CICR2_BLW_SMASK << CI_CICR2_BLW_SHIFT | CI_CICR2_ELW_SMASK << CI_CICR2_ELW_SHIFT ); -+ value |= (timing->BLW & CI_CICR2_BLW_SMASK) << CI_CICR2_BLW_SHIFT; -+ CICR2 = value; -+ -+ // write BFW, LPF in cicr3 -+ value = CICR3; -+ value &= ~(CI_CICR3_BFW_SMASK << CI_CICR3_BFW_SHIFT | CI_CICR3_LPF_SMASK << CI_CICR3_LPF_SHIFT ); -+ value |= (timing->BFW & CI_CICR3_BFW_SMASK) << CI_CICR3_BFW_SHIFT; -+ value |= (lpf & CI_CICR3_LPF_SMASK) << CI_CICR3_LPF_SHIFT; -+ CICR3 = value; -+ -+} -+ -+void ci_configure_sp(unsigned int ppl, unsigned int lpf, CI_SP_TIMING* timing) -+{ -+ unsigned int value; -+ -+ // write ppl field in cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT); -+ value |= (ppl & CI_CICR1_PPL_SMASK) << CI_CICR1_PPL_SHIFT; -+ CICR1 = value; -+ -+ // write cicr2 -+ value = CICR2; -+ value |= (timing->BLW & CI_CICR2_BLW_SMASK) << CI_CICR2_BLW_SHIFT; -+ value |= (timing->ELW & CI_CICR2_ELW_SMASK) << CI_CICR2_ELW_SHIFT; -+ value |= (timing->HSW & CI_CICR2_HSW_SMASK) << CI_CICR2_HSW_SHIFT; -+ value |= (timing->BFPW & CI_CICR2_BFPW_SMASK) << CI_CICR2_BFPW_SHIFT; -+ value |= (timing->FSW & CI_CICR2_FSW_SMASK) << CI_CICR2_FSW_SHIFT; -+ CICR2 = value; -+ -+ // write cicr3 -+ value = CICR3; -+ value |= (timing->BFW & CI_CICR3_BFW_SMASK) << CI_CICR3_BFW_SHIFT; -+ value |= (timing->EFW & CI_CICR3_EFW_SMASK) << CI_CICR3_EFW_SHIFT; -+ value |= (timing->VSW & CI_CICR3_VSW_SMASK) << CI_CICR3_VSW_SHIFT; -+ value |= (lpf & CI_CICR3_LPF_SMASK) << CI_CICR3_LPF_SHIFT; -+ CICR3 = value; -+ return; -+} -+ -+void ci_configure_ms(unsigned int ppl, unsigned int lpf, CI_MS_TIMING* timing) -+{ -+ // the operation is same as Master-Parallel -+ ci_configure_mp(ppl, lpf, (CI_MP_TIMING*)timing); -+} -+ -+void ci_configure_ep(int parity_check) -+{ -+ unsigned int value; -+ -+ // write parity_enable field in cicr0 -+ value = CICR0; -+ if(parity_check) -+ { -+ value |= CI_CICR0_PAR_EN; -+ } -+ else -+ { -+ value &= ~CI_CICR0_PAR_EN; -+ } -+ CICR0 = value; -+ return; -+} -+ -+void ci_configure_es(int parity_check) -+{ -+ // the operationi is same as Embedded-Parallel -+ ci_configure_ep(parity_check); -+} -+ -+void ci_set_clock(unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz) -+{ -+ unsigned int ciclk, value, div, cccr_l, K; -+ -+ // determine the LCLK frequency programmed into the CCCR. -+ cccr_l = (CCCR & 0x0000001F); -+ -+ if(cccr_l < 8) -+ K = 1; -+ else if(cccr_l < 17) -+ K = 2; -+ else -+ K = 3; -+ -+ ciclk = (13 * cccr_l) / K; -+ -+ div = (ciclk + mclk_khz) / ( 2 * mclk_khz ) - 1; -+ dbg_print("cccr=%xciclk=%d,cccr_l=%d,K=%d,div=%d,mclk=%d\n",CCCR,ciclk,cccr_l,K,div,mclk_khz); -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | CI_CICR4_DIV_SMASK<<CI_CICR4_DIV_SHIFT); -+ value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0; -+ value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0; -+ value |= div << CI_CICR4_DIV_SHIFT; -+ CICR4 = value; -+ return; -+} -+ -+void ci_set_polarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low) -+{ -+ unsigned int value; -+ dbg_print(""); -+ -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_PCP | CI_CICR4_HSP | CI_CICR4_VSP); -+ value |= (pclk_sample_falling)? CI_CICR4_PCP : 0; -+ value |= (hsync_active_low) ? CI_CICR4_HSP : 0; -+ value |= (vsync_active_low) ? CI_CICR4_VSP : 0; -+ CICR4 = value; -+ return; -+} -+ -+void ci_set_fifo(unsigned int timeout, CI_FIFO_THRESHOLD threshold, int fifo1_enable, -+ int fifo2_enable) -+{ -+ unsigned int value; -+ dbg_print(""); -+ // write citor -+ CITOR = timeout; -+ -+ // write cifr: always enable fifo 0! also reset input fifo -+ value = CIFR; -+ value &= ~(CI_CIFR_FEN0 | CI_CIFR_FEN1 | CI_CIFR_FEN2 | CI_CIFR_RESETF | -+ CI_CIFR_THL_0_SMASK<<CI_CIFR_THL_0_SHIFT); -+ value |= (unsigned int)threshold << CI_CIFR_THL_0_SHIFT; -+ value |= (fifo1_enable) ? CI_CIFR_FEN1 : 0; -+ value |= (fifo2_enable) ? CI_CIFR_FEN2 : 0; -+ value |= CI_CIFR_RESETF | CI_CIFR_FEN0; -+ CIFR = value; -+} -+ -+void ci_reset_fifo() -+{ -+ unsigned int value; -+ value = CIFR; -+ value |= CI_CIFR_RESETF; -+ CIFR = value; -+} -+ -+void ci_set_int_mask(unsigned int mask) -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value &= ~CI_CICR0_INTERRUPT_MASK; -+ value |= (mask & CI_CICR0_INTERRUPT_MASK); -+ dbg_print("-----------value=0x%x\n",value); -+ CICR0 = value; -+ return; -+} -+ -+unsigned int ci_get_int_mask() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ return (value & CI_CICR0_INTERRUPT_MASK); -+} -+ -+void ci_clear_int_status(unsigned int status) -+{ -+ // write 1 to clear -+ CISR = status; -+} -+ -+unsigned int ci_get_int_status() -+{ -+ int value; -+ -+ value = CISR; -+ -+ return value; -+} -+ -+void ci_set_reg_value(unsigned int reg_offset, unsigned int value) -+{ -+ switch(reg_offset) -+ { -+ case 0: -+ CICR0 = value; -+ break; -+ case 1: -+ CICR1 = value; -+ break; -+ case 2: -+ CICR2 = value; -+ break; -+ case 3: -+ CICR3 = value; -+ break; -+ case 4: -+ CICR4 = value; -+ break; -+ case 5: -+ CISR = value; -+ break; -+ case 6: -+ CIFR = value; -+ break; -+ case 7: -+ CITOR = value; -+ break; -+ } -+} -+ -+int ci_get_reg_value(unsigned int reg_offset) -+{ -+ -+ unsigned values[] = {CICR0, CICR1, CICR2, CICR3, CICR4, CISR, CIFR, CITOR}; -+ -+ if(reg_offset >=0 && reg_offset <= 7) -+ return values[reg_offset]; -+ else -+ return CISR; -+} -+ -+//------------------------------------------------------------------------------------------------------- -+// Control APIs -+//------------------------------------------------------------------------------------------------------- -+int ci_init() -+{ -+ -+ // clear all CI registers disable all interrupts -+ CICR0 = 0x3FF; -+ CICR1 = 0; -+ CICR2 = 0; -+ CICR3 = 0; -+ CICR4 = 0; -+ CISR = ~0; -+ CIFR = 0; -+ CITOR = 0; -+ -+ // enable CI clock -+ CKEN |= CKEN24_CAMERA; -+ return 0; -+} -+ -+void ci_deinit() -+{ -+ // disable CI clock -+ CICR4 = 0; -+ mdelay(1); -+ CKEN &= ~CKEN24_CAMERA; -+} -+void ci_reset() -+{ -+ ci_disable(1); -+ ci_enable(1); -+ mdelay(30); -+} -+void ci_enable(int dma_en) -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value |= CI_CICR0_ENB; -+ if(dma_en) { -+ value |= CI_CICR0_DMA_EN; -+ } -+ CICR0 = value; -+ return; -+} -+ -+int ci_disable(int quick) -+{ -+ volatile unsigned int value, mask; -+ int retry; -+ -+ // write control bit in cicr0 -+ value = CICR0; -+ if(quick) -+ { -+ value &= ~CI_CICR0_ENB; -+ mask = CI_CISR_CQD; -+ } -+ else -+ { -+ value |= CI_CICR0_DIS; -+ mask = CI_CISR_CDD; -+ } -+ CICR0 = value; -+ -+ // wait shutdown complete -+ retry = 50; -+ while ( retry-- > 0 ) -+ { -+ value = CISR; -+ if( value & mask ) -+ { -+ CISR = mask; -+ return 0; -+ } -+ mdelay(10); -+ } -+ return -1; -+} -+ -+void ci_slave_capture_enable() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value |= CI_CICR0_SL_CAP_EN; -+ CICR0 = value; -+ return; -+} -+ -+void ci_slave_capture_disable() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value &= ~CI_CICR0_SL_CAP_EN; -+ CICR0 = value; -+ return; -+} -+ -+void pxa_ci_dma_irq_y(int channel, void *data, struct pt_regs *regs) -+{ -+ -+ static int dma_repeated = 0; -+ camera_context_t *cam_ctx = g_camera_context; -+ int dcsr; -+ -+ dcsr = DCSR(channel); -+ DCSR(channel) = dcsr & ~DCSR_STOPIRQEN; -+ -+ if(still_image_mode == 1) -+ { -+ if(task_waiting == 1) -+ { -+ wake_up_interruptible (&camera_wait_q); -+ task_waiting = 0; -+ } -+ still_image_rdy = 1; -+ stop_dma_transfer(cam_ctx); -+ } -+ else if(dma_repeated == 0 && -+ (cam_ctx->block_tail == ((cam_ctx->block_header + 2) % cam_ctx->block_number))) -+ { -+ dma_repeated = 1; -+ pxa_dma_repeat(cam_ctx); -+ //dbg_print ("DMA repeated."); -+ cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ } -+ else if(dma_repeated == 1 && -+ (cam_ctx->block_tail != ((cam_ctx->block_header + 1) % cam_ctx->block_number)) && -+ (cam_ctx->block_tail != ((cam_ctx->block_header + 2) % cam_ctx->block_number))) -+ { -+ pxa_dma_continue(cam_ctx); -+ //dbg_print ("DMA continue."); -+ dma_repeated = 0; -+ } -+ else if(dma_repeated == 0) -+ { -+ cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ } -+ -+ if(task_waiting == 1 && !(cam_ctx->block_header == cam_ctx->block_tail)) -+ { -+ wake_up_interruptible (&camera_wait_q); -+ task_waiting = 0; -+ } -+ -+} -+ -+void pxa_ci_dma_irq_cb(int channel, void *data, struct pt_regs *regs) -+{ -+ return; -+} -+ -+void pxa_ci_dma_irq_cr(int channel, void *data, struct pt_regs *regs) -+{ -+ return; -+} -+ -+ -+static irqreturn_t pxa_camera_irq(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ unsigned int cisr; -+ -+ disable_irq(IRQ_CAMERA); -+ cisr = CISR; -+ -+ if (cisr & CI_CISR_SOF) -+ CISR |= CI_CISR_SOF; -+ -+ if (cisr & CI_CISR_EOF) -+ CISR |= CI_CISR_EOF; -+ -+ enable_irq(IRQ_CAMERA); -+ -+ return IRQ_HANDLED; -+} -+ -+void pxa_dma_repeat(camera_context_t *cam_ctx) -+{ -+ pxa_dma_desc *cnt_head, *cnt_tail; -+ int cnt_block; -+ -+ cnt_block = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ -+ // FIFO0 -+ (pxa_dma_desc *)cnt_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + -+ cnt_block * cam_ctx->fifo0_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo0_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+ -+ // FIFO1 -+ if(cam_ctx->fifo1_transfer_size) -+ { -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + -+ cnt_block * cam_ctx->fifo1_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo1_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ -+ // FIFO2 -+ if(cam_ctx->fifo2_transfer_size) -+ { -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + -+ cnt_block * cam_ctx->fifo2_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo2_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ } -+ -+void pxa_dma_continue(camera_context_t *cam_ctx) -+{ -+ pxa_dma_desc *cnt_head, *cnt_tail; -+ pxa_dma_desc *next_head; -+ int cnt_block, next_block; -+ -+ cnt_block = cam_ctx->block_header; -+ next_block = (cnt_block + 1) % cam_ctx->block_number; -+ -+ // FIFO0 -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + -+ cnt_block * cam_ctx->fifo0_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo0_num_descriptors - 1; -+ -+ next_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + -+ next_block * cam_ctx->fifo0_num_descriptors; -+ -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+ -+ // FIFO1 -+ if(cam_ctx->fifo1_transfer_size) -+ { -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + -+ cnt_block * cam_ctx->fifo1_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo1_num_descriptors - 1; -+ -+ next_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + -+ next_block * cam_ctx->fifo1_num_descriptors; -+ -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ -+ // FIFO2 -+ if(cam_ctx->fifo2_transfer_size) -+ { -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + -+ cnt_block * cam_ctx->fifo2_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo2_num_descriptors - 1; -+ -+ next_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + -+ next_block * cam_ctx->fifo2_num_descriptors; -+ -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ return; -+ -+} -+ -+void ci_dump(void) -+{ -+ dbg_print ("CICR0 = 0x%8lx ", CICR0); -+ dbg_print ("CICR1 = 0x%8lx ", CICR1); -+ dbg_print ("CICR2 = 0x%8lx ", CICR2); -+ dbg_print ("CICR3 = 0x%8lx ", CICR3); -+ dbg_print ("CICR4 = 0x%8lx ", CICR4); -+ dbg_print ("CISR = 0x%8lx ", CISR); -+ dbg_print ("CITOR = 0x%8lx ", CITOR); -+ dbg_print ("CIFR = 0x%8lx ", CIFR); -+} -+ -+ -+module_init(pxa_camera_init); -+module_exit(pxa_camera_exit); -+ -+MODULE_DESCRIPTION("Bulverde Camera Interface driver"); -+MODULE_LICENSE("GPL"); -+ -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/pxa_camera_micron.c linux-2.6.16.5-exz/drivers/media/video/pxa_camera_micron.c ---- linux-2.6.16.5/drivers/media/video/pxa_camera_micron.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/pxa_camera_micron.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,2905 @@ -+/*================================================================================ -+ -+ Module Name: pxa-camera.c -+ -+General Description: Camera module mt9m111 source file -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+ -+Portability: Indicate ifthis module is portable to other compilers or -+platforms. If not, indicate specific reasons why is it not portable. -+ -+================================================================================== -+ INCLUDE FILES -+================================================================================*/ -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/fs.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+#include <linux/videodev.h> -+#include <linux/pci.h> -+#include <linux/pm.h> -+#include <linux/poll.h> -+#include <linux/wait.h> -+ -+#include <linux/types.h> -+#include <asm/mach-types.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/dma.h> -+#include <asm/arch/irqs.h> -+#include <asm/irq.h> -+ -+ -+#define DEBUG -+#include "camera.h" -+#include "mt9m111.h" -+#include "mt9m111_hw.h" -+ -+#define CIBR0_PHY (0x50000000 + 0x28) -+#define CIBR1_PHY (0x50000000 + 0x30) -+#define CIBR2_PHY (0x50000000 + 0x38) -+ -+#define MAX_WIDTH 1280 -+#define MAX_HEIGHT 1024 -+ -+#define MIN_WIDTH 88 -+#define MIN_HEIGHT 72 -+#define WIDTH_DEFT 320 -+#define HEIGHT_DEFT 240 -+#define FRAMERATE_DEFT 15 -+ -+/* -+ * It is required to have at least 3 frames in buffer -+ * in current implementation -+ */ -+#define FRAMES_IN_BUFFER 3 -+#define BUF_SIZE_DEFT ((PAGE_ALIGN(MAX_WIDTH * MAX_HEIGHT) + (PAGE_ALIGN(MAX_WIDTH*MAX_HEIGHT/2)*2))) -+#define SINGLE_DESC_TRANS_MAX PAGE_SIZE -+#define MAX_DESC_NUM (BUF_SIZE_DEFT/PAGE_SIZE +10) -+ -+#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */ -+#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */ -+#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */ -+ -+static camera_context_t *g_camera_context; -+ -+#ifdef CONFIG_CAMERA_MT9M111 -+static camera_function_t mt9m111_func; -+#endif -+#ifdef CONFIG_CAMERA_OV9640 -+extern camera_function_t ov9640_func; -+#endif -+ -+static int irq_n =0; -+static int camera_irq_n =0; -+wait_queue_head_t camera_wait_q; -+ -+static int waitingFrame = 0; -+ -+/* /dev/videoX registration number */ -+static int minor = 0; -+static int ci_dma_y = -1; -+static int ci_dma_cb = -1; -+static int ci_dma_cr = -1; -+static int task_waiting = 0; -+static int still_image_mode = 0; -+static int still_image_rdy = 0; -+static int first_video_frame = 0; -+ -+void pxa_ci_dma_irq_y(int channel, void *data, struct pt_regs *regs); -+void pxa_ci_dma_irq_cb(int channel, void *data, struct pt_regs *regs); -+void pxa_ci_dma_irq_cr(int channel, void *data, struct pt_regs *regs); -+ -+static unsigned long ci_regs_base = 0; /* for CI registers IOMEM mapping */ -+ -+#define CI_REG(x) (* (volatile u32*)(x) ) -+#define CI_REG_SIZE 0x40 /* 0x5000_0000 --- 0x5000_0038 * 64K */ -+#define CI_REGS_PHYS 0x50000000 /* Start phyical address of CI registers */ -+ -+/* -+#define CICR0 CI_REG((u32)(ci_regs_base) + 0x00) -+#define CICR1 CI_REG((u32)(ci_regs_base) + 0x04) -+#define CICR2 CI_REG((u32)(ci_regs_base) + 0x08) -+#define CICR3 CI_REG((u32)(ci_regs_base) + 0x0c) -+#define CICR4 CI_REG((u32)(ci_regs_base) + 0x10) -+#define CISR CI_REG((u32)(ci_regs_base) + 0x14) -+#define CIFR CI_REG((u32)(ci_regs_base) + 0x18) -+#define CITOR CI_REG((u32)(ci_regs_base) + 0x1c) -+#define CIBR0 CI_REG((u32)(ci_regs_base) + 0x28) -+#define CIBR1 CI_REG((u32)(ci_regs_base) + 0x30) -+#define CIBR2 CI_REG((u32)(ci_regs_base) + 0x38) -+*/ -+ -+/*********************************************************************** -+ * -+ * Declarations -+ * -+ ***********************************************************************/ -+ -+// map of camera image format (camera.h) ==> capture interface format (ci.h) -+static const CI_IMAGE_FORMAT FORMAT_MAPPINGS[] = { -+ CI_RAW8, //RAW -+ CI_RAW9, -+ CI_RAW10, -+ -+ CI_RGB444, //RGB -+ CI_RGB555, -+ CI_RGB565, -+ CI_RGB666_PACKED, //RGB Packed -+ CI_RGB666, -+ CI_RGB888_PACKED, -+ CI_RGB888, -+ CI_RGBT555_0, //RGB+Transparent bit 0 -+ CI_RGBT888_0, -+ CI_RGBT555_1, //RGB+Transparent bit 1 -+ CI_RGBT888_1, -+ -+ CI_INVALID_FORMAT, -+ CI_YCBCR422, //YCBCR -+ CI_YCBCR422_PLANAR, //YCBCR Planaried -+ CI_INVALID_FORMAT, -+ CI_INVALID_FORMAT -+}; -+ -+static int update_dma_chain(p_camera_context_t camera_context); -+static void start_dma_transfer(p_camera_context_t camera_context, unsigned block_id); -+void stop_dma_transfer(p_camera_context_t camera_context); -+static int start_capture(p_camera_context_t camera_context, unsigned int block_id, unsigned int frames); -+int camera_init(p_camera_context_t camera_context); -+ -+#ifdef CONFIG_PM -+ static struct pm_dev *pm_dev; -+ static int resume_dma = 0; -+#endif -+ -+#ifdef CONFIG_PM -+ -+static int pxa_camera_pm_suspend() -+{ -+ if(g_camera_context != NULL ) -+ { -+ if(g_camera_context->dma_started) -+ { -+ dbg_print("camera running, suspended"); -+ stop_dma_transfer(g_camera_context); -+ resume_dma = 1; -+ } -+ } -+ -+ disable_irq(IRQ_CAMERA); -+ CKEN &= ~CKEN24_CAMERA; -+ return 0; -+} -+ -+static int pxa_camera_pm_resume() -+{ -+ CKEN |= CKEN24_CAMERA; -+ enable_irq(IRQ_CAMERA); -+ -+ if(g_camera_context != NULL) -+ { -+ dbg_print("camera running, resumed"); -+ micron_window_size size; -+ camera_init(g_camera_context); -+ -+ size.width = g_camera_context->sensor_width; -+ size.height = g_camera_context->sensor_height; -+ mt9m111_input_size(&size); -+ -+ size.width = g_camera_context->capture_width; -+ size.height = g_camera_context->capture_height; -+ mt9m111_output_size(&size); -+ -+ mt9m111_set_bright(g_camera_context->capture_bright); -+ -+ mt9m111_set_fps(g_camera_context->fps, g_camera_context->mini_fps); -+ mt9m111_set_light(g_camera_context->capture_light); -+ mt9m111_set_style(g_camera_context->capture_style); -+ -+ if(resume_dma == 1) -+ { -+ camera_start_video_capture(g_camera_context, 0); -+ resume_dma = 0; -+ } -+ -+ } -+ -+ return 0; -+} -+static int camera_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ switch(req) -+ { -+ case PM_SUSPEND: -+ pxa_camera_pm_suspend(); -+ break; -+ -+ case PM_RESUME: -+ pxa_camera_pm_resume(); -+ break; -+ -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+/*********************************************************************** -+ * -+ * Private functions -+ * -+ ***********************************************************************/ -+ -+static int pxa_dma_buffer_init(p_camera_context_t camera_context) -+{ -+ struct page *page; -+ unsigned int pages; -+ unsigned int page_count; -+ -+ camera_context->pages_allocated = 0; -+ -+ pages = (PAGE_ALIGN(camera_context->buf_size) / PAGE_SIZE); -+ -+ camera_context->page_array = (struct page **) -+ kmalloc(pages * sizeof(struct page *), -+ GFP_KERNEL); -+ -+ if(camera_context->page_array == NULL) -+ { -+ return -ENOMEM; -+ } -+ memset(camera_context->page_array, 0, pages * sizeof(struct page *)); -+ -+ for(page_count = 0; page_count < pages; page_count++) -+ { -+ page = alloc_page(GFP_KERNEL); -+ if(page == NULL) -+ { -+ goto error; -+ } -+ camera_context->page_array[page_count] = page; -+ set_page_count(page, 1); -+ SetPageReserved(page); -+ } -+ camera_context->buffer_virtual = remap_page_array(camera_context->page_array, -+ pages, -+ GFP_KERNEL); -+ -+ if(camera_context->buffer_virtual == NULL) -+ { -+ goto error; -+ } -+ -+ camera_context->pages_allocated = pages; -+ -+ return 0; -+ -+error: -+ for(page_count = 0; page_count < pages; page_count++) -+ { -+ if((page = camera_context->page_array[page_count]) != NULL) -+ { -+ ClearPageReserved(page); -+ set_page_count(page, 1); -+ put_page(page); -+ } -+ } -+ kfree(camera_context->page_array); -+ -+ return -ENOMEM; -+} -+ -+static void pxa_dma_buffer_free(p_camera_context_t camera_context) -+{ -+ struct page *page; -+ int page_count; -+ -+ if(camera_context->buffer_virtual == NULL) -+ return; -+ -+ vfree(camera_context->buffer_virtual); -+ -+ for(page_count = 0; page_count < camera_context->pages_allocated; page_count++) -+ { -+ if((page = camera_context->page_array[page_count]) != NULL) -+ { -+ ClearPageReserved(page); -+ set_page_count(page, 1); -+ put_page(page); -+ } -+ } -+ kfree(camera_context->page_array); -+} -+/* -+Generate dma descriptors -+Pre-condition: these variables must be set properly -+ block_number, fifox_transfer_size -+ dma_descriptors_virtual, dma_descriptors_physical, dma_descirptors_size -+Post-condition: these variables will be set -+ fifox_descriptors_virtual, fifox_descriptors_physical -+ fifox_num_descriptors -+*/ -+int update_dma_chain(p_camera_context_t camera_context) -+{ -+ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL; -+ int des_transfer_size, remain_size; -+ unsigned int i,j; -+ int target_page_num; -+ -+ dbg_print(""); -+ -+ // clear descriptor pointers -+ camera_context->fifo0_descriptors_virtual = camera_context->fifo0_descriptors_physical = 0; -+ camera_context->fifo1_descriptors_virtual = camera_context->fifo1_descriptors_physical = 0; -+ camera_context->fifo2_descriptors_virtual = camera_context->fifo2_descriptors_physical = 0; -+ -+ // calculate how many descriptors are needed per frame -+ camera_context->fifo0_num_descriptors = -+ camera_context->pages_per_fifo0; -+ -+ camera_context->fifo1_num_descriptors = -+ camera_context->pages_per_fifo1; -+ -+ camera_context->fifo2_num_descriptors = -+ camera_context->pages_per_fifo2; -+ -+ // check if enough memory to generate descriptors -+ if((camera_context->fifo0_num_descriptors + -+ camera_context->fifo1_num_descriptors + -+ camera_context->fifo2_num_descriptors) * camera_context->block_number -+ > camera_context->dma_descriptors_size) -+ { -+ return -1; -+ } -+ -+ dbg_print("1"); -+ // generate fifo0 dma chains -+ camera_context->fifo0_descriptors_virtual = (unsigned)camera_context->dma_descriptors_virtual; -+ camera_context->fifo0_descriptors_physical = (unsigned)camera_context->dma_descriptors_physical; -+ -+ cur_des_virtual = (pxa_dma_desc *)camera_context->fifo0_descriptors_virtual; -+ cur_des_physical = (pxa_dma_desc *)camera_context->fifo0_descriptors_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo0_transfer_size; -+ -+ // assume the blocks are stored consecutively -+ target_page_num = camera_context->pages_per_block * i; -+ -+ for(j=0; j<camera_context->fifo0_num_descriptors; j++) -+ { -+ // set descriptor -+ if(remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR0_PHY; // FIFO0 physical address -+ cur_des_virtual->dtadr = page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo0_descriptors_physical); -+ -+ // generate fifo1 dma chains -+ if(camera_context->fifo1_transfer_size) -+ { -+ // record fifo1 descriptors' start address -+ camera_context->fifo1_descriptors_virtual = (unsigned)cur_des_virtual; -+ camera_context->fifo1_descriptors_physical = (unsigned)cur_des_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo1_transfer_size; -+ -+ target_page_num = camera_context->pages_per_block * i + -+ camera_context->pages_per_fifo0; -+ -+ for(j=0; j<camera_context->fifo1_num_descriptors; j++) -+ { -+ // set descriptor -+ if(remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR1_PHY; // FIFO1 physical address -+ cur_des_virtual->dtadr = page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo1_descriptors_physical); -+ } -+ -+ // generate fifo2 dma chains -+ if(camera_context->fifo2_transfer_size) -+ { -+ // record fifo1 descriptors' start address -+ camera_context->fifo2_descriptors_virtual = (unsigned)cur_des_virtual; -+ camera_context->fifo2_descriptors_physical = (unsigned)cur_des_physical; -+ -+ for(i=0; i<camera_context->block_number; i++) -+ { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = camera_context->fifo2_transfer_size; -+ -+ target_page_num = camera_context->pages_per_block * i + -+ camera_context->pages_per_fifo0 + -+ camera_context->pages_per_fifo1; -+ -+ for(j=0; j<camera_context->fifo2_num_descriptors; j++) -+ { -+ // set descriptor -+ if(remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR2_PHY; // FIFO2 physical address -+ cur_des_virtual->dtadr = page_to_bus(camera_context->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ } -+ last_des_virtual->ddadr = ((unsigned)camera_context->fifo2_descriptors_physical); -+ } -+ -+ dbg_print(" success!"); -+ return 0; -+} -+ -+void start_dma_transfer(p_camera_context_t camera_context, unsigned block_id) -+{ -+ pxa_dma_desc *des_virtual, *des_physical; -+ -+ if(block_id >= camera_context->block_number) -+ { -+ return; -+ } -+ -+ // start channel 0 -+ des_virtual = (pxa_dma_desc *)camera_context->fifo0_descriptors_virtual + -+ block_id * camera_context->fifo0_num_descriptors; -+ -+ des_physical = (pxa_dma_desc *)camera_context->fifo0_descriptors_physical + -+ block_id * camera_context->fifo0_num_descriptors; -+ -+ DDADR(camera_context->dma_channels[0]) = des_physical; -+ DCSR(camera_context->dma_channels[0]) |= DCSR_RUN; -+ -+ // start channel 1 -+ if(camera_context->fifo1_descriptors_virtual) -+ { -+ des_virtual = (pxa_dma_desc *)camera_context->fifo1_descriptors_virtual + -+ block_id * camera_context->fifo1_num_descriptors; -+ -+ des_physical = (pxa_dma_desc *)camera_context->fifo1_descriptors_physical + -+ block_id * camera_context->fifo1_num_descriptors; -+ -+ DDADR(camera_context->dma_channels[1]) = des_physical; -+ DCSR(camera_context->dma_channels[1]) |= DCSR_RUN; -+ } -+ -+ // start channel 2 -+ if(camera_context->fifo2_descriptors_virtual) -+ { -+ des_virtual = (pxa_dma_desc *)camera_context->fifo2_descriptors_virtual + -+ block_id * camera_context->fifo2_num_descriptors; -+ -+ des_physical = (pxa_dma_desc *)camera_context->fifo2_descriptors_physical + -+ block_id * camera_context->fifo2_num_descriptors; -+ -+ DDADR(camera_context->dma_channels[2]) = des_physical; -+ DCSR(camera_context->dma_channels[2]) |= DCSR_RUN; -+ } -+ -+ camera_context->dma_started = 1; -+} -+ -+void stop_dma_transfer(p_camera_context_t camera_context) -+{ -+ int ch0, ch1, ch2; -+ -+ ch0 = camera_context->dma_channels[0]; -+ ch1 = camera_context->dma_channels[1]; -+ ch2 = camera_context->dma_channels[2]; -+ -+ DCSR(ch0) &= ~DCSR_RUN; -+ DCSR(ch1) &= ~DCSR_RUN; -+ DCSR(ch2) &= ~DCSR_RUN; -+ camera_context->dma_started = 0; -+ -+ return; -+} -+ -+int start_capture(p_camera_context_t camera_context, unsigned int block_id, unsigned int frames) -+{ -+ int status; -+ //clear ci fifo -+ ci_reset_fifo(); -+ ci_clear_int_status(0xFFFFFFFF); -+ -+ //start dma -+// start_dma_transfer(camera_context, block_id); -+ -+ -+ // start capture -+ status = camera_context->camera_functions->start_capture(camera_context, frames); -+ -+ ci_enable(1); -+ -+ if(frames == 1) //Wait 2 frames to begin capture photo -+ { -+ waitingFrame = 2; -+ } -+ else -+ { -+ waitingFrame = 1; -+ } -+ while(waitingFrame--) -+ { -+ CISR|=(1<<3); -+ while(!(CISR&(1<<3))); //Wait a EOF then begin start DMA -+ } -+ ci_reset_fifo(); -+ start_dma_transfer(camera_context, block_id); -+ return status; -+} -+ -+/*********************************************************************** -+ * -+ * Init/Deinit APIs -+ * -+ ***********************************************************************/ -+int camera_init(p_camera_context_t camera_context) -+{ -+ int ret=0; -+ int i; -+ dbg_print("0"); -+#ifdef DEBUG -+ // parameter check -+ if(camera_context->buffer_virtual == NULL || -+ camera_context->buf_size == 0) -+ { -+ dbg_print("camera_context->buffer wrong!"); -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ if(camera_context->dma_descriptors_virtual == NULL || -+ camera_context->dma_descriptors_physical == NULL || -+ camera_context->dma_descriptors_size == 0) -+ { -+ dbg_print("camera_context->dma_descriptors wrong!"); -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ if(camera_context->sensor_type > CAMERA_TYPE_MAX) -+ { -+ dbg_print("camera_context->sensor type wrong!"); -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ if(camera_context->capture_input_format > CAMERA_IMAGE_FORMAT_MAX || -+ camera_context->capture_output_format > CAMERA_IMAGE_FORMAT_MAX) -+ { -+ dbg_print("camera_context->capture format wrong!"); -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ // check the function dispatch table according to the sensor type -+ if(!camera_context->camera_functions ) -+ { -+ dbg_print("camera_context->camera_functions wrong!"); -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ if( !camera_context->camera_functions->init || -+ !camera_context->camera_functions->deinit || -+ !camera_context->camera_functions->set_capture_format || -+ !camera_context->camera_functions->start_capture || -+ !camera_context->camera_functions->stop_capture ) -+ { -+ return STATUS_WRONG_PARAMETER; -+ } -+#endif -+ dbg_print(""); -+ // init context status -+ for(i=0; i<3; i++) -+ { -+ camera_context->dma_channels[i] = 0xFF; -+ } -+ -+ (int)camera_context->fifo0_descriptors_virtual = NULL; -+ (int)camera_context->fifo1_descriptors_virtual = NULL; -+ (int)camera_context->fifo2_descriptors_virtual = NULL; -+ (int)camera_context->fifo0_descriptors_physical = NULL; -+ (int)camera_context->fifo1_descriptors_physical = NULL; -+ (int)camera_context->fifo2_descriptors_physical = NULL; -+ -+ camera_context->fifo0_num_descriptors = 0; -+ camera_context->fifo1_num_descriptors = 0; -+ camera_context->fifo2_num_descriptors = 0; -+ -+ camera_context->fifo0_transfer_size = 0; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ -+ camera_context->block_number = 0; -+ camera_context->block_size = 0; -+ camera_context->block_header = 0; -+ camera_context->block_tail = 0; -+ -+ // Enable hardware -+ camera_gpio_init(); -+ -+ // capture interface init -+ ci_init(); -+ -+ -+ // sensor init -+ if(camera_context->camera_functions->init(camera_context)) -+ { -+ dbg_print("camera function init error!!"); -+ goto camera_init_err; -+ } -+ -+ camera_context->dma_channels[0] = ci_dma_y; -+ camera_context->dma_channels[1] = ci_dma_cb; -+ camera_context->dma_channels[2] = ci_dma_cr; -+ DRCMR68 = ci_dma_y | DRCMR_MAPVLD; -+ DRCMR69 = ci_dma_cb | DRCMR_MAPVLD; -+ DRCMR70 = ci_dma_cr | DRCMR_MAPVLD; -+ ret = camera_set_capture_format(camera_context); -+ if(ret) -+ { -+ dbg_print("camera function init error!!"); -+ goto camera_init_err; -+ } -+ -+#ifdef DEBUG -+ ci_dump(); -+#endif -+ -+ ci_disable(1); -+ return 0; -+ -+camera_init_err: -+ camera_deinit(camera_context); -+ return -1; -+} -+ -+void camera_gpio_init() -+{ -+#ifdef CONFIG_CAMERA_OV9640 -+ set_GPIO_mode( 50 | GPIO_OUT ); /*CIF_PD*/ -+ set_GPIO_mode( 19 | GPIO_OUT ); /*CIF_RST*/ -+ set_GPIO_mode( 27 | GPIO_ALT_FN_3_IN); /* CIF_DD[0] */ -+ set_GPIO_mode( 114 | GPIO_ALT_FN_1_IN); /* CIF_DD[1] */ -+ set_GPIO_mode( 51 | GPIO_ALT_FN_1_IN); /* CIF_DD[2] */ -+ set_GPIO_mode( 115| GPIO_ALT_FN_2_IN); /* CIF_DD[3] */ -+ set_GPIO_mode( 95 | GPIO_ALT_FN_2_IN); /* CIF_DD[4] */ -+ set_GPIO_mode( 94 | GPIO_ALT_FN_2_IN); /* CIF_DD[5] */ -+ set_GPIO_mode( 17 | GPIO_ALT_FN_2_IN); /* CIF_DD[6] */ -+ set_GPIO_mode( 108 | GPIO_ALT_FN_1_IN); /* CIF_DD[7] */ -+// set_GPIO_mode( 107 | GPIO_ALT_FN_1_IN); /* CIF_DD[8] */ -+// set_GPIO_mode( 106 | GPIO_ALT_FN_1_IN); /* CIF_DD[9] */ -+ set_GPIO_mode( 23 | GPIO_ALT_FN_1_OUT); /* CIF_MCLK */ -+ set_GPIO_mode( 54 | GPIO_ALT_FN_3_IN); /* CIF_PCLK */ -+ set_GPIO_mode( 85 | GPIO_ALT_FN_3_IN); /* CIF_LV */ -+ set_GPIO_mode( 84 | GPIO_ALT_FN_3_IN); /* CIF_FV */ -+ -+#endif -+ -+#ifdef CONFIG_CAMERA_MT9M111 -+ set_GPIO_mode( CIF_PD_MD ); /*CIF_PD*/ -+ GPCR(CIF_PD) = GPIO_bit(CIF_PD); /*set to low*/ -+ set_GPIO_mode( CIF_RST_MD ); /*CIF_RST*/ -+ GPSR(CIF_RST) = GPIO_bit(CIF_RST); /*set to high*/ -+ set_GPIO_mode( CIF_DD0_MD ); /* CIF_DD[0] */ -+ set_GPIO_mode( CIF_DD1_MD ); /* CIF_DD[1] */ -+ set_GPIO_mode( CIF_DD2_MD ); /* CIF_DD[2] */ -+ set_GPIO_mode( CIF_DD3_MD ); /* CIF_DD[3] */ -+ set_GPIO_mode( CIF_DD4_MD ); /* CIF_DD[4] */ -+ set_GPIO_mode( CIF_DD5_MD ); /* CIF_DD[5] */ -+ set_GPIO_mode( CIF_DD6_MD ); /* CIF_DD[6] */ -+ set_GPIO_mode( CIF_DD7_MD ); /* CIF_DD[7] */ -+ set_GPIO_mode( CIF_MCLK_MD ); /* CIF_MCLK */ -+ set_GPIO_mode( CIF_PCLK_MD ); /* CIF_PCLK */ -+ set_GPIO_mode( CIF_LV_MD ); /* CIF_LV */ -+ set_GPIO_mode( CIF_FV_MD ); /* CIF_FV */ -+#endif -+ -+ -+ return; -+} -+ -+ -+void camera_gpio_deinit() -+{ -+ -+ #ifdef CONFIG_CAMERA_MT9M111 -+ /* Turn off M_VCC CIF_PD*/ -+ GPSR(CIF_PD) = GPIO_bit(CIF_PD); /* Set PD to low */ -+ -+ set_GPIO_mode( CIF_MCLK | GPIO_IN); /*trun off MCLK*/ -+ #endif -+} -+ -+int camera_deinit( p_camera_context_t camera_context ) -+{ -+ -+ // free dma channel -+ /* -+ for(i=0; i<3; i++) -+ { -+ if(camera_context->dma_channels[i] != 0x00) -+ { -+ pxa_free_dma(camera_context->dma_channels[i]); -+ camera_context->dma_channels[i] = 0; -+ } -+ } -+ */ -+ -+ // deinit sensor -+ camera_context->camera_functions->deinit(camera_context); -+ -+ // capture interface deinit -+ ci_deinit(); -+ camera_gpio_deinit(); -+ return 0; -+} -+ -+int camera_ring_buf_init(p_camera_context_t camera_context) -+{ -+ dbg_print(""); -+ unsigned frame_size; -+ switch(camera_context->capture_output_format) -+ { -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 2; -+ camera_context->fifo0_transfer_size = frame_size; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 2; -+ camera_context->fifo0_transfer_size = frame_size; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 2; -+ camera_context->fifo0_transfer_size = frame_size / 2; -+ camera_context->fifo1_transfer_size = frame_size / 4; -+ camera_context->fifo2_transfer_size = frame_size / 4; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB666_PLANAR: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 4; -+ camera_context->fifo0_transfer_size = frame_size; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB666_PACKED: -+ frame_size = camera_context->capture_width * camera_context->capture_height * 3; -+ camera_context->fifo0_transfer_size = frame_size; -+ camera_context->fifo1_transfer_size = 0; -+ camera_context->fifo2_transfer_size = 0; -+ break; -+ default: -+ return STATUS_WRONG_PARAMETER; -+ break; -+ } -+ -+ camera_context->block_size = frame_size; -+ -+ camera_context->pages_per_fifo0 = -+ (PAGE_ALIGN(camera_context->fifo0_transfer_size) / PAGE_SIZE); -+ camera_context->pages_per_fifo1 = -+ (PAGE_ALIGN(camera_context->fifo1_transfer_size) / PAGE_SIZE); -+ camera_context->pages_per_fifo2 = -+ (PAGE_ALIGN(camera_context->fifo2_transfer_size) / PAGE_SIZE); -+ -+ camera_context->pages_per_block = -+ camera_context->pages_per_fifo0 + -+ camera_context->pages_per_fifo1 + -+ camera_context->pages_per_fifo2; -+ -+ camera_context->page_aligned_block_size = -+ camera_context->pages_per_block * PAGE_SIZE; -+ -+ camera_context->block_number_max = -+ camera_context->pages_allocated / -+ camera_context->pages_per_block; -+ -+ -+ //restrict max block number -+ if(camera_context->block_number_max > FRAMES_IN_BUFFER) -+ { -+ camera_context->block_number = FRAMES_IN_BUFFER; -+ } -+ else -+ { -+ camera_context->block_number = camera_context->block_number_max; -+ } -+ -+ camera_context->block_header = camera_context->block_tail = 0; -+ -+ // generate dma descriptor chain -+ return update_dma_chain(camera_context); -+ -+} -+/*********************************************************************** -+ * -+ * Capture APIs -+ * -+ ***********************************************************************/ -+// Set the image format -+int camera_set_capture_format(p_camera_context_t camera_context) -+{ -+ -+ CI_IMAGE_FORMAT ci_input_format, ci_output_format; -+ CI_MP_TIMING timing; -+ -+ if(camera_context->capture_input_format > CAMERA_IMAGE_FORMAT_MAX || -+ camera_context->capture_output_format > CAMERA_IMAGE_FORMAT_MAX ) -+ { -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ ci_input_format = FORMAT_MAPPINGS[camera_context->capture_input_format]; -+ ci_output_format = FORMAT_MAPPINGS[camera_context->capture_output_format]; -+ -+ if(ci_input_format == CI_INVALID_FORMAT || ci_output_format == CI_INVALID_FORMAT) -+ { -+ return STATUS_WRONG_PARAMETER; -+ } -+ -+ ci_set_image_format(ci_input_format, ci_output_format); -+ -+#ifdef CONFIG_CAMERA_MT9M111 -+ timing.BFW = 0; -+ timing.BLW = 0; -+#endif -+#ifdef CONFIG_CAMERA_OV9640 -+ timing.BFW = 0; -+ timing.BLW = 51*2; -+#endif -+ -+ -+ ci_configure_mp(camera_context->capture_width-1, camera_context->capture_height-1, &timing); -+ -+ if(camera_context == NULL || camera_context->camera_functions == NULL || -+ camera_context->camera_functions->set_capture_format == NULL) -+ { -+ dbg_print("camera_context point NULL!!!"); -+ return -1; -+ } -+ // set sensor setting -+ if(camera_context->camera_functions->set_capture_format(camera_context)) -+ { -+ return -1; -+ } -+ -+ // ring buffer init -+ return camera_ring_buf_init(camera_context); -+ -+} -+ -+// take a picture and copy it into the ring buffer -+int camera_capture_still_image(p_camera_context_t camera_context, unsigned int block_id) -+{ -+ // init buffer status & capture -+ camera_set_int_mask(camera_context, 0x3ff | 0x0400); -+ still_image_mode = 1; -+ first_video_frame = 0; -+ camera_context->block_header = camera_context->block_tail = block_id; -+ camera_context->capture_status = 0; -+ return start_capture(camera_context, block_id, 1); -+} -+ -+// capture motion video and copy it to the ring buffer -+int camera_start_video_capture( p_camera_context_t camera_context, unsigned int block_id ) -+{ -+ //init buffer status & capture -+ camera_set_int_mask(camera_context, 0x3ff | 0x0400); -+ still_image_mode = 0; -+ first_video_frame = 1; -+ camera_context->block_header = camera_context->block_tail = block_id; -+ camera_context->capture_status = CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS; -+ return start_capture(camera_context, block_id, 0); -+} -+ -+// disable motion video image capture -+void camera_stop_video_capture( p_camera_context_t camera_context ) -+{ -+ //stop capture -+ camera_context->camera_functions->stop_capture(camera_context); -+ -+ //stop dma -+ stop_dma_transfer(camera_context); -+ -+ //update the flag -+ if(!(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ { -+ camera_context->capture_status &= ~CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS; -+ } -+ -+ ci_disable(1); -+} -+ -+ -+/*********************************************************************** -+ * -+ * Flow Control APIs -+ * -+ ***********************************************************************/ -+// continue capture image to next available buffer -+void camera_continue_transfer( p_camera_context_t camera_context ) -+{ -+ // don't think we need this either. JR -+ // continue transfer on next block -+ start_dma_transfer( camera_context, camera_context->block_tail ); -+} -+ -+// Return 1: there is available buffer, 0: buffer is full -+int camera_next_buffer_available( p_camera_context_t camera_context ) -+{ -+ camera_context->block_header = (camera_context->block_header + 1) % camera_context->block_number; -+ if(((camera_context->block_header + 1) % camera_context->block_number) != camera_context->block_tail) -+ { -+ return 1; -+ } -+ -+ camera_context->capture_status |= CAMERA_STATUS_RING_BUFFER_FULL; -+ return 0; -+} -+ -+// Application supplies the FrameBufferID to the driver to tell it that the application has completed processing of -+// the given frame buffer, and that buffer is now available for re-use. -+void camera_release_frame_buffer(p_camera_context_t camera_context, unsigned int frame_buffer_id) -+{ -+ -+ camera_context->block_tail = (camera_context->block_tail + 1) % camera_context->block_number; -+ -+ // restart video capture only ifvideo capture is in progress and space is available for image capture -+ if((camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL ) && -+ (camera_context->capture_status & CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS)) -+ { -+ if(((camera_context->block_header + 2) % camera_context->block_number) != camera_context->block_tail) -+ { -+ camera_context->capture_status &= ~CAMERA_STATUS_RING_BUFFER_FULL; -+ start_capture(camera_context, camera_context->block_tail, 0); -+ } -+ } -+} -+ -+// Returns the FrameBufferID for the first filled frame -+// Note: -1 represents buffer empty -+int camera_get_first_frame_buffer_id(p_camera_context_t camera_context) -+{ -+ // not sure ifthis routine makes any sense.. JR -+ -+ // check whether buffer is empty -+ if((camera_context->block_header == camera_context->block_tail) && -+ !(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ { -+ return -1; -+ } -+ -+ // return the block header -+ return camera_context->block_header; -+} -+ -+// Returns the FrameBufferID for the last filled frame, this would be used ifwe were polling for image completion data, -+// or we wanted to make sure there were no frames waiting for us to process. -+// Note: -1 represents buffer empty -+int camera_get_last_frame_buffer_id(p_camera_context_t camera_context) -+{ -+ -+ // check whether buffer is empty -+ if((camera_context->block_header == camera_context->block_tail) && -+ !(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ { -+ return -1; -+ } -+ -+ // return the block before the block_tail -+ return (camera_context->block_tail + camera_context->block_number - 1) % camera_context->block_number; -+} -+ -+ -+/*********************************************************************** -+ * -+ * Buffer Info APIs -+ * -+ ***********************************************************************/ -+// Return: the number of frame buffers allocated for use. -+unsigned int camera_get_num_frame_buffers(p_camera_context_t camera_context) -+{ -+ return camera_context->block_number; -+} -+ -+// FrameBufferID is a number between 0 and N-1, where N is the total number of frame buffers in use. Returns the address of -+// the given frame buffer. The application will call this once for each frame buffer at application initialization only. -+void * camera_get_frame_buffer_addr(p_camera_context_t camera_context, unsigned int frame_buffer_id) -+{ -+ return (void*)((unsigned)camera_context->buffer_virtual + -+ camera_context->page_aligned_block_size * frame_buffer_id); -+} -+ -+// Return the block id -+int camera_get_frame_buffer_id(p_camera_context_t camera_context, void* address) -+{ -+ if(((unsigned)address >= (unsigned)camera_context->buffer_virtual) && -+ ((unsigned)address <= (unsigned)camera_context->buffer_virtual + camera_context->buf_size)) -+ { -+ return ((unsigned)address - -+ (unsigned)camera_context->buffer_virtual) / -+ camera_context->page_aligned_block_size; -+ } -+ -+ return -1; -+} -+ -+ -+/*********************************************************************** -+ * -+ * Frame rate APIs -+ * -+ ***********************************************************************/ -+// Set desired frame rate -+void camera_set_capture_frame_rate(p_camera_context_t camera_context) -+{ -+ ci_set_frame_rate(camera_context->fps); -+} -+ -+// return current setting -+void camera_get_capture_frame_rate(p_camera_context_t camera_context) -+{ -+ camera_context->fps = ci_get_frame_rate(); -+} -+ -+ -+/*********************************************************************** -+ * -+ * Interrupt APIs -+ * -+ ***********************************************************************/ -+// set interrupt mask -+void camera_set_int_mask(p_camera_context_t cam_ctx, unsigned int mask) -+{ -+ pxa_dma_desc * end_des_virtual; -+ int dma_interrupt_on, i; -+ -+ // set CI interrupt -+ ci_set_int_mask( mask & CI_CICR0_INTERRUPT_MASK ); -+ -+ // set dma end interrupt -+ if( mask & CAMERA_INTMASK_END_OF_DMA ) -+ dma_interrupt_on = 1; -+ else -+ dma_interrupt_on = 0; -+ -+ // set fifo0 dma chains' flag -+ end_des_virtual = (pxa_dma_desc*)cam_ctx->fifo0_descriptors_virtual + cam_ctx->fifo0_num_descriptors - 1; -+ -+ for(i=0; i<cam_ctx->block_number; i++) -+ { -+ if(dma_interrupt_on) -+ end_des_virtual->dcmd |= DCMD_ENDIRQEN; -+ else -+ end_des_virtual->dcmd &= ~DCMD_ENDIRQEN; -+ -+ end_des_virtual += cam_ctx->fifo0_num_descriptors; -+ } -+} -+ -+// get interrupt mask -+unsigned int camera_get_int_mask(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *end_des_virtual; -+ unsigned int ret; -+ -+ // get CI mask -+ ret = ci_get_int_mask(); -+ -+ // get dma end mask -+ end_des_virtual = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + cam_ctx->fifo0_num_descriptors - 1; -+ -+ if(end_des_virtual->dcmd & DCMD_ENDIRQEN) -+ { -+ ret |= CAMERA_INTMASK_END_OF_DMA; -+ } -+ return ret; -+} -+ -+// clear interrupt status -+void camera_clear_int_status( p_camera_context_t camera_context, unsigned int status ) -+{ -+ ci_clear_int_status( (status & 0xFFFF) ); -+} -+ -+/*********************************************************************************** -+* Application interface * -+***********************************************************************************/ -+static int pxa_camera_open(struct video_device *dev, int flags) -+{ -+ dbg_print("start..."); -+ camera_context_t *cam_ctx; -+ -+ init_waitqueue_head(&camera_wait_q); -+ -+ if(pxa_camera_mem_init()) -+ { -+ dbg_print("DMA memory allocate failed!"); -+ return -1; -+ } -+ -+ -+ cam_ctx = g_camera_context; -+ -+#ifdef CONFIG_CAMERA_MT9M111 -+ cam_ctx->sensor_type = CAMERA_TYPE_MT9M111; -+ cam_ctx->capture_width = WIDTH_DEFT; -+ cam_ctx->capture_height = HEIGHT_DEFT; -+ cam_ctx->camera_functions = &mt9m111_func; -+#endif -+#ifdef CONFIG_CAMERA_OV9640 -+ cam_ctx->sensor_type = CAMERA_TYPE_OMNIVISION_9640; -+ cam_ctx->capture_width = 320; -+ cam_ctx->capture_height = 240; -+ cam_ctx->camera_functions = &ov9640_func; -+#endif -+ -+ cam_ctx->capture_input_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ cam_ctx->capture_output_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ -+ cam_ctx->fps = FRAMERATE_DEFT; -+ -+// cam_ctx->ost_reg_base = 0; -+// cam_ctx->gpio_reg_base = 0; -+// cam_ctx->ci_reg_base = 0; -+// cam_ctx->board_reg_base = 0; -+ -+ if(cam_ctx->dma_descriptors_virtual == NULL) -+ { -+ dbg_print("descriptors virtual memory not allocated!"); -+ return -1; -+ } -+ -+ if(cam_ctx->buffer_virtual == NULL) -+ { -+ dbg_print("buffer virtual memory not allocated!"); -+ return -1; -+ } -+ -+ cam_ctx->ost_reg_base = 0; -+ cam_ctx->gpio_reg_base = 0; -+ cam_ctx->ci_reg_base = 0; -+ cam_ctx->board_reg_base = 0; -+ -+ -+ if(camera_init(cam_ctx)) -+ { -+ dbg_print("camera_init faile!"); -+ return -1; -+ } -+ -+ dbg_print("PXA_CAMERA: pxa_camera_open success!"); -+ return 0; -+} -+ -+static void pxa_camera_close(struct video_device *dev) -+{ -+ camera_deinit(g_camera_context); -+ pxa_camera_mem_deinit(); -+ dbg_print("PXA_CAMERA: pxa_camera_close\n"); -+} -+ -+#define PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, size) \ -+do { \ -+ unsigned int len; \ -+ unsigned int remain_size = size; \ -+ while (remain_size > 0) { \ -+ if(remain_size > PAGE_SIZE) \ -+ len = PAGE_SIZE; \ -+ else \ -+ len = remain_size; \ -+ if(copy_to_user(buf, page_address(*p_page), len)) \ -+ return -EFAULT; \ -+ remain_size -= len; \ -+ buf += len; \ -+ p_page++; \ -+ } \ -+} while (0); -+ -+ -+static long pxa_camera_read(struct video_device *dev, -+ char *buf, -+ unsigned long count, -+ int noblock) -+{ -+ -+ struct page **p_page; -+ -+ camera_context_t *cam_ctx = g_camera_context; -+ -+ if(still_image_mode == 1 && still_image_rdy == 1) -+ { -+ p_page = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo0_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo1_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo2_transfer_size); -+ -+ still_image_rdy = 0; -+ return cam_ctx->block_size; -+ } -+ -+ if(still_image_mode == 0) -+ { -+ if(first_video_frame == 1) -+ cam_ctx->block_tail = cam_ctx->block_header; -+ else -+ cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number; -+ } -+ -+ first_video_frame = 0; -+ -+ if(cam_ctx->block_header == cam_ctx->block_tail) -+ { -+ task_waiting = 1; -+ interruptible_sleep_on (&camera_wait_q); -+ } -+ -+ p_page = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo0_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo1_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo2_transfer_size); -+ -+ return cam_ctx->block_size; -+} -+ -+struct reg_set_s -+{ -+ int val1; -+ int val2; -+}; -+ -+/*ioctl sub functions*/ -+static int pxa_camera_VIDIOCGCAP(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_capability vc; -+ dbg_print("VIDIOCGCAP"); -+ strcpy (vc.name, "Micron MT9M111"); -+ vc.maxwidth = MAX_WIDTH; -+ vc.maxheight = MAX_HEIGHT; -+ vc.minwidth = MIN_WIDTH; -+ vc.minheight = MIN_HEIGHT; -+ if(copy_to_user(param, &vc, sizeof(struct video_capability))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+static int pxa_camera_VIDIOCGWIN(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_window vw; -+ dbg_print("VIDIOCGWIN"); -+ vw.width = cam_ctx->capture_width; -+ vw.height = cam_ctx->capture_height; -+ if(copy_to_user(param, &vw, sizeof(struct video_window))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+static int pxa_camera_VIDIOCSWIN(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_window vw; -+ dbg_print("VIDIOCSWIN"); -+ if(copy_from_user(&vw, param, sizeof(vw))) -+ { -+ dbg_print("VIDIOCSWIN get parameter error!"); -+ return -EFAULT; -+ } -+ if(vw.width > MAX_WIDTH || vw.height > MAX_HEIGHT || vw.width < MIN_WIDTH || vw.height < MIN_HEIGHT) -+ { -+ dbg_print("VIDIOCSWIN error parameter!"); -+ dbg_print("vw.width:%d, MAX_WIDTH:%d, MIN_WIDTH:%d", vw.width, MAX_WIDTH, MIN_WIDTH); -+ dbg_print("vw.height:%d, MAX_HEIGHT:%d, MIN_HEIGHT:%d", vw.width, MAX_HEIGHT, MIN_HEIGHT); -+ return -EFAULT; -+ } -+ cam_ctx->capture_width = vw.width; -+ //make it in an even -+ cam_ctx->capture_width = (vw.width+1)/2; -+ cam_ctx->capture_width *= 2; -+ -+ cam_ctx->capture_height = (vw.height+1)/2; -+ cam_ctx->capture_height *= 2; -+ -+ return camera_set_capture_format(cam_ctx); -+} -+static int pxa_camera_VIDIOCSPICT(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_picture vp; -+ dbg_print("VIDIOCSPICT"); -+ if(copy_from_user(&vp, param, sizeof(vp))) -+ { -+ return -EFAULT; -+ } -+ cam_ctx->capture_output_format = vp.palette; -+ -+ return camera_set_capture_format(cam_ctx); -+ -+} -+ -+static int pxa_camera_VIDIOCGPICT(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_picture vp; -+ dbg_print("VIDIOCGPICT"); -+ vp.palette = cam_ctx->capture_output_format; -+ if(copy_to_user(param, &vp, sizeof(struct video_picture))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static int pxa_camera_VIDIOCCAPTURE(p_camera_context_t cam_ctx, void * param) -+{ -+ int capture_flag = (int)param; -+ dbg_print("VIDIOCCAPTURE"); -+ if(capture_flag > 0) -+ { -+ dbg_print("Still Image capture!"); -+ camera_capture_still_image(cam_ctx, 0); -+ } -+ else if(capture_flag == 0) -+ { -+ dbg_print("Video Image capture!"); -+ camera_start_video_capture(cam_ctx, 0); -+ } -+ else if(capture_flag == -1) -+ { -+ dbg_print("Capture stop!"); -+ camera_set_int_mask(cam_ctx, 0x3ff); -+ camera_stop_video_capture(cam_ctx); -+ } -+ else -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static int pxa_camera_VIDIOCGMBUF(p_camera_context_t cam_ctx, void * param) -+{ -+ struct video_mbuf vm; -+ int i; -+ -+ dbg_print("VIDIOCGMBUF"); -+ -+ memset(&vm, 0, sizeof(vm)); -+ vm.size = cam_ctx->buf_size; -+ vm.frames = cam_ctx->block_number; -+ for(i = 0; i < vm.frames; i++) -+ { -+ vm.offsets[i] = cam_ctx->page_aligned_block_size * i; -+ } -+ if(copy_to_user((void *)param, (void *)&vm, sizeof(vm))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+static int pxa_camera_WCAM_VIDIOCSINFOR(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ struct reg_set_s reg_s; -+ int ret; -+ dbg_print("WCAM_VIDIOCSINFOR"); -+ -+ if(copy_from_user(®_s, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ -+ cam_ctx->capture_input_format = reg_s.val1; -+ cam_ctx->capture_output_format = reg_s.val2; -+ ret=camera_set_capture_format(cam_ctx); -+ ci_dump(); -+ return ret; -+} -+static int pxa_camera_WCAM_VIDIOCGINFOR(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ struct reg_set_s reg_s; -+ dbg_print("WCAM_VIDIOCGINFOR"); -+ reg_s.val1 = cam_ctx->capture_input_format; -+ reg_s.val2 = cam_ctx->capture_output_format; -+ if(copy_to_user(param, ®_s, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+static int pxa_camera_WCAM_VIDIOCGCIREG(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ int reg_value, offset; -+ dbg_print("WCAM_VIDIOCGCIREG"); -+ if(copy_from_user(&offset, param, sizeof(int))) -+ { -+ return -EFAULT; -+ -+ } -+ reg_value = ci_get_reg_value (offset); -+ if(copy_to_user(param, ®_value, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static int pxa_camera_WCAM_VIDIOCSCIREG(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ struct reg_set_s reg_s; -+ dbg_print("WCAM_VIDIOCSCIREG"); -+ if(copy_from_user(®_s, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ ci_set_reg_value (reg_s.val1, reg_s.val2); -+ return 0; -+ -+} -+static int pxa_camera_WCAM_VIDIOCGCAMREG(p_camera_context_t cam_ctx, void * param) -+{ -+ int reg_value, offset; -+ dbg_print("WCAM_VIDIOCGCAMREG"); -+ if(copy_from_user(&offset, param, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ reg_value = (int)mt9m111_reg_read((u16)offset); -+ -+ if(copy_to_user(param, ®_value, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+static int pxa_camera_WCAM_VIDIOCSCAMREG(p_camera_context_t cam_ctx, void * param) -+{ -+ struct reg_set_s reg_s; -+ dbg_print("WCAM_VIDIOCSCAMREG"); -+ -+ if(copy_from_user(®_s, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ mt9m111_reg_write((u16)reg_s.val1, (u16)reg_s.val2); -+ return 0; -+} -+ -+static int pxa_cam_WCAM_VIDIOCSFPS(p_camera_context_t cam_ctx, void * param) -+{ -+ struct {int fps, minfps;} cam_fps; -+ dbg_print("WCAM_VIDIOCSFPS"); -+ if(copy_from_user(&cam_fps, param, sizeof(int) * 2)) -+ { -+ return -EFAULT; -+ } -+ cam_ctx->fps = cam_fps.fps; -+ cam_ctx->mini_fps = cam_fps.minfps; -+ mt9m111_set_fps(cam_fps.fps, cam_fps.minfps); -+ return 0; -+} -+ -+ -+/*Set sensor size*/ -+static int pxa_cam_WCAM_VIDIOCSSSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ micron_window_size size; -+ dbg_print("WCAM_VIDIOCSSSIZE"); -+ -+ if(copy_from_user(&size, param, sizeof(micron_window_size))) -+ { -+ return -EFAULT; -+ } -+ -+ size.width = (size.width+1)/2 * 2; -+ size.height = (size.height+1)/2 * 2; -+ cam_ctx->sensor_width = size.width; -+ cam_ctx->sensor_height = size.height; -+ mt9m111_input_size(&size); -+ return 0; -+} -+ -+//set output size -+static int pxa_cam_WCAM_VIDIOCSOSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ micron_window_size size; -+ CI_MP_TIMING timing; -+ dbg_print("WCAM_VIDIOCSOSIZE"); -+ -+ if(copy_from_user(&size, param, sizeof(micron_window_size))) -+ { -+ return -EFAULT; -+ } -+ -+ //make it in an even number -+ size.width = (size.width+1)/2 * 2; -+ size.height = (size.height+1)/2 * 2; -+ mt9m111_output_size(&size); -+ -+ cam_ctx->capture_width = size.width; -+ cam_ctx->capture_height = size.height; -+ timing.BFW = timing.BLW = 0; -+ -+ ci_configure_mp(cam_ctx->capture_width-1, cam_ctx->capture_height-1, &timing); -+ camera_ring_buf_init(cam_ctx); -+ -+ return 0; -+} -+ -+ -+ -+/*get sensor size */ -+static int pxa_cam_WCAM_VIDIOCGSSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ micron_window_size size; -+ dbg_print("WCAM_VIDIOCGSSIZE"); -+ mt9m111_get_input_size(&size); -+ if(copy_to_user(param, &size, sizeof(micron_window_size))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+/*get output size*/ -+static int pxa_cam_WCAM_VIDIOCGOSIZE(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ micron_window_size size; -+ dbg_print("WCAM_VIDIOCGOSIZE"); -+ size.width = cam_ctx->capture_width; -+ size.height = cam_ctx->capture_height; -+ if(copy_to_user(param, &size, sizeof(micron_window_size))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+/*set picture style*/ -+static int pxa_cam_WCAM_VIDIOCSSTYLE(p_camera_context_t cam_ctx, void * param) -+{ -+ dbg_print("WCAM_VIDIOCSSTYLE"); -+ cam_ctx->capture_style = (V4l_PIC_STYLE)param; -+ -+ if(cam_ctx->capture_style != V4l_STYLE_BLACK_WHITE && cam_ctx->capture_style != V4l_STYLE_SEPIA) -+ { -+ mt9m111_set_light(cam_ctx->capture_light); -+ } -+ -+ return mt9m111_set_style(cam_ctx->capture_style); -+} -+ -+ -+/*set picture light*/ -+static int pxa_cam_WCAM_VIDIOCSLIGHT(p_camera_context_t cam_ctx, void * param) -+{ -+ -+ dbg_print("WCAM_VIDIOCSLIGHT"); -+ cam_ctx->capture_light = (V4l_PIC_WB)param; -+ if(cam_ctx->capture_style != V4l_STYLE_BLACK_WHITE && cam_ctx->capture_style != V4l_STYLE_SEPIA) -+ { -+ return mt9m111_set_light((V4l_PIC_WB)param); -+ } -+ return 0; -+} -+ -+/*set picture brightness*/ -+static int pxa_cam_WCAM_VIDIOCSBRIGHT(p_camera_context_t cam_ctx, void * param) -+{ -+ dbg_print("WCAM_VIDIOCSBRIGHT"); -+ cam_ctx->capture_bright = (int)param; -+ return mt9m111_set_bright((int)param); -+} -+ -+/*set frame buffer count*/ -+static int pxa_cam_WCAM_VIDIOCSBUFCOUNT(p_camera_context_t cam_ctx, void * param) -+{ -+// dbg_print(""); -+ int count; -+ if(copy_from_user(&count, param, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ -+ if(cam_ctx->block_number_max == 0) -+ { -+ dbg_print("windows size or format not setting!!"); -+ return -EFAULT; -+ } -+ -+ if(count < FRAMES_IN_BUFFER) -+ { -+ count = FRAMES_IN_BUFFER; -+ } -+ -+ if(count > cam_ctx->block_number_max) -+ { -+ count = cam_ctx->block_number_max; -+ } -+ -+ -+ cam_ctx->block_number = count; -+ cam_ctx->block_header = cam_ctx->block_tail = 0; -+ //generate dma descriptor chain -+ update_dma_chain(cam_ctx); -+ -+ if(copy_to_user(param, &count, sizeof(int))) -+ { -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*get cur avaliable frames*/ -+static int pxa_cam_WCAM_VIDIOCGCURFRMS(p_camera_context_t cam_ctx, void * param) -+{ -+// dbg_print(""); -+ struct {int first, last;}pos; -+ pos.first = cam_ctx->block_tail; -+ pos.last = cam_ctx->block_header; -+ -+ if(copy_to_user(param, &pos, sizeof(pos))) -+ { -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static int pxa_camera_ioctl(struct video_device *dev, unsigned int cmd, void *param) -+{ -+ //dbg_print ("mt9m111: ioctl cmd = %d\n",cmd); -+ switch (cmd) -+ { -+ /*get capture capability*/ -+ case VIDIOCGCAP: -+ return pxa_camera_VIDIOCGCAP(g_camera_context, param); -+ -+ /* get capture size */ -+ case VIDIOCGWIN: -+ return pxa_camera_VIDIOCGWIN(g_camera_context, param); -+ -+ /* set capture size. */ -+ case VIDIOCSWIN: -+ return pxa_camera_VIDIOCSWIN(g_camera_context, param); -+ -+ /*set capture output format*/ -+ case VIDIOCSPICT: -+ return pxa_camera_VIDIOCSPICT(g_camera_context, param); -+ -+ /*get capture output format*/ -+ case VIDIOCGPICT: -+ return pxa_camera_VIDIOCGPICT(g_camera_context, param); -+ -+ /*start capture */ -+ case VIDIOCCAPTURE: -+ return pxa_camera_VIDIOCCAPTURE(g_camera_context, param); -+ -+ /* mmap interface */ -+ case VIDIOCGMBUF: -+ return pxa_camera_VIDIOCGMBUF(g_camera_context, param); -+ -+ /* Application extended IOCTL. */ -+ /* Register access interface */ -+ case WCAM_VIDIOCSINFOR: -+ return pxa_camera_WCAM_VIDIOCSINFOR(g_camera_context, param); -+ -+ /*get capture format*/ -+ case WCAM_VIDIOCGINFOR: -+ return pxa_camera_WCAM_VIDIOCGINFOR(g_camera_context, param); -+ -+ /*get ci reg value*/ -+ case WCAM_VIDIOCGCIREG: -+ return pxa_camera_WCAM_VIDIOCGCIREG(g_camera_context, param); -+ -+ /*set ci reg*/ -+ case WCAM_VIDIOCSCIREG: -+ return pxa_camera_WCAM_VIDIOCSCIREG(g_camera_context, param); -+#ifdef CONFIG_CAMERA_MT9M111 -+ -+ /*read mt9m111 registers*/ -+ case WCAM_VIDIOCGCAMREG: -+ return pxa_camera_WCAM_VIDIOCGCAMREG(g_camera_context, param); -+ -+ /*write mt9m111 registers*/ -+ case WCAM_VIDIOCSCAMREG: -+ return pxa_camera_WCAM_VIDIOCSCAMREG(g_camera_context, param); -+ -+ /*set sensor size */ -+ case WCAM_VIDIOCSSSIZE: -+ return pxa_cam_WCAM_VIDIOCSSSIZE(g_camera_context, param); -+ -+ /*get sensor size */ -+ case WCAM_VIDIOCGSSIZE: -+ return pxa_cam_WCAM_VIDIOCGSSIZE(g_camera_context, param); -+ -+ /*set output size*/ -+ case WCAM_VIDIOCSOSIZE: -+ return pxa_cam_WCAM_VIDIOCSOSIZE(g_camera_context, param); -+ -+ /*get output size*/ -+ case WCAM_VIDIOCGOSIZE: -+ return pxa_cam_WCAM_VIDIOCGOSIZE(g_camera_context, param); -+ -+ /*set video mode fps*/ -+ case WCAM_VIDIOCSFPS: -+ return pxa_cam_WCAM_VIDIOCSFPS(g_camera_context, param); -+ -+#endif -+ /*set picture style*/ -+ case WCAM_VIDIOCSSTYLE: -+ return pxa_cam_WCAM_VIDIOCSSTYLE(g_camera_context, param); -+ -+ /*set picture light*/ -+ case WCAM_VIDIOCSLIGHT: -+ return pxa_cam_WCAM_VIDIOCSLIGHT(g_camera_context, param); -+ -+ /*set picture brightness*/ -+ case WCAM_VIDIOCSBRIGHT: -+ return pxa_cam_WCAM_VIDIOCSBRIGHT(g_camera_context, param); -+ /*set frame buffer count*/ -+ case WCAM_VIDIOCSBUFCOUNT: -+ return pxa_cam_WCAM_VIDIOCSBUFCOUNT(g_camera_context, param); -+ -+ /*get cur avaliable frames*/ -+ case WCAM_VIDIOCGCURFRMS: -+ return pxa_cam_WCAM_VIDIOCGCURFRMS(g_camera_context, param); -+ default: -+ { -+ //dbg_print ("mt9m111: Invalid ioctl parameters.cmd = %d\n",cmd); -+ return -ENOIOCTLCMD; -+ break; -+ } -+ } -+ return 0; -+} -+ -+static int pxa_camera_mmap(struct video_device *dev, const char *adr, unsigned long size) -+{ -+ unsigned long start = (unsigned long)adr; -+ camera_context_t *cam_ctx = g_camera_context; -+ struct page **p_page = cam_ctx->page_array; -+ -+ size = PAGE_ALIGN(size); -+ while (size > 0) -+ { -+ if(remap_page_range(start, page_to_phys(*p_page), PAGE_SIZE, PAGE_SHARED)) -+ { -+ return -EFAULT; -+ } -+ start += PAGE_SIZE; -+ p_page++; -+ size -= PAGE_SIZE; -+ } -+ return 0; -+ } -+ -+unsigned int pxa_camera_poll(struct video_device *dev, struct file *file, poll_table *wait) -+{ -+ camera_context_t *cam_ctx = g_camera_context; -+ static int waited = 0; -+ -+ poll_wait(file, &camera_wait_q, wait); -+ -+ if(still_image_mode == 1 && still_image_rdy == 1) -+ { -+ still_image_rdy = 0; -+ waited = 0; -+ return POLLIN | POLLRDNORM; -+ } -+ -+ if(first_video_frame == 1) -+ first_video_frame = 0; -+ else if(still_image_mode == 0 && waited != 1) -+ cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number; -+ -+ if(cam_ctx->block_header == cam_ctx->block_tail) -+ { -+ //dbg_print ("enter waiting, tail = %d, header = %d \n", cam_ctx->block_tail, cam_ctx->block_header); -+ task_waiting = 1; -+ waited = 1; -+ //interruptible_sleep_on (&camera_wait_q); -+ return 0; -+ } -+ else -+ { -+ waited = 0; -+ } -+ -+ return POLLIN | POLLRDNORM; -+} -+ -+int pxa_camera_mem_deinit() -+{ -+ if(g_camera_context) -+ { -+ if(g_camera_context->dma_descriptors_virtual != NULL) -+ { -+ consistent_free(g_camera_context->dma_descriptors_virtual, -+ MAX_DESC_NUM * sizeof(pxa_dma_desc), -+ (int)g_camera_context->dma_descriptors_physical); -+ -+ g_camera_context->dma_descriptors_virtual = NULL; -+ -+ } -+ if(g_camera_context->buffer_virtual != NULL) -+ { -+ pxa_dma_buffer_free(g_camera_context); -+ g_camera_context->buffer_virtual = NULL; -+ } -+ kfree(g_camera_context); -+ g_camera_context = NULL; -+ } -+ -+ return 0; -+} -+ -+int pxa_camera_mem_init() -+{ -+ g_camera_context = kmalloc(sizeof(struct camera_context_s), GFP_KERNEL); -+ -+ if(g_camera_context == NULL) -+ { -+ dbg_print( "PXA_CAMERA: Cann't allocate buffer for camera control structure \n"); -+ return -1; -+ } -+ -+ memset(g_camera_context, 0, sizeof(struct camera_context_s)); -+ -+ g_camera_context->dma_started = 0; -+ g_camera_context->dma_descriptors_virtual = consistent_alloc(GFP_KERNEL, MAX_DESC_NUM * sizeof(pxa_dma_desc), -+ (void *)&(g_camera_context->dma_descriptors_physical)); -+ if(g_camera_context->dma_descriptors_virtual == NULL) -+ { -+ dbg_print("consistent alloc memory for dma_descriptors_virtual fail!"); -+ goto err_init; -+ } -+ -+ g_camera_context->buf_size = BUF_SIZE_DEFT; -+ g_camera_context->dma_descriptors_size = MAX_DESC_NUM; -+ -+ -+ if(pxa_dma_buffer_init(g_camera_context) != 0) -+ { -+ dbg_print("alloc memory for buffer_virtual %d bytes fail!", g_camera_context->buf_size); -+ goto err_init; -+ } -+#ifdef CONFIG_CAMERA_MT9M111 -+ // init function dispatch table -+ mt9m111_func.init = camera_func_mt9m111_init; -+ mt9m111_func.deinit = camera_func_mt9m111_deinit; -+ mt9m111_func.set_capture_format = camera_func_mt9m111_set_capture_format; -+ mt9m111_func.start_capture = camera_func_mt9m111_start_capture; -+ mt9m111_func.stop_capture = camera_func_mt9m111_stop_capture; -+ -+ g_camera_context->camera_functions = &mt9m111_func; -+#endif -+ dbg_print("success!"); -+ return 0; -+ -+err_init: -+ pxa_camera_mem_deinit(); -+ return -1; -+} -+ -+int pxa_camera_video_init(struct video_device *vdev) -+{ -+ return 0; -+} -+ -+static struct video_device vd = { -+ owner: THIS_MODULE, -+ name: "E680 camera", -+ type: VID_TYPE_CAPTURE, -+ hardware: VID_HARDWARE_PXA_CAMERA, /* FIXME */ -+ open: pxa_camera_open, -+ close: pxa_camera_close, -+ read: pxa_camera_read, -+ poll: pxa_camera_poll, -+ ioctl: pxa_camera_ioctl, -+ mmap: pxa_camera_mmap, -+ initialize: pxa_camera_video_init, -+ minor: -1, -+}; -+ -+ -+ -+ -+#define MIN(a, b) ((a) < (b) ? (a) : (b)) -+#define MAX_WRITE_LEN 12 -+static ssize_t camera_write (struct file *file, const char *buf, size_t count, loff_t * pos) -+{ -+ -+ char feedback[2*MAX_WRITE_LEN + 1] ={0}; -+ char feedback1[2*MAX_WRITE_LEN + 1] = {0}; -+ size_t n = count; -+ size_t l; -+ char c; -+ int i,x,y,t; -+ -+ u16 reg, value; -+ -+ MOD_INC_USE_COUNT; -+ if (n > 0) -+ { -+ l = MIN (n, MAX_WRITE_LEN); -+ if (copy_from_user (feedback, buf, l)) -+ { -+ count = -EFAULT; -+ } -+ else -+ { -+ if (l > 0 && feedback[l - 1] == '\n') -+ { -+ l -= 1; -+ } -+ feedback[l] = 0; -+ n -= l; -+ // flush remainder, if any -+ while (n > 0) -+ { -+ // Not too efficient, but it shouldn't matter -+ if (copy_from_user (&c, buf + (count - n), 1)) -+ { -+ count = -EFAULT; -+ break; -+ } -+ n -= 1; -+ } -+ } -+ } -+ -+ i=1; -+ x=1; -+ y=1; -+ if (count > 0 && feedback[0] == '{') -+ { -+ while(feedback[i] != '}' && i<=MAX_WRITE_LEN*2) -+ { -+ c= feedback[i]; -+ i++; -+ if(c>='a' && c<='f') -+ { -+ c-=0x20; -+ } -+ if(!((c>='0'&& c<='9')||(c>='A'&&c<='F')||c==',')) -+ { -+ continue; -+ } -+ feedback1[x++] = c; -+ } -+ -+ feedback1[x]='}'; -+ feedback1[0]='{'; -+ for(i=1;i<=x;i++) -+ { -+ if(feedback1[i] == ',') -+ { -+ y=3; -+ for(t=i-1;t>=1;t--) -+ { -+ if(y==0) -+ break; -+ feedback[y--]=feedback1[t]; -+ } -+ if(y>=1) -+ { -+ for(t=y;t>=1;t--) -+ { -+ feedback[t] = '0'; -+ } -+ } -+ } -+ -+ if(feedback1[i] == '}') -+ { -+ y=8; -+ for(t=i-1;feedback1[t]!=','&&t>=1;t--) -+ { -+ if(y==4) -+ break; -+ feedback[y--]=feedback1[t]; -+ } -+ if(y>=5) -+ { -+ for(t=y;t>=5;t--) -+ { -+ feedback[t] = '0'; -+ } -+ } -+ } -+ } -+ -+ -+ reg = 16 * 16 * (feedback[1]>='A'?feedback[1]-'A'+10:feedback[1]-0x30) + 16 * (feedback[2]>='A'?feedback[2]-'A'+10:feedback[2]-0x30) + (feedback[3]>='A'?feedback[3]-'A'+10:feedback[3]-0x30) ; -+ value = 16 * 16 * 16 * (feedback[5]>='A'?feedback[5]-'A'+10:feedback[5]-0x30) + 16 *16* (feedback[6]>='A'?feedback[6]-'A'+10:feedback[6]-0x30) + 16 * (feedback[7]>='A'?feedback[7]-'A'+10:feedback[7]-0x30) + (feedback[8]>='A'?feedback[8]-'A'+10:feedback[8]-0x30) ; -+ -+ if(reg == 0xFFF && value == 0xFFFF) -+ { -+ mt9m111_dump_register(0,0x2ff,NULL); -+ } -+ else if(reg == 0xFFF) -+ { -+ mt9m111_reg_read(value); -+ } -+ else -+ mt9m111_write(reg, value); -+ } -+ MOD_DEC_USE_COUNT; -+ -+ return (count); -+} -+ -+ -+static struct file_operations camera_funcs = { -+ read:NULL, -+ write:camera_write, -+}; -+ -+ -+static int __init pxa_camera_init(void) -+{ -+ struct proc_dir_entry *pw; -+ /* 1. mapping CI registers, so that we can access the CI */ -+ if(request_irq(IRQ_CAMERA, pxa_camera_irq, 0, "PXA Camera", &vd)) -+ { -+ dbg_print ("Camera interrupt register failed failed number \n"); -+ return -EIO; -+ } -+ dbg_print ("Camera interrupt register successful \n"); -+ -+ -+ ci_dma_y = pxa_request_dma("CI_Y",DMA_PRIO_HIGH, pxa_ci_dma_irq_y, &vd); -+ if(ci_dma_y < 0) -+ { -+ dbg_print( "PXA_CAMERA: Cann't request DMA for Y\n"); -+ return -EIO; -+ } -+ dbg_print( "PXA_CAMERA: Request DMA for Y successfully [%d]\n",ci_dma_y); -+ -+ ci_dma_cb = pxa_request_dma("CI_Cb",DMA_PRIO_HIGH, pxa_ci_dma_irq_cb, &vd); -+ if(ci_dma_cb < 0) -+ { -+ dbg_print( "PXA_CAMERA: Cann't request DMA for Cb\n"); -+ return -EIO; -+ } -+ dbg_print( "PXA_CAMERA: Request DMA for Cb successfully [%d]\n",ci_dma_cb); -+ -+ ci_dma_cr = pxa_request_dma("CI_Cr",DMA_PRIO_HIGH, pxa_ci_dma_irq_cr, &vd); -+ if(ci_dma_cr < 0) -+ { -+ dbg_print( "PXA_CAMERA: Cann't request DMA for Cr\n"); -+ return -EIO; -+ } -+ -+ dbg_print( "PXA_CAMERA: Request DMA for Cr successfully [%d]\n",ci_dma_cr); -+ -+ -+ DRCMR68 = ci_dma_y | DRCMR_MAPVLD; -+ DRCMR69 = ci_dma_cb | DRCMR_MAPVLD; -+ DRCMR70 = ci_dma_cr | DRCMR_MAPVLD; -+ -+#ifdef CONFIG_CAMERA_OV9640 -+ minor =1; -+#endif -+ -+#ifdef CONFIG_CAMERA_MT9M111 -+ minor =0 ; -+#endif -+ -+ if(video_register_device(&vd, VFL_TYPE_GRABBER, minor) < 0) -+ { -+ dbg_print("PXA_CAMERA: video_register_device failed\n"); -+ return -EIO; -+ } -+ -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, camera_pm_callback); -+#endif -+ -+ dbg_print("PXA_CAMERA: video_register_device successfully. /dev/video%d \n",minor); -+ -+ if ((pw = create_proc_entry ("cam", 0666, 0)) == NULL) -+ { -+ return -ENOMEM; -+ } -+ pw->proc_fops = &camera_funcs; -+ -+ return 0; -+} -+ -+static void __exit pxa_camera_exit(void) -+{ -+ -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+ if(ci_dma_y) -+ { -+ pxa_free_dma(ci_dma_y); -+ ci_dma_y = 0; -+ } -+ if(ci_dma_cb) -+ { -+ pxa_free_dma(ci_dma_cb); -+ ci_dma_cb = 0; -+ } -+ if(ci_dma_cr) -+ { -+ pxa_free_dma(ci_dma_cr); -+ ci_dma_cr = 0; -+ } -+ -+ DRCMR68 = 0; -+ DRCMR69 = 0; -+ DRCMR70 = 0; -+ -+ pxa_camera_mem_deinit(); -+ -+ free_irq(IRQ_CAMERA, &vd); -+ -+ video_unregister_device(&vd); -+ -+ -+ remove_proc_entry ("cam", NULL); -+ -+} -+ -+ -+//------------------------------------------------------------------------------------------------------- -+// Configuration APIs -+//------------------------------------------------------------------------------------------------------- -+void ci_set_frame_rate(CI_FRAME_CAPTURE_RATE frate) -+{ -+ unsigned int value; -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_FR_RATE_SMASK << CI_CICR4_FR_RATE_SHIFT); -+ value |= (unsigned)frate << CI_CICR4_FR_RATE_SHIFT; -+ CICR4 = value; -+} -+ -+CI_FRAME_CAPTURE_RATE ci_get_frame_rate(void) -+{ -+ unsigned int value; -+ value = CICR4; -+ return (CI_FRAME_CAPTURE_RATE)((value >> CI_CICR4_FR_RATE_SHIFT) & CI_CICR4_FR_RATE_SMASK); -+} -+ -+void ci_set_image_format(CI_IMAGE_FORMAT input_format, CI_IMAGE_FORMAT output_format) -+{ -+ -+ unsigned int value, tbit, rgbt_conv, rgb_conv, rgb_f, ycbcr_f, rgb_bpp, raw_bpp, cspace; -+ // write cicr1: preserve ppl value and data width value -+ dbg_print("0"); -+ value = CICR1; -+ dbg_print("1"); -+ value &= ( (CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT) | ((CI_CICR1_DW_SMASK) << CI_CICR1_DW_SHIFT)); -+ tbit = rgbt_conv = rgb_conv = rgb_f = ycbcr_f = rgb_bpp = raw_bpp = cspace = 0; -+ switch(input_format) -+ { -+ case CI_RAW8: -+ cspace = 0; -+ raw_bpp = 0; -+ break; -+ case CI_RAW9: -+ cspace = 0; -+ raw_bpp = 1; -+ break; -+ case CI_RAW10: -+ cspace = 0; -+ raw_bpp = 2; -+ break; -+ case CI_YCBCR422: -+ case CI_YCBCR422_PLANAR: -+ cspace = 2; -+ if(output_format == CI_YCBCR422_PLANAR) -+ { -+ ycbcr_f = 1; -+ } -+ break; -+ case CI_RGB444: -+ cspace = 1; -+ rgb_bpp = 0; -+ break; -+ case CI_RGB555: -+ cspace = 1; -+ rgb_bpp = 1; -+ if(output_format == CI_RGBT555_0) -+ { -+ rgbt_conv = 2; -+ tbit = 0; -+ } -+ else if(output_format == CI_RGBT555_1) -+ { -+ rgbt_conv = 2; -+ tbit = 1; -+ } -+ break; -+ case CI_RGB565: -+ cspace = 1; -+ rgb_bpp = 2; -+ rgb_f = 1; -+ break; -+ case CI_RGB666: -+ cspace = 1; -+ rgb_bpp = 3; -+ if(output_format == CI_RGB666_PACKED) -+ { -+ rgb_f = 1; -+ } -+ break; -+ case CI_RGB888: -+ case CI_RGB888_PACKED: -+ cspace = 1; -+ rgb_bpp = 4; -+ switch(output_format) -+ { -+ case CI_RGB888_PACKED: -+ rgb_f = 1; -+ break; -+ case CI_RGBT888_0: -+ rgbt_conv = 1; -+ tbit = 0; -+ break; -+ case CI_RGBT888_1: -+ rgbt_conv = 1; -+ tbit = 1; -+ break; -+ case CI_RGB666: -+ rgb_conv = 1; -+ break; -+ // RGB666 PACKED - JamesL -+ case CI_RGB666_PACKED: -+ rgb_conv = 1; -+ rgb_f = 1; -+ break; -+ // end -+ case CI_RGB565: -+ dbg_print("format : 565"); -+ rgb_conv = 2; -+ break; -+ case CI_RGB555: -+ rgb_conv = 3; -+ break; -+ case CI_RGB444: -+ rgb_conv = 4; -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ dbg_print("2"); -+ value |= (tbit==1) ? CI_CICR1_TBIT : 0; -+ value |= rgbt_conv << CI_CICR1_RGBT_CONV_SHIFT; -+ value |= rgb_conv << CI_CICR1_RGB_CONV_SHIFT; -+ value |= (rgb_f==1) ? CI_CICR1_RBG_F : 0; -+ value |= (ycbcr_f==1) ? CI_CICR1_YCBCR_F : 0; -+ value |= rgb_bpp << CI_CICR1_RGB_BPP_SHIFT; -+ value |= raw_bpp << CI_CICR1_RAW_BPP_SHIFT; -+ value |= cspace << CI_CICR1_COLOR_SP_SHIFT; -+ CICR1 = value; -+ -+} -+ -+void ci_set_mode(CI_MODE mode, CI_DATA_WIDTH data_width) -+{ -+ unsigned int value; -+ -+ // write mode field in cicr0 -+ value = CICR0; -+ value &= ~(CI_CICR0_SIM_SMASK << CI_CICR0_SIM_SHIFT); -+ value |= (unsigned int)mode << CI_CICR0_SIM_SHIFT; -+ CICR0 = value; -+ -+ // write data width cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_DW_SMASK << CI_CICR1_DW_SHIFT); -+ value |= ((unsigned)data_width) << CI_CICR1_DW_SHIFT; -+ CICR1 = value; -+ return; -+} -+ -+void ci_configure_mp(unsigned int ppl, unsigned int lpf, CI_MP_TIMING* timing) -+{ -+ unsigned int value; -+ // write ppl field in cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT); -+ value |= (ppl & CI_CICR1_PPL_SMASK) << CI_CICR1_PPL_SHIFT; -+ CICR1 = value; -+ -+ // write BLW, ELW in cicr2 -+ value = CICR2; -+ value &= ~(CI_CICR2_BLW_SMASK << CI_CICR2_BLW_SHIFT | CI_CICR2_ELW_SMASK << CI_CICR2_ELW_SHIFT ); -+ value |= (timing->BLW & CI_CICR2_BLW_SMASK) << CI_CICR2_BLW_SHIFT; -+ CICR2 = value; -+ -+ // write BFW, LPF in cicr3 -+ value = CICR3; -+ value &= ~(CI_CICR3_BFW_SMASK << CI_CICR3_BFW_SHIFT | CI_CICR3_LPF_SMASK << CI_CICR3_LPF_SHIFT ); -+ value |= (timing->BFW & CI_CICR3_BFW_SMASK) << CI_CICR3_BFW_SHIFT; -+ value |= (lpf & CI_CICR3_LPF_SMASK) << CI_CICR3_LPF_SHIFT; -+ CICR3 = value; -+ -+} -+ -+void ci_configure_sp(unsigned int ppl, unsigned int lpf, CI_SP_TIMING* timing) -+{ -+ unsigned int value; -+ -+ // write ppl field in cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT); -+ value |= (ppl & CI_CICR1_PPL_SMASK) << CI_CICR1_PPL_SHIFT; -+ CICR1 = value; -+ -+ // write cicr2 -+ value = CICR2; -+ value |= (timing->BLW & CI_CICR2_BLW_SMASK) << CI_CICR2_BLW_SHIFT; -+ value |= (timing->ELW & CI_CICR2_ELW_SMASK) << CI_CICR2_ELW_SHIFT; -+ value |= (timing->HSW & CI_CICR2_HSW_SMASK) << CI_CICR2_HSW_SHIFT; -+ value |= (timing->BFPW & CI_CICR2_BFPW_SMASK) << CI_CICR2_BFPW_SHIFT; -+ value |= (timing->FSW & CI_CICR2_FSW_SMASK) << CI_CICR2_FSW_SHIFT; -+ CICR2 = value; -+ -+ // write cicr3 -+ value = CICR3; -+ value |= (timing->BFW & CI_CICR3_BFW_SMASK) << CI_CICR3_BFW_SHIFT; -+ value |= (timing->EFW & CI_CICR3_EFW_SMASK) << CI_CICR3_EFW_SHIFT; -+ value |= (timing->VSW & CI_CICR3_VSW_SMASK) << CI_CICR3_VSW_SHIFT; -+ value |= (lpf & CI_CICR3_LPF_SMASK) << CI_CICR3_LPF_SHIFT; -+ CICR3 = value; -+ return; -+} -+ -+void ci_configure_ms(unsigned int ppl, unsigned int lpf, CI_MS_TIMING* timing) -+{ -+ // the operation is same as Master-Parallel -+ ci_configure_mp(ppl, lpf, (CI_MP_TIMING*)timing); -+} -+ -+void ci_configure_ep(int parity_check) -+{ -+ unsigned int value; -+ -+ // write parity_enable field in cicr0 -+ value = CICR0; -+ if(parity_check) -+ { -+ value |= CI_CICR0_PAR_EN; -+ } -+ else -+ { -+ value &= ~CI_CICR0_PAR_EN; -+ } -+ CICR0 = value; -+ return; -+} -+ -+void ci_configure_es(int parity_check) -+{ -+ // the operationi is same as Embedded-Parallel -+ ci_configure_ep(parity_check); -+} -+ -+void ci_set_clock(unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz) -+{ -+ unsigned int ciclk, value, div, cccr_l, K; -+ -+ // determine the LCLK frequency programmed into the CCCR. -+ cccr_l = (CCCR & 0x0000001F); -+ -+ if(cccr_l < 8) -+ K = 1; -+ else if(cccr_l < 17) -+ K = 2; -+ else -+ K = 3; -+ -+ ciclk = (13 * cccr_l) / K; -+ -+ div = (ciclk + mclk_khz) / ( 2 * mclk_khz ) - 1 ; -+ dbg_print("cccr=%xciclk=%d,cccr_l=%d,K=%d,div=%d\n",CCCR,ciclk,cccr_l,K,div); -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | CI_CICR4_DIV_SMASK<<CI_CICR4_DIV_SHIFT); -+ value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0; -+ value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0; -+ value |= div << CI_CICR4_DIV_SHIFT; -+ CICR4 = value; -+ return; -+} -+ -+void ci_set_polarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low) -+{ -+ dbg_print(""); -+ unsigned int value; -+ -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_PCP | CI_CICR4_HSP | CI_CICR4_VSP); -+ value |= (pclk_sample_falling)? CI_CICR4_PCP : 0; -+ value |= (hsync_active_low) ? CI_CICR4_HSP : 0; -+ value |= (vsync_active_low) ? CI_CICR4_VSP : 0; -+ CICR4 = value; -+ return; -+} -+ -+void ci_set_fifo(unsigned int timeout, CI_FIFO_THRESHOLD threshold, int fifo1_enable, -+ int fifo2_enable) -+{ -+ unsigned int value; -+ dbg_print(""); -+ // write citor -+ CITOR = timeout; -+ -+ // write cifr: always enable fifo 0! also reset input fifo -+ value = CIFR; -+ value &= ~(CI_CIFR_FEN0 | CI_CIFR_FEN1 | CI_CIFR_FEN2 | CI_CIFR_RESETF | -+ CI_CIFR_THL_0_SMASK<<CI_CIFR_THL_0_SHIFT); -+ value |= (unsigned int)threshold << CI_CIFR_THL_0_SHIFT; -+ value |= (fifo1_enable) ? CI_CIFR_FEN1 : 0; -+ value |= (fifo2_enable) ? CI_CIFR_FEN2 : 0; -+ value |= CI_CIFR_RESETF | CI_CIFR_FEN0; -+ CIFR = value; -+} -+ -+void ci_reset_fifo() -+{ -+ unsigned int value; -+ value = CIFR; -+ value |= CI_CIFR_RESETF; -+ CIFR = value; -+} -+ -+void ci_set_int_mask(unsigned int mask) -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value &= ~CI_CICR0_INTERRUPT_MASK; -+ value |= (mask & CI_CICR0_INTERRUPT_MASK); -+ dbg_print("-----------value=0x%x\n",value); -+ CICR0 = value; -+ return; -+} -+ -+unsigned int ci_get_int_mask() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ return (value & CI_CICR0_INTERRUPT_MASK); -+} -+ -+void ci_clear_int_status(unsigned int status) -+{ -+ // write 1 to clear -+ CISR = status; -+} -+ -+unsigned int ci_get_int_status() -+{ -+ int value; -+ -+ value = CISR; -+ -+ return value; -+} -+ -+void ci_set_reg_value(unsigned int reg_offset, unsigned int value) -+{ -+ CI_REG((u32)(ci_regs_base) + reg_offset) = value; -+} -+ -+int ci_get_reg_value(unsigned int reg_offset) -+{ -+ int value; -+ -+ value = CI_REG((u32)(ci_regs_base) + reg_offset); -+ return value; -+} -+ -+//------------------------------------------------------------------------------------------------------- -+// Control APIs -+//------------------------------------------------------------------------------------------------------- -+int ci_init() -+{ -+// (unsigned long*)ci_regs_base = (unsigned long*)ioremap(CI_REGS_PHYS, CI_REG_SIZE); -+ -+// if(ci_regs_base == NULL) -+// { -+// dbg_print ("ci regs base apply failed \n"); -+// return -1; -+// } -+ -+ // clear all CI registers -+ CICR0 = 0x3FF; // disable all interrupts -+ CICR1 = 0; -+ CICR2 = 0; -+ CICR3 = 0; -+ CICR4 = 0; -+ CISR = ~0; -+ CIFR = 0; -+ CITOR = 0; -+ -+ // enable CI clock -+ CKEN |= CKEN24_CAMERA; -+ return 0; -+} -+ -+void ci_deinit() -+{ -+ // disable CI clock -+ CKEN &= ~CKEN24_CAMERA; -+} -+ -+void ci_enable(int dma_en) -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value |= CI_CICR0_ENB; -+ if(dma_en) { -+ value |= CI_CICR0_DMA_EN; -+ } -+ CICR0 = value; -+ return; -+} -+ -+int ci_disable(int quick) -+{ -+ volatile unsigned int value, mask; -+ int retry; -+ -+ // write control bit in cicr0 -+ value = CICR0; -+ if(quick) -+ { -+ value &= ~CI_CICR0_ENB; -+ mask = CI_CISR_CQD; -+ } -+ else -+ { -+ value |= CI_CICR0_DIS; -+ mask = CI_CISR_CDD; -+ } -+ CICR0 = value; -+ -+ // wait shutdown complete -+ retry = 50; -+ while ( retry-- > 0 ) -+ { -+ value = CISR; -+ if( value & mask ) -+ { -+ CISR = mask; -+ return 0; -+ } -+ mdelay(10); -+ } -+ -+ return -1; -+} -+ -+void ci_slave_capture_enable() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value |= CI_CICR0_SL_CAP_EN; -+ CICR0 = value; -+ return; -+} -+ -+void ci_slave_capture_disable() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value &= ~CI_CICR0_SL_CAP_EN; -+ CICR0 = value; -+ return; -+} -+ -+void pxa_ci_dma_irq_y(int channel, void *data, struct pt_regs *regs) -+{ -+ -+ static int dma_repeated = 0; -+ camera_context_t *cam_ctx = g_camera_context; -+ int dcsr; -+ -+ //dbg_print (""); -+ dcsr = DCSR(channel); -+ DCSR(channel) = dcsr & ~DCSR_STOPIRQEN; -+#ifdef CONFIG_OV9640 -+ if(dma_repeated==1) -+ repeated_n++; -+ else -+ irq_n ++; -+#endif -+ if(irq_n <14) -+ { -+ irq_n++; -+ } -+ else -+ {irq_n=0; -+ dbg_print("got 15 frame !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); -+ } -+ if(still_image_mode == 1) -+ { -+ -+ if(task_waiting == 1) -+ { -+ wake_up_interruptible (&camera_wait_q); -+ task_waiting = 0; -+ } -+ //else -+ { -+ still_image_rdy = 1; -+ stop_dma_transfer(g_camera_context); -+ dbg_print("Photo ready!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); -+ } -+ } -+ else if(dma_repeated == 0 && -+ (cam_ctx->block_tail == ((cam_ctx->block_header + 2) % cam_ctx->block_number))) -+ { -+ dma_repeated = 1; -+ pxa_dma_repeat(cam_ctx); -+ //dbg_print ("DMA repeated."); -+ cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ } -+ else if(dma_repeated == 1 && -+ (cam_ctx->block_tail != ((cam_ctx->block_header + 1) % cam_ctx->block_number)) && -+ (cam_ctx->block_tail != ((cam_ctx->block_header + 2) % cam_ctx->block_number))) -+ { -+ pxa_dma_continue(cam_ctx); -+ //dbg_print ("DMA continue."); -+ dma_repeated = 0; -+ /* -+ if(task_waiting == 1) -+ { -+ wake_up_interruptible (&camera_wait_q); -+ task_waiting = 0; -+ } -+ */ -+ } -+ else if(dma_repeated == 0) -+ { -+ cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ /* -+ if(task_waiting == 1) -+ { -+ wake_up_interruptible (&camera_wait_q); -+ task_waiting = 0; -+ } -+ */ -+ } -+ -+ if(task_waiting == 1 && !(cam_ctx->block_header == cam_ctx->block_tail)) -+ { -+ wake_up_interruptible (&camera_wait_q); -+ task_waiting = 0; -+ } -+ -+ //dbg_print("Get a frame: block-tail = %d, block-header = %d \n", cam_ctx->block_tail, cam_ctx->block_header); -+} -+ -+void pxa_ci_dma_irq_cb(int channel, void *data, struct pt_regs *regs) -+{ -+ return; -+} -+ -+void pxa_ci_dma_irq_cr(int channel, void *data, struct pt_regs *regs) -+{ -+ return; -+} -+ -+ -+void pxa_camera_irq(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ int cisr; -+ static int dma_started=0; -+ camera_irq_n++; -+ disable_irq(IRQ_CAMERA); -+ cisr = CISR; -+ if(cisr & CI_CISR_SOF) -+ { -+ if(dma_started == 0) -+ { -+ dma_started = 1; -+ } -+ CISR |= CI_CISR_SOF; -+ } -+ if(cisr & CI_CISR_EOF) -+ { -+ CISR |= CI_CISR_EOF; -+ } -+ enable_irq(IRQ_CAMERA); -+} -+ -+void pxa_dma_repeat(camera_context_t *cam_ctx) -+{ -+ pxa_dma_desc *cnt_head, *cnt_tail; -+ int cnt_block; -+ -+ cnt_block = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ -+ // FIFO0 -+ (pxa_dma_desc *)cnt_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + -+ cnt_block * cam_ctx->fifo0_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo0_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+ -+ // FIFO1 -+ if(cam_ctx->fifo1_transfer_size) -+ { -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + -+ cnt_block * cam_ctx->fifo1_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo1_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ -+ // FIFO2 -+ if(cam_ctx->fifo2_transfer_size) -+ { -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + -+ cnt_block * cam_ctx->fifo2_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo2_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ } -+ -+void pxa_dma_continue(camera_context_t *cam_ctx) -+{ -+ pxa_dma_desc *cnt_head, *cnt_tail; -+ pxa_dma_desc *next_head; -+ int cnt_block, next_block; -+ -+ cnt_block = cam_ctx->block_header; -+ next_block = (cnt_block + 1) % cam_ctx->block_number; -+ -+ // FIFO0 -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + -+ cnt_block * cam_ctx->fifo0_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo0_num_descriptors - 1; -+ -+ next_head = (pxa_dma_desc *)cam_ctx->fifo0_descriptors_virtual + -+ next_block * cam_ctx->fifo0_num_descriptors; -+ -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+ -+ // FIFO1 -+ if(cam_ctx->fifo1_transfer_size) -+ { -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + -+ cnt_block * cam_ctx->fifo1_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo1_num_descriptors - 1; -+ -+ next_head = (pxa_dma_desc *)cam_ctx->fifo1_descriptors_virtual + -+ next_block * cam_ctx->fifo1_num_descriptors; -+ -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ -+ // FIFO2 -+ if(cam_ctx->fifo2_transfer_size) -+ { -+ cnt_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + -+ cnt_block * cam_ctx->fifo2_num_descriptors; -+ -+ cnt_tail = cnt_head + cam_ctx->fifo2_num_descriptors - 1; -+ -+ next_head = (pxa_dma_desc *)cam_ctx->fifo2_descriptors_virtual + -+ next_block * cam_ctx->fifo2_num_descriptors; -+ -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ return; -+ -+} -+ -+void ci_dump(void) -+{ -+ dbg_print ("CICR0 = 0x%8x ", CICR0); -+ dbg_print ("CICR1 = 0x%8x ", CICR1); -+ dbg_print ("CICR2 = 0x%8x ", CICR2); -+ dbg_print ("CICR3 = 0x%8x ", CICR3); -+ dbg_print ("CICR4 = 0x%8x ", CICR4); -+ dbg_print ("CISR = 0x%8x ", CISR); -+ dbg_print ("CITOR = 0x%8x ", CITOR); -+ dbg_print ("CIFR = 0x%8x ", CIFR); -+} -+ -+ -+module_init(pxa_camera_init); -+module_exit(pxa_camera_exit); -+ -+MODULE_DESCRIPTION("Bulverde Camera Interface driver"); -+MODULE_LICENSE("GPL"); -+EXPORT_NO_SYMBOL; -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/drivers/media/video/pxa_camera_ov.c linux-2.6.16.5-exz/drivers/media/video/pxa_camera_ov.c ---- linux-2.6.16.5/drivers/media/video/pxa_camera_ov.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/drivers/media/video/pxa_camera_ov.c 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,2449 @@ -+/* -+ * pxa_camera.c -+ * -+ * Bulverde Processor Camera Interface driver. -+ * -+ * Copyright (C) 2003, Intel Corporation -+ * Copyright (C) 2003, Montavista Software Inc. -+ * -+ * Author: Intel Corporation Inc. -+ * MontaVista Software, Inc. -+ * source@mvista.com -+ * -+ * 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 program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * 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/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/init.h> -+#include <linux/fs.h> -+#include <linux/vmalloc.h> -+#include <linux/delay.h> -+#include <linux/slab.h> -+#include <linux/proc_fs.h> -+#include <linux/ctype.h> -+#include <linux/pagemap.h> -+#include <linux/wrapper.h> -+#include <linux/videodev.h> -+#include <linux/pci.h> -+#include <linux/pm.h> -+#include <linux/poll.h> -+#include <linux/wait.h> -+#ifdef CONFIG_DPM -+#include <linux/device.h> -+#include <asm/arch/ldm.h> -+#endif -+ -+#include <linux/types.h> -+#include <asm/mach-types.h> -+#include <asm/io.h> -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/dma.h> -+#include <asm/irq.h> -+#include <asm/arch/irqs.h> -+ -+ -+#include "camera.h" -+ -+ -+#ifdef CONFIG_CAMERA_OV9640 -+#define OV9640 -+#elif defined CONFIG_CAMERA_ADCM2700 -+#define ADCM2700 -+#elif defined CONFIG_CAMERA_ADCM2650 -+#define ADCM2650 -+#endif -+ -+#ifdef ADCM2650 -+#include "pxa_camera.h" -+#include "adcm2650.h" -+#include "adcm2650_hw.h" -+#endif -+ -+#ifdef ADCM2700 -+#include "adcm2700.h" -+#include "adcm2700_hw.h" -+#endif -+ -+#ifdef OV9640 -+#include "ov9640.h" -+#include "ov9640_hw.h" -+#endif -+ -+#define PREFIX "PXA camera: " -+ -+#ifdef ADCM2650 -+#define MAX_WIDTH 480 -+#define MAX_HEIGHT 640 -+#define MIN_WIDTH 72 -+#define MIN_HEIGHT 72 -+#endif -+ -+#ifdef ADCM2700 -+#define MAX_WIDTH 480 -+#define MAX_HEIGHT 640 -+#define MIN_WIDTH 72 -+#define MIN_HEIGHT 72 -+#endif -+ -+#ifdef OV9640 -+/* in ov9640.h */ -+#endif -+ -+#define MAX_BPP 32 -+#define WIDTH_DEFT 320 -+#define HEIGHT_DEFT 240 -+#define FRAMERATE_DEFT 0x0 -+ -+ -+/* -+ * It is required to have at least 3 frames in buffer -+ * in current implementation -+ */ -+#define FRAMES_IN_BUFFER 3 -+#define MIN_FRAMES_IN_BUFFER 3 -+#define MAX_FRAME_SIZE (MAX_WIDTH * MAX_HEIGHT * (MAX_BPP >> 3)) -+#define BUF_SIZE_DEFT (MAX_FRAME_SIZE * MIN_FRAMES_IN_BUFFER) -+#define SINGLE_DESC_TRANS_MAX PAGE_SIZE -+#define MAX_DESC_NUM ((MAX_FRAME_SIZE / SINGLE_DESC_TRANS_MAX + 1) *\ -+ MIN_FRAMES_IN_BUFFER*2) -+ -+#define MAX_BLOCK_NUM 20 -+ -+static camera_context_t *g_camera_context = NULL; -+#ifdef ADCM2650 -+static camera_function_t adcm2650_func; -+#endif -+#ifdef ADCM2700 -+static camera_function_t adcm2700_func; -+#endif -+#ifdef OV9640 -+static camera_function_t ov9640_func; -+#endif -+wait_queue_head_t camera_wait_q; -+ -+/* /dev/videoX registration number */ -+static int minor = 0; -+static int ci_dma_y = -1; -+static int ci_dma_cb = -1; -+static int ci_dma_cr = -1; -+volatile int task_waiting = 0; -+static int still_image_mode = 0; -+static int still_image_rdy = 0; -+static int first_video_frame = 0; -+ -+void pxa_ci_dma_irq_y(int channel, void *data, struct pt_regs *regs); -+void pxa_ci_dma_irq_cb(int channel, void *data, struct pt_regs *regs); -+void pxa_ci_dma_irq_cr(int channel, void *data, struct pt_regs *regs); -+ -+static unsigned long ci_regs_base = 0; /* for CI registers IOMEM mapping */ -+ -+#define CI_REG(x) (* (volatile u32*)(x) ) -+#define CI_REG_SIZE 0x40 /* 0x5000_0000 --- 0x5000_0038 * 64K */ -+#define CI_REGS_PHYS 0x50000000 /* Start phyical address of CI registers */ -+/* placed in include/asm/arch/pxa_regs.h -+#define CICR0 CI_REG((u32)(ci_regs_base) + 0x00) -+#define CICR1 CI_REG((u32)(ci_regs_base) + 0x04) -+#define CICR2 CI_REG((u32)(ci_regs_base) + 0x08) -+#define CICR3 CI_REG((u32)(ci_regs_base) + 0x0c) -+#define CICR4 CI_REG((u32)(ci_regs_base) + 0x10) -+#define CISR CI_REG((u32)(ci_regs_base) + 0x14) -+#define CIFR CI_REG((u32)(ci_regs_base) + 0x18) -+#define CITOR CI_REG((u32)(ci_regs_base) + 0x1c) -+#define CIBR0 CI_REG((u32)(ci_regs_base) + 0x28) -+#define CIBR1 CI_REG((u32)(ci_regs_base) + 0x30) -+#define CIBR2 CI_REG((u32)(ci_regs_base) + 0x38) -+*/ -+/*********************************************************************** -+ * -+ * Declarations -+ * -+ ***********************************************************************/ -+ -+// map of camera image format (camera.h) ==> capture interface format (ci.h) -+static const CI_IMAGE_FORMAT FORMAT_MAPPINGS[] = { -+ CI_RAW8, //RAW -+ CI_RAW9, -+ CI_RAW10, -+ -+ CI_RGB444, //RGB -+ CI_RGB555, -+ CI_RGB565, -+ CI_RGB666_PACKED, //RGB Packed -+ CI_RGB666, -+ CI_RGB888_PACKED, -+ CI_RGB888, -+ CI_RGBT555_0, //RGB+Transparent bit 0 -+ CI_RGBT888_0, -+ CI_RGBT555_1, //RGB+Transparent bit 1 -+ CI_RGBT888_1, -+ -+ CI_INVALID_FORMAT, -+ CI_YCBCR422, //YCBCR -+ CI_YCBCR422_PLANAR, //YCBCR Planaried -+ CI_INVALID_FORMAT, -+ CI_INVALID_FORMAT -+}; -+ -+static int update_dma_chain(p_camera_context_t cam_ctx); -+void start_dma_transfer(p_camera_context_t cam_ctx, unsigned block_id); -+void stop_dma_transfer(p_camera_context_t cam_ctx); -+static int start_capture(p_camera_context_t cam_ctx, unsigned int block_id, unsigned int frames); -+ -+static void pxa_dma_repeat(camera_context_t * cam_ctx); -+static void pxa_dma_continue(camera_context_t * cam_ctx); -+ -+#ifdef ADCM2650 -+extern int adcm2650_pipeline_read(u16 reg_addr, u16 * reg_value); -+extern int adcm2650_pipeline_write(u16 reg_addr, u16 reg_value); -+#define sensor_pipeline_read adcm2650_pipeline_read -+#define sensor_pipeline_write adcm2650_pipeline_write -+ -+#endif -+ -+#ifdef ADCM2700 -+extern int adcm2700_pipeline_read(u16 reg_addr, u16 * reg_value); -+extern int adcm2700_pipeline_write(u16 reg_addr, u16 reg_value); -+#define sensor_pipeline_read adcm2700_pipeline_read -+#define sensor_pipeline_write adcm2700_pipeline_write -+#endif -+ -+#ifdef OV9640 -+//int ov9640_pipeline_read( u16 reg_addr, u16 * reg_value){return 0;} -+//int ov9640_pipeline_write( u16 reg_addr, u16 reg_value){return 0;} -+#define sensor_pipeline_read ov9640_read -+#define sensor_pipeline_write ov9640_write -+#endif -+/*************** -+ * -+ * DPM functions -+ * -+ ***************/ -+#ifdef CONFIG_DPM -+ -+static int last_buffer_id; -+ -+static int pxa_camera_dpm_suspend(struct device *dev, u32 state, u32 level) -+{ -+ DPRINTK(KERN_DEBUG PREFIX "DPM suspend (state %d, level %d)\n", state, level); -+ switch (level) { -+ case SUSPEND_POWER_DOWN: -+ if (g_camera_context->dma_started) { -+ DPRINTK(KERN_DEBUG PREFIX "DMA running, suspended\n"); -+ last_buffer_id = camera_get_last_frame_buffer_id(g_camera_context); -+ stop_dma_transfer(g_camera_context); -+ } -+ disable_irq(IRQ_CAMERA); -+ CKEN &= ~CKEN24_CAMERA; -+ break; -+ } -+ return 0; -+} -+ -+static int pxa_camera_dpm_resume(struct device *dev, u32 level) -+{ -+ DPRINTK(KERN_DEBUG PREFIX "DPM resume (level %d)\n", level); -+ switch (level) { -+ case RESUME_POWER_ON: -+ CKEN |= CKEN24_CAMERA; -+ enable_irq(IRQ_CAMERA); -+ if (g_camera_context->dma_started) { -+ DPRINTK(KERN_DEBUG PREFIX "resume DMA\n"); -+ start_dma_transfer(g_camera_context, last_buffer_id); -+ } -+ break; -+ } -+ return 0; -+} -+ -+static int pxa_camera_dpm_scale(struct bus_op_point *op, u32 level) -+{ -+ DPRINTK(KERN_DEBUG PREFIX "DPM scale (level %d)\n", level); -+ /* CCCR is changed - adjust clock */ -+ ci_set_clock(g_camera_context->clk_reg_base, 1, 1, 7 /* MCLK_DEFT in adcm2650.c */ ); -+ return 0; -+} -+ -+static struct device_driver pxa_camera_driver_ldm = { -+ name:"camera", -+ devclass:NULL, -+ probe:NULL, -+ suspend:pxa_camera_dpm_suspend, -+ resume:pxa_camera_dpm_resume, -+ scale:pxa_camera_dpm_scale, -+ remove:NULL, -+ constraints:NULL -+}; -+ -+static struct device pxa_camera_device_ldm = { -+ name:"PXA camera", -+ bus_id:"video", -+ driver:NULL, -+ power_state:DPM_POWER_ON -+}; -+ -+static void pxa_camera_ldm_register(void) -+{ -+ pxaebc_driver_register(&pxa_camera_driver_ldm); -+ pxaebc_device_register(&pxa_camera_device_ldm); -+} -+ -+static void pxa_camera_ldm_unregister(void) -+{ -+ pxaebc_driver_unregister(&pxa_camera_driver_ldm); -+ pxaebc_device_unregister(&pxa_camera_device_ldm); -+} -+#endif /* CONFIG_DPM */ -+#ifdef CONFIG_PM -+static struct pm_dev *pm_dev; -+static int resume_dma = 0; -+ -+static int pxa_camera_pm_suspend() -+{ -+ if (g_camera_context != NULL) { -+ if (g_camera_context->dma_started) { -+ dbg_print("camera running, suspended"); -+ stop_dma_transfer(g_camera_context); -+ resume_dma = 1; -+ } -+ } -+ -+ disable_irq(IRQ_CAMERA); -+ CKEN &= ~CKEN24_CAMERA; -+ return 0; -+} -+ -+static int pxa_camera_pm_resume() -+{ -+ CKEN |= CKEN24_CAMERA; -+ enable_irq(IRQ_CAMERA); -+ -+ DPRINTK(" in %s, camera running, resumed", __FUNCTION__); -+ if (g_camera_context != NULL) { -+ /* -+ */ -+ struct video_window vw; -+ vw.width = g_camera_context->capture_width; -+ vw.height = g_camera_context->capture_height; -+ ov9640_set_window(&vw); -+ -+ // set_bright(g_camera_context->capture_bright); -+ ov9640_set_expose_compensation(g_camera_context->capture_bright); -+ // set_fps(g_camera_context->fps, g_camera_context->mini_fps); -+ ov9640_set_fps(g_camera_context->fps); -+ // set_light(g_camera_context->capture_light); -+ ov9640_set_light_environment(g_camera_context->capture_light); -+ // set_style(g_camera_context->capture_style); -+ ov9640_set_special_effect(g_camera_context->capture_style); -+ -+ if (resume_dma == 1) { -+ camera_start_video_capture(g_camera_context, 0); -+ resume_dma = 0; -+ } -+ -+ } -+ -+ return 0; -+} -+static int camera_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ switch (req) { -+ case PM_SUSPEND: -+ pxa_camera_pm_suspend(); -+ break; -+ -+ case PM_RESUME: -+ pxa_camera_pm_resume(); -+ break; -+ -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+ -+/*********************************************************************** -+ * -+ * Private functions -+ * -+ ***********************************************************************/ -+ -+static int pxa_dma_buffer_init(p_camera_context_t cam_ctx) -+{ -+ struct page *page; -+ unsigned int pages; -+ unsigned int page_count; -+ -+ cam_ctx->pages_allocated = 0; -+ -+ pages = (PAGE_ALIGN(cam_ctx->buf_size) / PAGE_SIZE); -+ -+ cam_ctx->page_array = (struct page **) kmalloc(pages * sizeof(struct page *), GFP_KERNEL); -+ if (cam_ctx->page_array == NULL) { -+ return -ENOMEM; -+ } -+ memset(cam_ctx->page_array, 0, pages * sizeof(struct page *)); -+ -+ for (page_count = 0; page_count < pages; page_count++) { -+ page = alloc_page(GFP_KERNEL); -+ if (page == NULL) { -+ goto error; -+ } -+ cam_ctx->page_array[page_count] = page; -+ set_page_count(page, 1); -+ SetPageReserved(page); -+ } -+ cam_ctx->buffer_virtual = remap_page_array(cam_ctx->page_array, pages, GFP_KERNEL); -+ -+ if (cam_ctx->buffer_virtual == NULL) { -+ goto error; -+ } -+ -+ cam_ctx->pages_allocated = pages; -+ -+ return 0; -+ -+ error: -+ for (page_count = 0; page_count < pages; page_count++) { -+ if ((page = cam_ctx->page_array[page_count]) != NULL) { -+ ClearPageReserved(page); -+ set_page_count(page, 1); -+ put_page(page); -+ } -+ } -+ kfree(cam_ctx->page_array); -+ -+ return -ENOMEM; -+} -+ -+static void pxa_dma_buffer_free(p_camera_context_t cam_ctx) -+{ -+ struct page *page; -+ int page_count; -+ -+ if (cam_ctx->buffer_virtual == NULL) -+ return; -+ -+ vfree(cam_ctx->buffer_virtual); -+ -+ for (page_count = 0; page_count < cam_ctx->pages_allocated; page_count++) { -+ if ((page = cam_ctx->page_array[page_count]) != NULL) { -+ ClearPageReserved(page); -+ set_page_count(page, 1); -+ put_page(page); -+ } -+ } -+ kfree(cam_ctx->page_array); -+} -+ -+/* -+Generate dma descriptors -+Pre-condition: these variables must be set properly -+ block_number, fifox_transfer_size -+ dma_descriptors_virtual, dma_descriptors_physical, dma_descirptors_size -+Post-condition: these variables will be set -+ fifox_descriptors_virtual, fifox_descriptors_physical -+ fifox_num_descriptors -+*/ -+int update_dma_chain(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL; -+ int des_transfer_size, remain_size; -+ unsigned int i, j; -+ -+ int target_page_num; -+ -+ // clear descriptor pointers -+ cam_ctx->fifo0_descriptors_virtual = cam_ctx->fifo0_descriptors_physical = 0; -+ cam_ctx->fifo1_descriptors_virtual = cam_ctx->fifo1_descriptors_physical = 0; -+ cam_ctx->fifo2_descriptors_virtual = cam_ctx->fifo2_descriptors_physical = 0; -+ -+ // calculate how many descriptors are needed per frame -+ cam_ctx->fifo0_num_descriptors = cam_ctx->pages_per_fifo0; -+ -+ cam_ctx->fifo1_num_descriptors = cam_ctx->pages_per_fifo1; -+ -+ cam_ctx->fifo2_num_descriptors = cam_ctx->pages_per_fifo2; -+ -+ // check if enough memory to generate descriptors -+ if ((cam_ctx->fifo0_num_descriptors + cam_ctx->fifo1_num_descriptors + -+ cam_ctx->fifo2_num_descriptors) * cam_ctx->block_number > cam_ctx->dma_descriptors_size) -+ return -1; -+ -+ // generate fifo0 dma chains -+ cam_ctx->fifo0_descriptors_virtual = (unsigned) cam_ctx->dma_descriptors_virtual; -+ cam_ctx->fifo0_descriptors_physical = (unsigned) cam_ctx->dma_descriptors_physical; -+ cur_des_virtual = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual; -+ cur_des_physical = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_physical; -+ -+ for (i = 0; i < cam_ctx->block_number; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo0_transfer_size; -+ -+ // assume the blocks are stored consecutively -+ target_page_num = cam_ctx->pages_per_block * i; -+ -+ for (j = 0; j < cam_ctx->fifo0_num_descriptors; j++) { -+ // set descriptor -+ if (remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned) cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR0_PHY; // FIFO0 physical address -+ cur_des_virtual->dtadr = page_to_bus(cam_ctx->page_array[target_page_num]); -+ cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo0_descriptors_physical); -+ -+ // generate fifo1 dma chains -+ if (cam_ctx->fifo1_transfer_size) { -+ // record fifo1 descriptors' start address -+ cam_ctx->fifo1_descriptors_virtual = (unsigned) cur_des_virtual; -+ cam_ctx->fifo1_descriptors_physical = (unsigned) cur_des_physical; -+ -+ for (i = 0; i < cam_ctx->block_number; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo1_transfer_size; -+ -+ target_page_num = cam_ctx->pages_per_block * i + cam_ctx->pages_per_fifo0; -+ -+ for (j = 0; j < cam_ctx->fifo1_num_descriptors; j++) { -+ // set descriptor -+ if (remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned) cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR1_PHY; // FIFO1 physical address -+ cur_des_virtual->dtadr = page_to_bus(cam_ctx->page_array[target_page_num]); -+ cur_des_virtual->dcmd = -+ des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo1_descriptors_physical); -+ } -+ // generate fifo2 dma chains -+ if (cam_ctx->fifo2_transfer_size) { -+ // record fifo1 descriptors' start address -+ cam_ctx->fifo2_descriptors_virtual = (unsigned) cur_des_virtual; -+ cam_ctx->fifo2_descriptors_physical = (unsigned) cur_des_physical; -+ -+ for (i = 0; i < cam_ctx->block_number; i++) { -+ // in each iteration, generate one dma chain for one frame -+ remain_size = cam_ctx->fifo2_transfer_size; -+ -+ target_page_num = cam_ctx->pages_per_block * i + -+ cam_ctx->pages_per_fifo0 + cam_ctx->pages_per_fifo1; -+ -+ for (j = 0; j < cam_ctx->fifo2_num_descriptors; j++) { -+ // set descriptor -+ if (remain_size > SINGLE_DESC_TRANS_MAX) -+ des_transfer_size = SINGLE_DESC_TRANS_MAX; -+ else -+ des_transfer_size = remain_size; -+ cur_des_virtual->ddadr = (unsigned) cur_des_physical + sizeof(pxa_dma_desc); -+ cur_des_virtual->dsadr = CIBR2_PHY; // FIFO2 physical address -+ cur_des_virtual->dtadr = page_to_bus(cam_ctx->page_array[target_page_num]); -+ cur_des_virtual->dcmd = -+ des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32; -+ -+ // advance pointers -+ remain_size -= des_transfer_size; -+ cur_des_virtual++; -+ cur_des_physical++; -+ target_page_num++; -+ } -+ -+ // stop the dma transfer on one frame captured -+ last_des_virtual = cur_des_virtual - 1; -+ //last_des_virtual->ddadr |= 0x1; -+ } -+ last_des_virtual->ddadr = ((unsigned) cam_ctx->fifo2_descriptors_physical); -+ } -+ return 0; -+} -+ -+void start_dma_transfer(p_camera_context_t cam_ctx, unsigned block_id) -+{ -+ pxa_dma_desc *des_virtual, *des_physical; -+ -+ DPRINTK("in %s,cam_ctx->block_number =%d\n", __FUNCTION__, cam_ctx->block_number); -+ /* -+ if (block_id >= cam_ctx->block_number) -+ return; -+ */ -+ // start channel 0 -+ des_virtual = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual + block_id * cam_ctx->fifo0_num_descriptors; -+ des_physical = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_physical + block_id * cam_ctx->fifo0_num_descriptors; -+ -+ DDADR(cam_ctx->dma_channels[0]) = des_physical; -+ DCSR(cam_ctx->dma_channels[0]) |= DCSR_RUN; -+ -+ // start channel 1 -+ if (cam_ctx->fifo1_descriptors_virtual) { -+ des_virtual = (pxa_dma_desc *) cam_ctx->fifo1_descriptors_virtual + -+ block_id * cam_ctx->fifo1_num_descriptors; -+ des_physical = (pxa_dma_desc *) cam_ctx->fifo1_descriptors_physical + -+ block_id * cam_ctx->fifo1_num_descriptors; -+ DDADR(cam_ctx->dma_channels[1]) = des_physical; -+ DCSR(cam_ctx->dma_channels[1]) |= DCSR_RUN; -+ } -+ // start channel 2 -+ if (cam_ctx->fifo2_descriptors_virtual) { -+ des_virtual = (pxa_dma_desc *) cam_ctx->fifo2_descriptors_virtual + -+ block_id * cam_ctx->fifo2_num_descriptors; -+ des_physical = (pxa_dma_desc *) cam_ctx->fifo2_descriptors_physical + -+ block_id * cam_ctx->fifo2_num_descriptors; -+ DDADR(cam_ctx->dma_channels[2]) = des_physical; -+ DCSR(cam_ctx->dma_channels[2]) |= DCSR_RUN; -+ } -+ cam_ctx->dma_started = 1; -+} -+ -+void set_still_image_ready(int rdy) -+{ -+ still_image_rdy = rdy; -+} -+ -+void stop_dma_transfer(p_camera_context_t cam_ctx) -+{ -+ int ch0, ch1, ch2; -+ -+ ch0 = cam_ctx->dma_channels[0]; -+ ch1 = cam_ctx->dma_channels[1]; -+ ch2 = cam_ctx->dma_channels[2]; -+ DCSR(ch0) &= ~DCSR_RUN; -+ DCSR(ch1) &= ~DCSR_RUN; -+ DCSR(ch2) &= ~DCSR_RUN; -+ cam_ctx->dma_started = 0; -+#ifdef CONFIG_DPM -+#endif -+} -+int start_capture(p_camera_context_t cam_ctx, unsigned int block_id, unsigned int frames) -+{ -+ int status; -+ int i; -+ -+ // clear ci fifo -+ ci_reset_fifo(); -+ ci_clear_int_status(0xFFFFFFFF); -+ -+ // start dma -+ start_dma_transfer(cam_ctx, block_id); -+ -+ // start capture -+ status = cam_ctx->camera_functions->start_capture(cam_ctx, frames); -+ return status; -+} -+ -+/*********************************************************************** -+ * -+ * Init/Deinit APIs -+ * -+ ***********************************************************************/ -+int camera_init(p_camera_context_t cam_ctx) -+{ -+ int ret = 0; -+ int i; -+ -+// parameter check -+ if (cam_ctx->buffer_virtual == NULL || cam_ctx->buf_size == 0) -+ return STATUS_WRONG_PARAMETER; -+ if (cam_ctx->dma_descriptors_virtual == NULL || -+ cam_ctx->dma_descriptors_physical == NULL || cam_ctx->dma_descriptors_size == 0) -+ return STATUS_WRONG_PARAMETER; -+ if (cam_ctx->sensor_type > CAMERA_TYPE_MAX) -+ return STATUS_WRONG_PARAMETER; -+ if (cam_ctx->capture_input_format > CAMERA_IMAGE_FORMAT_MAX || -+ cam_ctx->capture_output_format > CAMERA_IMAGE_FORMAT_MAX) -+ return STATUS_WRONG_PARAMETER; -+ -+ // check the function dispatch table according to the sensor type -+ if (!cam_ctx->camera_functions) -+ return STATUS_WRONG_PARAMETER; -+ if (!cam_ctx->camera_functions->init || -+ !cam_ctx->camera_functions->deinit || -+ !cam_ctx->camera_functions->set_capture_format || -+ !cam_ctx->camera_functions->start_capture || !cam_ctx->camera_functions->stop_capture) -+ return STATUS_WRONG_PARAMETER; -+ -+ // init context status -+ for (i = 0; i < 3; i++) -+ cam_ctx->dma_channels[i] = 0xFF; -+ (int) cam_ctx->fifo0_descriptors_virtual = NULL; -+ (int) cam_ctx->fifo1_descriptors_virtual = NULL; -+ (int) cam_ctx->fifo2_descriptors_virtual = NULL; -+ (int) cam_ctx->fifo0_descriptors_physical = NULL; -+ (int) cam_ctx->fifo1_descriptors_physical = NULL; -+ (int) cam_ctx->fifo2_descriptors_physical = NULL; -+ -+ cam_ctx->fifo0_num_descriptors = 0; -+ cam_ctx->fifo1_num_descriptors = 0; -+ cam_ctx->fifo2_num_descriptors = 0; -+ -+ cam_ctx->fifo0_transfer_size = 0; -+ cam_ctx->fifo1_transfer_size = 0; -+ cam_ctx->fifo2_transfer_size = 0; -+ -+ cam_ctx->block_number = 0; -+ cam_ctx->block_size = 0; -+ cam_ctx->block_header = 0; -+ cam_ctx->block_tail = 0; -+ -+ // Enable hardware -+ camera_gpio_init(); -+ DPRINTK("gpio init\n"); -+ -+ // capture interface init -+ ci_init(); -+ -+ // sensor init -+ ret = cam_ctx->camera_functions->init(cam_ctx); -+ DPRINTK("after cam_ctx->camera_functions->init\n"); -+ if (ret) -+ goto camera_init_err; -+ -+ -+ cam_ctx->dma_channels[0] = ci_dma_y; -+ cam_ctx->dma_channels[1] = ci_dma_cb; -+ cam_ctx->dma_channels[2] = ci_dma_cr; -+ DRCMR68 = ci_dma_y | DRCMR_MAPVLD; -+ DRCMR69 = ci_dma_cb | DRCMR_MAPVLD; -+ DRCMR70 = ci_dma_cr | DRCMR_MAPVLD; -+ -+ -+ // set capture format -+ ret = camera_set_capture_format(cam_ctx); -+ if (ret) -+ goto camera_init_err; -+ -+ // set frame rate -+ //camera_set_capture_frame_rate(cam_ctx); -+ -+ return 0; -+ -+ camera_init_err: -+ camera_deinit(cam_ctx); -+ return -1; -+} -+ -+void camera_gpio_init() -+{ -+#ifdef ADCM2650 -+ set_GPIO_mode(27 | GPIO_ALT_FN_3_IN); /* CIF_DD[0] */ -+ set_GPIO_mode(114 | GPIO_ALT_FN_1_IN); /* CIF_DD[1] */ -+ set_GPIO_mode(116 | GPIO_ALT_FN_1_IN); /* CIF_DD[2] */ -+ set_GPIO_mode(115 | GPIO_ALT_FN_2_IN); /* CIF_DD[3] */ -+ set_GPIO_mode(90 | GPIO_ALT_FN_3_IN); /* CIF_DD[4] */ -+ set_GPIO_mode(91 | GPIO_ALT_FN_3_IN); /* CIF_DD[5] */ -+ set_GPIO_mode(17 | GPIO_ALT_FN_2_IN); /* CIF_DD[6] */ -+ set_GPIO_mode(12 | GPIO_ALT_FN_2_IN); /* CIF_DD[7] */ -+ set_GPIO_mode(23 | GPIO_ALT_FN_1_OUT); /* CIF_MCLK */ -+ set_GPIO_mode(26 | GPIO_ALT_FN_2_IN); /* CIF_PCLK */ -+ set_GPIO_mode(25 | GPIO_ALT_FN_1_IN); /* CIF_LV */ -+ set_GPIO_mode(24 | GPIO_ALT_FN_1_IN); /* CIF_FV */ -+#endif -+ -+#ifdef OV9640 -+ set_GPIO_mode(27 | GPIO_ALT_FN_3_IN); /* CIF_DD[0] */ -+ set_GPIO_mode(114 | GPIO_ALT_FN_1_IN); /* CIF_DD[1] */ -+ set_GPIO_mode(51 | GPIO_ALT_FN_1_IN); /* CIF_DD[2] */ -+ set_GPIO_mode(115 | GPIO_ALT_FN_2_IN); /* CIF_DD[3] */ -+ set_GPIO_mode(95 | GPIO_ALT_FN_2_IN); /* CIF_DD[4] */ -+ set_GPIO_mode(94 | GPIO_ALT_FN_2_IN); /* CIF_DD[5] */ -+ set_GPIO_mode(17 | GPIO_ALT_FN_2_IN); /* CIF_DD[6] */ -+ set_GPIO_mode(108 | GPIO_ALT_FN_1_IN); /* CIF_DD[7] */ -+ set_GPIO_mode(23 | GPIO_ALT_FN_1_OUT); /* CIF_MCLK */ -+ set_GPIO_mode(54 | GPIO_ALT_FN_3_IN); /* CIF_PCLK */ -+ set_GPIO_mode(85 | GPIO_ALT_FN_3_IN); /* CIF_LV */ -+ set_GPIO_mode(84 | GPIO_ALT_FN_3_IN); /* CIF_FV */ -+ set_GPIO_mode(50 | GPIO_OUT); /*CIF_PD */ -+ set_GPIO_mode(19 | GPIO_OUT); /*CIF_RST */ -+ -+#endif -+ -+#ifdef ADCM2700 -+ set_GPIO_mode(CIF_PD_MD); /*CIF_PD */ -+ GPCR(CIF_PD) |= GPIO_bit(CIF_PD); /*set to low */ -+ set_GPIO_mode(CIF_RST_MD); /*CIF_RST */ -+ GPSR(CIF_RST) |= GPIO_bit(CIF_RST); /*set to high */ -+ set_GPIO_mode(CIF_DD0_MD); /* CIF_DD[0] */ -+ set_GPIO_mode(CIF_DD1_MD); /* CIF_DD[1] */ -+ set_GPIO_mode(CIF_DD2_MD); /* CIF_DD[2] */ -+ set_GPIO_mode(CIF_DD3_MD); /* CIF_DD[3] */ -+ set_GPIO_mode(CIF_DD4_MD); /* CIF_DD[4] */ -+ set_GPIO_mode(CIF_DD5_MD); /* CIF_DD[5] */ -+ set_GPIO_mode(CIF_DD6_MD); /* CIF_DD[6] */ -+ set_GPIO_mode(CIF_DD7_MD); /* CIF_DD[7] */ -+ set_GPIO_mode(CIF_MCLK_MD); /* CIF_MCLK */ -+ set_GPIO_mode(CIF_PCLK_MD); /* CIF_PCLK */ -+ set_GPIO_mode(CIF_LV_MD); /* CIF_LV */ -+ set_GPIO_mode(CIF_FV_MD); /* CIF_FV */ -+ -+#endif -+ -+ return; -+} -+ -+int camera_deinit(p_camera_context_t cam_ctx) -+{ -+ int ret = 0; -+ -+ ret = cam_ctx->camera_functions->deinit(cam_ctx); -+ -+ // capture interface deinit -+ ci_deinit(); -+ return ret; -+} -+ -+/*********************************************************************** -+ * -+ * Capture APIs -+ * -+ ***********************************************************************/ -+// Set the image format -+ -+int camera_set_capture_format(p_camera_context_t cam_ctx) -+{ -+ int ret; -+ unsigned frame_size; -+ CI_IMAGE_FORMAT ci_input_format, ci_output_format; -+ CI_MP_TIMING timing; -+ -+ // set capture interface -+ if (cam_ctx->capture_input_format > CAMERA_IMAGE_FORMAT_MAX || -+ cam_ctx->capture_output_format > CAMERA_IMAGE_FORMAT_MAX) -+ return STATUS_WRONG_PARAMETER; -+ ci_input_format = FORMAT_MAPPINGS[cam_ctx->capture_input_format]; -+ ci_output_format = FORMAT_MAPPINGS[cam_ctx->capture_output_format]; -+ if (ci_input_format == CI_INVALID_FORMAT || ci_output_format == CI_INVALID_FORMAT) -+ return STATUS_WRONG_PARAMETER; -+ ci_set_image_format(ci_input_format, ci_output_format); -+ -+ // ring buffer init -+ switch (cam_ctx->capture_output_format) { -+ case CAMERA_IMAGE_FORMAT_RGB565: -+ frame_size = cam_ctx->capture_width * cam_ctx->capture_height * 2; -+ cam_ctx->fifo0_transfer_size = frame_size; -+ cam_ctx->fifo1_transfer_size = 0; -+ cam_ctx->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED: -+ frame_size = cam_ctx->capture_width * cam_ctx->capture_height * 2; -+ cam_ctx->fifo0_transfer_size = frame_size; -+ cam_ctx->fifo1_transfer_size = 0; -+ cam_ctx->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR: -+ frame_size = cam_ctx->capture_width * cam_ctx->capture_height * 2; -+ cam_ctx->fifo0_transfer_size = frame_size / 2; -+ cam_ctx->fifo1_transfer_size = frame_size / 4; -+ cam_ctx->fifo2_transfer_size = frame_size / 4; -+ break; -+// RGB666 support - JamesL -+ case CAMERA_IMAGE_FORMAT_RGB666_PLANAR: -+ frame_size = cam_ctx->capture_width * cam_ctx->capture_height * 4; -+ cam_ctx->fifo0_transfer_size = frame_size; -+ cam_ctx->fifo1_transfer_size = 0; -+ cam_ctx->fifo2_transfer_size = 0; -+ break; -+ case CAMERA_IMAGE_FORMAT_RGB666_PACKED: -+ frame_size = cam_ctx->capture_width * cam_ctx->capture_height * 3; -+ cam_ctx->fifo0_transfer_size = frame_size; -+ cam_ctx->fifo1_transfer_size = 0; -+ cam_ctx->fifo2_transfer_size = 0; -+ break; -+// RGB888 support - JamesL -+ case CAMERA_IMAGE_FORMAT_RGB888_PLANAR: -+ frame_size = cam_ctx->capture_width * cam_ctx->capture_height * 4; -+ cam_ctx->fifo0_transfer_size = frame_size; -+ cam_ctx->fifo1_transfer_size = 0; -+ cam_ctx->fifo2_transfer_size = 0; -+ break; -+// -+ default: -+ return STATUS_WRONG_PARAMETER; -+ break; -+ } -+ cam_ctx->block_size = frame_size; -+ -+ cam_ctx->pages_per_fifo0 = (PAGE_ALIGN(cam_ctx->fifo0_transfer_size) / PAGE_SIZE); -+ cam_ctx->pages_per_fifo1 = (PAGE_ALIGN(cam_ctx->fifo1_transfer_size) / PAGE_SIZE); -+ cam_ctx->pages_per_fifo2 = (PAGE_ALIGN(cam_ctx->fifo2_transfer_size) / PAGE_SIZE); -+ -+ cam_ctx->pages_per_block = cam_ctx->pages_per_fifo0 + cam_ctx->pages_per_fifo1 + cam_ctx->pages_per_fifo2; -+ -+ cam_ctx->page_aligned_block_size = cam_ctx->pages_per_block * PAGE_SIZE; -+ -+ cam_ctx->block_number = cam_ctx->pages_allocated / cam_ctx->pages_per_block; -+ cam_ctx->block_number_max = cam_ctx->pages_allocated / cam_ctx->pages_per_block; -+ DPRINTK("in %s,cam_ctx->block_number =%d \n", __FUNCTION__, cam_ctx->block_number); -+ -+ if (cam_ctx->block_number > 3) -+ cam_ctx->block_number = 3; -+ -+ if (cam_ctx->block_number > VIDEO_MAX_FRAME) -+ cam_ctx->block_number = VIDEO_MAX_FRAME; -+ -+ //cam_ctx->block_header = cam_ctx->block_tail = 0; -+ -+ // generate dma descriptor chain -+ ret = update_dma_chain(cam_ctx); -+ if (ret) -+ return -1; -+ timing.BFW = timing.BLW = 0; -+ ci_configure_mp(cam_ctx->capture_width - 1, cam_ctx->capture_height - 1, &timing); -+ DPRINTK("before cam_ctx->camera_functions->set_capture_format \n"); -+ // set sensor setting -+ ret = cam_ctx->camera_functions->set_capture_format(cam_ctx); -+ if (ret) -+ return ret; -+ -+ DPRINTK("after cam_ctx->camera_functions->set_capture_format \n"); -+ return 0; -+} -+ -+// take a picture and copy it into the ring buffer -+int camera_capture_still_image(p_camera_context_t cam_ctx, unsigned int block_id) -+{ -+ int status; -+ -+ // init buffer status & capture -+ cam_ctx->block_header = cam_ctx->block_tail = block_id; -+ cam_ctx->capture_status = 0; -+ status = start_capture(cam_ctx, block_id, 1); -+ -+ return status; -+} -+ -+// capture motion video and copy it to the ring buffer -+int camera_start_video_capture(p_camera_context_t cam_ctx, unsigned int block_id) -+{ -+ int status; -+ -+ // init buffer status & capture -+ cam_ctx->block_header = cam_ctx->block_tail = block_id; -+ cam_ctx->capture_status = CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS; -+ status = start_capture(cam_ctx, block_id, 0); -+ -+ return status; -+} -+ -+// disable motion video image capture -+void camera_stop_video_capture(p_camera_context_t cam_ctx) -+{ -+ int status; -+ -+ // stop capture -+ status = cam_ctx->camera_functions->stop_capture(cam_ctx); -+ -+ // stop dma -+ stop_dma_transfer(cam_ctx); -+ -+ // update the flag -+ if (!(cam_ctx->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ cam_ctx->capture_status &= ~CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS; -+ return; -+} -+ -+ -+/*********************************************************************** -+ * -+ * Flow Control APIs -+ * -+ ***********************************************************************/ -+// continue capture image to next available buffer -+void camera_continue_transfer(p_camera_context_t cam_ctx) -+{ -+ // don't think we need this either. JR -+ // continue transfer on next block -+ start_dma_transfer(cam_ctx, cam_ctx->block_tail); -+} -+ -+// Return 1: there is available buffer, 0: buffer is full -+int camera_next_buffer_available(p_camera_context_t cam_ctx) -+{ -+ cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ if (((cam_ctx->block_header + 1) % cam_ctx->block_number) != cam_ctx->block_tail) { -+ return 1; -+ } -+ cam_ctx->capture_status |= CAMERA_STATUS_RING_BUFFER_FULL; -+ -+ return 0; -+} -+ -+// Application supplies the FrameBufferID to the driver to tell it that the application has completed processing of -+// the given frame buffer, and that buffer is now available for re-use. -+void camera_release_frame_buffer(p_camera_context_t cam_ctx, unsigned int frame_buffer_id) -+{ -+ -+ cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number; -+ -+ // restart video capture only if video capture is in progress and space is available for image capture -+ if ((cam_ctx->capture_status & CAMERA_STATUS_RING_BUFFER_FULL) && -+ (cam_ctx->capture_status & CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS)) { -+ if (((cam_ctx->block_header + 2) % cam_ctx->block_number) != cam_ctx->block_tail) { -+ cam_ctx->capture_status &= ~CAMERA_STATUS_RING_BUFFER_FULL; -+ start_capture(cam_ctx, cam_ctx->block_tail, 0); -+ } -+ } -+} -+ -+// Returns the FrameBufferID for the first filled frame -+// Note: -1 represents buffer empty -+int camera_get_first_frame_buffer_id(p_camera_context_t cam_ctx) -+{ -+ // not sure if this routine makes any sense.. JR -+ -+ // check whether buffer is empty -+ if ((cam_ctx->block_header == cam_ctx->block_tail) && -+ !(cam_ctx->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ return -1; -+ -+ // return the block header -+ return cam_ctx->block_header; -+} -+ -+// Returns the FrameBufferID for the last filled frame, this would be used if we were polling for image completion data, -+// or we wanted to make sure there were no frames waiting for us to process. -+// Note: -1 represents buffer empty -+int camera_get_last_frame_buffer_id(p_camera_context_t cam_ctx) -+{ -+ int ret; -+ -+ // check whether buffer is empty -+ if ((cam_ctx->block_header == cam_ctx->block_tail) && -+ !(cam_ctx->capture_status & CAMERA_STATUS_RING_BUFFER_FULL)) -+ return -1; -+ -+ // return the block before the block_tail -+ ret = (cam_ctx->block_tail + cam_ctx->block_number - 1) % cam_ctx->block_number; -+ return ret; -+} -+ -+/*********************************************************************** -+ * -+ * Buffer Info APIs -+ * -+ ***********************************************************************/ -+// Return: the number of frame buffers allocated for use. -+unsigned int camera_get_num_frame_buffers(p_camera_context_t cam_ctx) -+{ -+ return cam_ctx->block_number; -+} -+ -+// FrameBufferID is a number between 0 and N-1, where N is the total number of frame buffers in use. Returns the address of -+// the given frame buffer. The application will call this once for each frame buffer at application initialization only. -+void *camera_get_frame_buffer_addr(p_camera_context_t cam_ctx, unsigned int frame_buffer_id) -+{ -+ return (void *) ((unsigned) cam_ctx->buffer_virtual + cam_ctx->page_aligned_block_size * frame_buffer_id); -+} -+ -+// Return the block id -+int camera_get_frame_buffer_id(p_camera_context_t cam_ctx, void *address) -+{ -+ if (((unsigned) address >= -+ (unsigned) cam_ctx->buffer_virtual) && -+ ((unsigned) address <= (unsigned) cam_ctx->buffer_virtual + cam_ctx->buf_size)) { -+ return ((unsigned) address - (unsigned) cam_ctx->buffer_virtual) / cam_ctx->page_aligned_block_size; -+ } -+ return -1; -+} -+ -+ -+/*********************************************************************** -+ * -+ * Frame rate APIs -+ * -+ ***********************************************************************/ -+// Set desired frame rate -+void camera_set_capture_frame_rate(p_camera_context_t cam_ctx) -+{ -+ ci_set_frame_rate(cam_ctx->frame_rate); -+ return; -+} -+ -+// return current setting -+void camera_get_capture_frame_rate(p_camera_context_t cam_ctx) -+{ -+ cam_ctx->frame_rate = ci_get_frame_rate(); -+ return; -+} -+ -+ -+/*********************************************************************** -+ * -+ * Interrupt APIs -+ * -+ ***********************************************************************/ -+// set interrupt mask -+void camera_set_int_mask(p_camera_context_t cam_ctx, unsigned int mask) -+{ -+ pxa_dma_desc *end_des_virtual; -+ int dma_interrupt_on; -+ unsigned int i; -+ -+ // set CI interrupt -+ ci_set_int_mask(mask & CI_CICR0_INTERRUPT_MASK); -+ -+ // set dma end interrupt -+ if (mask & CAMERA_INTMASK_END_OF_DMA) -+ dma_interrupt_on = 1; -+ else -+ dma_interrupt_on = 0; -+ -+ // set fifo0 dma chains' flag -+ end_des_virtual = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual + cam_ctx->fifo0_num_descriptors - 1; -+ for (i = 0; i < cam_ctx->block_number; i++) { -+ if (dma_interrupt_on) -+ end_des_virtual->dcmd |= DCMD_ENDIRQEN; -+ else -+ end_des_virtual->dcmd &= ~DCMD_ENDIRQEN; -+ end_des_virtual += cam_ctx->fifo0_num_descriptors; -+ } -+} -+ -+// get interrupt mask -+unsigned int camera_get_int_mask(p_camera_context_t cam_ctx) -+{ -+ pxa_dma_desc *end_des_virtual; -+ unsigned int ret; -+ -+ // get CI mask -+ ret = ci_get_int_mask(); -+ -+ // get dma end mask -+ end_des_virtual = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual + cam_ctx->fifo0_num_descriptors - 1; -+ if (end_des_virtual->dcmd & DCMD_ENDIRQEN) -+ ret |= CAMERA_INTMASK_END_OF_DMA; -+ -+ return ret; -+} -+ -+// clear interrupt status -+void camera_clear_int_status(p_camera_context_t cam_ctx, unsigned int status) -+{ -+ ci_clear_int_status((status & 0xFFFF)); -+} -+ -+/*********************************************************************************** -+* Application interface * -+***********************************************************************************/ -+static int pxa_camera_open(struct video_device *dev, int flags) -+{ -+ int status = -1; -+ camera_context_t *cam_ctx; -+ -+ init_waitqueue_head(&camera_wait_q); -+ if (pxa_camera_mem_init()) { -+ DPRINTK("DMA memory allocate failed!"); -+ return -1; -+ } -+ DPRINTK("in %s, after pxa_camera_mem_init \n", __FUNCTION__); -+ cam_ctx = g_camera_context; -+ if (atomic_read(&cam_ctx->refcount)) -+ return -EBUSY; -+ atomic_inc(&cam_ctx->refcount); -+ -+ -+#ifdef ADCM2650 -+ cam_ctx->sensor_type = CAMERA_TYPE_ADCM_2650; -+#endif -+#ifdef ADCM2700 -+ cam_ctx->sensor_type = CAMERA_TYPE_ADCM_2700; -+#endif -+#ifdef OV9640 -+ cam_ctx->sensor_type = CAMERA_TYPE_OMNIVISION_9640; -+#endif -+ cam_ctx->capture_width = WIDTH_DEFT; -+ cam_ctx->capture_height = HEIGHT_DEFT; -+ cam_ctx->capture_input_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ cam_ctx->capture_output_format = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ cam_ctx->frame_rate = FRAMERATE_DEFT; -+ -+ // init function dispatch table -+#ifdef ADCM2650 -+ adcm2650_func.init = camera_func_adcm2650_init; -+ adcm2650_func.deinit = camera_func_adcm2650_deinit; -+ adcm2650_func.set_capture_format = camera_func_adcm2650_set_capture_format; -+ adcm2650_func.start_capture = camera_func_adcm2650_start_capture; -+ adcm2650_func.stop_capture = camera_func_adcm2650_stop_capture; -+ cam_ctx->camera_functions = &adcm2650_func; -+#endif -+ -+#ifdef ADCM2700 -+ adcm2700_func.init = camera_func_adcm2700_init; -+ adcm2700_func.deinit = camera_func_adcm2700_deinit; -+ adcm2700_func.set_capture_format = camera_func_adcm2700_set_capture_format; -+ adcm2700_func.start_capture = camera_func_adcm2700_start_capture; -+ adcm2700_func.stop_capture = camera_func_adcm2700_stop_capture; -+ cam_ctx->camera_functions = &adcm2700_func; -+#endif -+ -+#ifdef OV9640 -+ ov9640_func.init = camera_func_ov9640_init; -+ ov9640_func.deinit = camera_func_ov9640_deinit; -+ ov9640_func.set_capture_format = camera_func_ov9640_set_capture_format; -+ ov9640_func.start_capture = camera_func_ov9640_start_capture; -+ ov9640_func.stop_capture = camera_func_ov9640_stop_capture; -+ ov9640_func.command = camera_func_ov9640_command; -+ cam_ctx->camera_functions = &ov9640_func; -+#endif -+ -+ cam_ctx->ost_reg_base = 0; -+ cam_ctx->gpio_reg_base = 0; -+ cam_ctx->ci_reg_base = 0; -+ cam_ctx->board_reg_base = 0; -+ still_image_rdy = 0; -+ -+ /* FIXME: handle camera_init() errors ? */ -+ status = camera_init(cam_ctx); -+ DPRINTK(KERN_DEBUG PREFIX "camera opened\n"); -+ status = 0; -+ return status; -+} -+ -+static void pxa_camera_close(struct video_device *dev) -+{ -+ camera_context_t *cam_ctx = g_camera_context; -+ -+ DPRINTK(KERN_DEBUG PREFIX "camera closed\n"); -+ atomic_dec(&cam_ctx->refcount); -+ camera_deinit(cam_ctx); -+ pxa_camera_mem_deinit(); -+} -+ -+#define PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, size) \ -+do { \ -+ unsigned int len; \ -+ unsigned int remain_size = size; \ -+ while (remain_size > 0) { \ -+ if (remain_size > PAGE_SIZE) \ -+ len = PAGE_SIZE; \ -+ else \ -+ len = remain_size; \ -+ if (copy_to_user(buf, page_address(*p_page), len)) \ -+ return -EFAULT; \ -+ remain_size -= len; \ -+ buf += len; \ -+ p_page++; \ -+ } \ -+} while (0); -+ -+ -+static long pxa_camera_read(struct video_device *dev, char *buf, unsigned long count, int noblock) -+{ -+ struct page **p_page; -+ -+ camera_context_t *cam_ctx = g_camera_context; -+ -+ if (still_image_mode == 1) { -+ while (still_image_rdy != 1) -+ mdelay(1); -+ /* -+ if (cam_ctx->capture_width ==1280 && cam_ctx->capture_height==960) -+ cam_ctx->block_tail = cam_ctx->block_header = 0; -+ else if (cam_ctx->capture_width==960 && cam_ctx->capture_height==480) -+ cam_ctx->block_tail = cam_ctx->block_header = 2; -+ DPRINTK("cam_ctx->block_number =%d \n",cam_ctx->block_number); -+ cam_ctx->camera_functions->stop_capture(cam_ctx); -+ */ -+ p_page = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo0_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo1_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo2_transfer_size); -+ -+ still_image_rdy = 0; -+ return cam_ctx->block_size; -+ } -+ if (still_image_mode == 0) { -+ if (first_video_frame == 1) -+ cam_ctx->block_tail = cam_ctx->block_header; -+ else -+ cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number; -+ } -+ -+ first_video_frame = 0; -+ -+ if (cam_ctx->block_header == cam_ctx->block_tail) { -+ if (still_image_mode == 0) { -+ task_waiting = 1; -+ interruptible_sleep_on(&camera_wait_q); -+ } else { -+ while (still_image_rdy != 1) { -+ DPRINTK("wait still_image_rdy =1 \n"); -+ mdelay(1); -+ } -+ } -+ } -+ -+ p_page = &cam_ctx->page_array[cam_ctx->block_tail * cam_ctx->pages_per_block]; -+ -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo0_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo1_transfer_size); -+ PXA_CAMERA_BUFFER_COPY_TO_USER(buf, p_page, cam_ctx->fifo2_transfer_size); -+ -+ return cam_ctx->block_size; -+} -+ -+int camera_sleep() -+{ -+ interruptible_sleep_on(&camera_wait_q); -+} -+ -+struct reg_set_s { -+ int val1; -+ int val2; -+}; -+ -+static int pxa_camera_ioctl(struct video_device *dev, unsigned int cmd, void *param) -+{ -+ int retval = 0; -+ camera_context_t *cam_ctx = g_camera_context; -+ -+ switch (cmd) { -+/* V4L Standard IOCTL. */ -+ case VIDIOCGCAP: -+ { -+ struct video_capability vc; -+ strcpy(vc.name, "Bulverde Camera"); -+ vc.maxwidth = MAX_WIDTH; -+ vc.maxheight = MAX_HEIGHT; -+#ifdef OV9640 -+ vc.maxwidth = 1280; -+ vc.maxheight = 960; -+#endif -+ vc.minwidth = MIN_WIDTH; -+ vc.minheight = MIN_HEIGHT; -+ if (copy_to_user(param, &vc, sizeof(struct video_capability))) -+ return -EFAULT; -+ break; -+ } -+ -+ -+ case VIDIOCSPICT: -+ { -+ struct video_picture vp; -+ if (copy_from_user(&vp, param, sizeof(vp))) { -+ retval = -EFAULT; -+ break; -+ } -+ cam_ctx->capture_output_format = vp.palette; -+ retval = camera_set_capture_format(cam_ctx); -+ break; -+ } -+ case VIDIOCGPICT: -+ { -+ struct video_picture vp; -+ vp.palette = cam_ctx->capture_output_format; -+ if (copy_to_user(param, &vp, sizeof(struct video_picture))) -+ retval = -EFAULT; -+ break; -+ } -+ -+ case VIDIOCCAPTURE: -+ { -+ int capture_flag; -+ -+ capture_flag = (int) param; -+/* Still Image Capture */ -+ if (capture_flag == STILL_IMAGE) { -+ camera_set_int_mask(cam_ctx, 0x3ff | 0x0400); -+ still_image_mode = 1; -+ task_waiting = 0; -+ camera_capture_still_image(cam_ctx, 0); -+ cam_ctx->block_header = 0; -+ cam_ctx->block_tail = 0; -+ break; -+ } -+/* Video Capture Start */ -+ else if (capture_flag == VIDEO_START) { -+ camera_set_int_mask(cam_ctx, 0x3ff | 0x0400); -+ cam_ctx->block_header = 0; -+ cam_ctx->block_tail = 0; -+ still_image_mode = 0; -+ first_video_frame = 1; -+ camera_start_video_capture(cam_ctx, 0); -+ break; -+ } -+/* Video Capture Stop */ -+ else if (capture_flag == VIDEO_STOP) { -+ camera_set_int_mask(cam_ctx, 0x3ff); -+ camera_stop_video_capture(cam_ctx); -+ break; -+ } else { -+ retval = -EFAULT; -+ break; -+ } -+ } -+ -+/* mmap interface */ -+ case VIDIOCGMBUF: -+ { -+ struct video_mbuf vm; -+ int i; -+ -+ memset(&vm, 0, sizeof(vm)); -+ vm.size = cam_ctx->buf_size; -+ vm.frames = cam_ctx->block_number; -+ for (i = 0; i < vm.frames; i++) -+ vm.offsets[i] = cam_ctx->page_aligned_block_size * i; -+ -+ if (copy_to_user((void *) param, (void *) &vm, sizeof(vm))) -+ retval = -EFAULT; -+ break; -+ } -+ -+/* Application extended IOCTL. */ -+/* Register access interface */ -+ case WCAM_VIDIOCSINFOR: -+ { -+ struct reg_set_s reg_s; -+ if (copy_from_user(®_s, param, sizeof(int) * 2)) { -+ retval = -EFAULT; -+ break; -+ } -+ cam_ctx->capture_input_format = reg_s.val1; -+ cam_ctx->capture_output_format = reg_s.val2; -+ -+ retval = camera_set_capture_format(cam_ctx); -+ DPRINTK("WCAM_VIDIOCSINFOR retval=%d\n", retval); -+ break; -+ } -+ -+ case WCAM_VIDIOCGINFOR: -+ { -+ struct reg_set_s reg_s; -+ reg_s.val1 = cam_ctx->capture_input_format; -+ reg_s.val2 = cam_ctx->capture_output_format; -+ if (copy_to_user(param, ®_s, sizeof(int) * 2)) -+ retval = -EFAULT; -+ break; -+ } -+ -+ case WCAM_VIDIOCGCIREG: -+ { -+ struct reg_set_s reg_s; -+ if (copy_from_user(®_s, param, sizeof(int) * 2)) { -+ retval = -EFAULT; -+ break; -+ } -+ -+ reg_s.val2 = ci_get_reg_value(reg_s.val1); -+ if (copy_to_user(param, ®_s, sizeof(int) * 2)) -+ retval = -EFAULT; -+ break; -+ } -+ -+ case WCAM_VIDIOCSCIREG: -+ { -+ struct reg_set_s reg_s; -+ if (copy_from_user(®_s, param, sizeof(int) * 2)) { -+ retval = -EFAULT; -+ break; -+ } -+ ci_set_reg_value(reg_s.val1, reg_s.val2); -+ break; -+ } -+ -+ case WCAM_VIDIOCGCAMREG: -+ { -+ struct reg_set_s reg_s; -+ if (copy_from_user(®_s, param, sizeof(int) * 2)) { -+ retval = -EFAULT; -+ break; -+ } -+ sensor_pipeline_read((u16) reg_s.val1, (u16 *) & reg_s.val2); -+ DPRINTK("WCAM_VIDIOCGCAMREG reg.val1=0x%x,reg.val2=0x%x\n", reg_s.val1, reg_s.val2); -+ if (copy_to_user(param, ®_s, sizeof(int) * 2)) -+ retval = -EFAULT; -+ ci_dump(); -+ break; -+ } -+ -+ case WCAM_VIDIOCSCAMREG: -+ { -+ struct reg_set_s reg_s; -+ if (copy_from_user(®_s, param, sizeof(int) * 2)) { -+ retval = -EFAULT; -+ break; -+ } -+ sensor_pipeline_write((u16) reg_s.val1, (u16) reg_s.val2); -+ break; -+ } -+ /*set frame buffer count */ -+ case WCAM_VIDIOCSBUFCOUNT: -+ { -+ int count; -+ if (copy_from_user(&count, param, sizeof(int))) { -+ return -EFAULT; -+ } -+ if (cam_ctx->block_number_max == 0) { -+ dbg_print("windows size or format not setting!!"); -+ return -EFAULT; -+ } -+ -+ if (count >= FRAMES_IN_BUFFER && count <= cam_ctx->block_number_max) { -+ cam_ctx->block_number = count; -+ cam_ctx->block_header = cam_ctx->block_tail = 0; -+ // generate dma descriptor chain -+ update_dma_chain(cam_ctx); -+ } -+ -+ count = cam_ctx->block_number; -+ -+ if (copy_to_user(param, &count, sizeof(int))) { -+ return -EFAULT; -+ } -+ -+ } -+ break; -+ /*get cur avaliable frames */ -+ case WCAM_VIDIOCGCURFRMS: -+ { -+ struct { -+ int first, last; -+ } pos; -+ pos.first = cam_ctx->block_tail; -+ pos.last = cam_ctx->block_header; -+ -+ if (copy_to_user(param, &pos, sizeof(pos))) { -+ return -EFAULT; -+ } -+ } -+ -+ break; -+ -+ default: -+ { -+ int ret; -+ DPRINTK("in _ioctl default command,param=%d!!!!!!!!!!!!!!!!!!!!\n", param); -+ ret = cam_ctx->camera_functions->command(cam_ctx, cmd, param); -+ DPRINTK("cam_ctx->camera_functions->command ret=%d\n", ret); -+ retval = ret; -+ if (ret) { -+ DPRINTK(KERN_WARNING PREFIX "invalid ioctl %x\n", cmd); -+ retval = -ENOIOCTLCMD; -+ } -+ break; -+ } -+ } -+ return retval; -+} -+ -+static int pxa_camera_mmap(struct video_device *dev, const char *adr, unsigned long size) -+{ -+ unsigned long start = (unsigned long) adr; -+ camera_context_t *cam_ctx = g_camera_context; -+ struct page **p_page = cam_ctx->page_array; -+ -+ size = PAGE_ALIGN(size); -+ while (size > 0) { -+ if (remap_page_range(start, page_to_phys(*p_page), PAGE_SIZE, PAGE_SHARED)) { -+ return -EFAULT; -+ } -+ start += PAGE_SIZE; -+ p_page++; -+ size -= PAGE_SIZE; -+ } -+ return 0; -+} -+ -+unsigned int pxa_camera_poll(struct video_device *dev, struct file *file, poll_table * wait) -+{ -+ camera_context_t *cam_ctx = g_camera_context; -+ static int waited = 0; -+ -+ poll_wait(file, &camera_wait_q, wait); -+ -+ if (still_image_mode == 1) -+ if (still_image_rdy == 1) { -+ still_image_rdy = 0; -+ write_balance(); -+ return POLLIN | POLLRDNORM; -+ } -+ //else -+ // return 0; -+ if (first_video_frame == 1) -+ first_video_frame = 0; -+ else if (still_image_mode == 0 && waited != 1) -+ cam_ctx->block_tail = (cam_ctx->block_tail + 1) % cam_ctx->block_number; -+ -+ if (cam_ctx->block_header == cam_ctx->block_tail) { -+ DPRINTK("enter poll waiting, tail = %d, header = %d \n", cam_ctx->block_tail, cam_ctx->block_header); -+ task_waiting = 1; -+ waited = 1; -+ //interruptible_sleep_on(&camera_wait_q); -+ return 0; -+ } else -+ waited = 0; -+ -+ write_balance(); -+ return POLLIN | POLLRDNORM; -+} -+ -+ -+int pxa_camera_video_init(struct video_device *vdev) -+{ -+ DPRINTK(KERN_DEBUG PREFIX "camera initialized\n"); -+ return 0; -+} -+ -+ -+static struct video_device vd = { -+ owner:THIS_MODULE, -+ name:"PXA Camera", -+ type:VID_TYPE_CAPTURE, -+ hardware:VID_HARDWARE_PXA_CAMERA, /* FIXME */ -+ open:pxa_camera_open, -+ close:pxa_camera_close, -+ read:pxa_camera_read, -+ poll:pxa_camera_poll, -+ ioctl:pxa_camera_ioctl, -+ mmap:pxa_camera_mmap, -+ initialize:pxa_camera_video_init, -+ minor:-1, -+}; -+ -+int pxa_camera_mem_deinit() -+{ -+ camera_context_t *cam_ctx = g_camera_context; -+ if (ci_regs_base) -+ iounmap((unsigned long *) ci_regs_base); -+ if (g_camera_context) { -+ if (cam_ctx->dma_descriptors_virtual) { -+ consistent_free(cam_ctx->dma_descriptors_virtual, -+ MAX_DESC_NUM * sizeof(pxa_dma_desc), (int) cam_ctx->dma_descriptors_physical); -+ g_camera_context->dma_descriptors_virtual = NULL; -+ } -+ -+ if (cam_ctx->buffer_virtual) { -+ pxa_dma_buffer_free(cam_ctx); -+ g_camera_context->buffer_virtual = NULL; -+ -+ } -+ -+ kfree(g_camera_context); -+ g_camera_context = NULL; -+ } -+ return 0; -+} -+ -+int pxa_camera_mem_init() -+{ -+ p_camera_context_t cam_ctx; -+ (unsigned long *) ci_regs_base = (unsigned long *) ioremap(CI_REGS_PHYS, CI_REG_SIZE); -+ if (!ci_regs_base) { -+ DPRINTK(KERN_ERR PREFIX "can't remap I/O registers at %x\n", CI_REGS_PHYS); -+ return -1; -+ } -+ -+ cam_ctx = (camera_context_t *) -+ kmalloc(sizeof(struct camera_context_s), GFP_KERNEL); -+ if (cam_ctx == NULL) { -+ DPRINTK(KERN_WARNING PREFIX "can't allocate buffer for camera control structure\n"); -+ return -1; -+ } -+ g_camera_context = cam_ctx; -+ memset(g_camera_context, 0, sizeof(struct camera_context_s)); -+ atomic_set(&cam_ctx->refcount, 0); -+ cam_ctx->dma_started = 0; -+ -+ cam_ctx->dma_descriptors_virtual = -+ consistent_alloc(GFP_KERNEL, MAX_DESC_NUM * sizeof(pxa_dma_desc), -+ (void *) &cam_ctx->dma_descriptors_physical); -+ if (cam_ctx->dma_descriptors_virtual == NULL) { -+ DPRINTK(KERN_WARNING PREFIX -+ "memory allocation for DMA descriptors (%ld bytes) failed\n", -+ MAX_DESC_NUM * sizeof(pxa_dma_desc)); -+ goto err_mem; -+ } -+ -+ cam_ctx->buf_size = BUF_SIZE_DEFT; -+ -+ if (pxa_dma_buffer_init(cam_ctx) != 0) { -+ DPRINTK(KERN_WARNING PREFIX -+ "memory allocation for capture buffer (%d bytes) failed\n", cam_ctx->buf_size); -+ goto err_mem; -+ } -+ -+ cam_ctx->dma_descriptors_size = MAX_DESC_NUM; -+ return 0; -+ err_mem: -+ pxa_camera_mem_deinit(); -+ return -ENXIO; -+} -+ -+static int __init pxa_camera_init(void) -+{ -+ camera_context_t *cam_ctx = NULL; -+ int err; -+ -+ /* 1. mapping CI registers, so that we can access the CI */ -+ if ((err = request_irq(IRQ_CAMERA, pxa_camera_irq, 0, "PXA Camera", &vd))) { -+ DPRINTK(KERN_WARNING PREFIX "camera interrupt register failed, error %d\n", err); -+ return -ENXIO; -+ } -+ ci_dma_y = pxa_request_dma("CI_Y", DMA_PRIO_HIGH, pxa_ci_dma_irq_y, &vd); -+ if (ci_dma_y < 0) { -+ DPRINTK(KERN_WARNING PREFIX "can't request DMA for Y\n"); -+ goto err_init; -+ } -+ ci_dma_cb = pxa_request_dma("CI_Cb", DMA_PRIO_HIGH, pxa_ci_dma_irq_cb, &vd); -+ if (ci_dma_cb < 0) { -+ DPRINTK(KERN_WARNING PREFIX "can't request DMA for Cb\n"); -+ goto err_init; -+ } -+ ci_dma_cr = pxa_request_dma("CI_Cr", DMA_PRIO_HIGH, pxa_ci_dma_irq_cr, &vd); -+ if (ci_dma_cr < 0) { -+ DPRINTK(KERN_WARNING PREFIX "can't request DMA for Cr\n"); -+ goto err_init; -+ } -+ -+ DRCMR68 = ci_dma_y | DRCMR_MAPVLD; -+ DRCMR69 = ci_dma_cb | DRCMR_MAPVLD; -+ DRCMR70 = ci_dma_cr | DRCMR_MAPVLD; -+ -+ -+ if (video_register_device(&vd, VFL_TYPE_GRABBER, minor) < 0) { -+ DPRINTK(KERN_WARNING PREFIX "can't register video device\n"); -+ goto err_init; -+ } -+#ifdef CONFIG_DPM -+ pxa_camera_ldm_register(); -+#endif -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, camera_pm_callback); -+#endif -+ -+ -+ DPRINTK(KERN_NOTICE PREFIX "video device registered, use device /dev/video%d \n", minor); -+ return 0; -+ -+ err_init: -+ free_irq(IRQ_CAMERA, &vd); -+ -+ if (ci_dma_y >= 0) -+ pxa_free_dma(ci_dma_y); -+ -+ if (ci_dma_cb >= 0) -+ pxa_free_dma(ci_dma_cb); -+ -+ if (ci_dma_cr >= 0) -+ pxa_free_dma(ci_dma_cr); -+ -+ DRCMR68 = 0; -+ DRCMR69 = 0; -+ DRCMR70 = 0; -+ -+ return 0; -+} -+ -+static void __exit pxa_camera_exit(void) -+{ -+ camera_context_t *cam_ctx = g_camera_context; -+#ifdef CONFIG_DPM -+ pxa_camera_ldm_unregister(); -+#endif -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+ -+ video_unregister_device(&vd); -+ -+ free_irq(IRQ_CAMERA, &vd); -+ -+ if (ci_dma_y >= 0) -+ pxa_free_dma(ci_dma_y); -+ -+ if (ci_dma_cb >= 0) -+ pxa_free_dma(ci_dma_cb); -+ -+ if (ci_dma_cr >= 0) -+ pxa_free_dma(ci_dma_cr); -+ -+ DRCMR68 = 0; -+ DRCMR69 = 0; -+ DRCMR70 = 0; -+ -+ pxa_camera_mem_deinit(); -+ -+} -+ -+//------------------------------------------------------------------------------------------------------- -+// Configuration APIs -+//------------------------------------------------------------------------------------------------------- -+void ci_set_frame_rate(CI_FRAME_CAPTURE_RATE frate) -+{ -+ unsigned int value; -+ -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_FR_RATE_SMASK << CI_CICR4_FR_RATE_SHIFT); -+ value |= (unsigned) frate << CI_CICR4_FR_RATE_SHIFT; -+ CICR4 = value; -+} -+ -+CI_FRAME_CAPTURE_RATE ci_get_frame_rate(void) -+{ -+ unsigned int value; -+ value = CICR4; -+ return (CI_FRAME_CAPTURE_RATE) ((value >> CI_CICR4_FR_RATE_SHIFT) & CI_CICR4_FR_RATE_SMASK); -+} -+ -+void ci_set_image_format(CI_IMAGE_FORMAT input_format, CI_IMAGE_FORMAT output_format) -+{ -+ unsigned int value, tbit, rgbt_conv, rgb_conv, rgb_f, ycbcr_f, rgb_bpp, raw_bpp, cspace; -+ -+ // write cicr1: preserve ppl value and data width value -+ value = CICR1; -+ value &= ((CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT) | ((CI_CICR1_DW_SMASK) << CI_CICR1_DW_SHIFT)); -+ tbit = rgbt_conv = rgb_conv = rgb_f = ycbcr_f = rgb_bpp = raw_bpp = cspace = 0; -+ switch (input_format) { -+ case CI_RAW8: -+ cspace = 0; -+ raw_bpp = 0; -+ break; -+ case CI_RAW9: -+ cspace = 0; -+ raw_bpp = 1; -+ break; -+ case CI_RAW10: -+ cspace = 0; -+ raw_bpp = 2; -+ break; -+ case CI_YCBCR422: -+ case CI_YCBCR422_PLANAR: -+ cspace = 2; -+ if (output_format == CI_YCBCR422_PLANAR) { -+ ycbcr_f = 1; -+ } -+ break; -+ case CI_RGB444: -+ cspace = 1; -+ rgb_bpp = 0; -+ break; -+ case CI_RGB555: -+ cspace = 1; -+ rgb_bpp = 1; -+ if (output_format == CI_RGBT555_0) { -+ rgbt_conv = 2; -+ tbit = 0; -+ } else if (output_format == CI_RGBT555_1) { -+ rgbt_conv = 2; -+ tbit = 1; -+ } -+ break; -+ case CI_RGB565: -+ cspace = 1; -+ rgb_bpp = 2; -+ rgb_f = 1; -+ break; -+ case CI_RGB666: -+ cspace = 1; -+ rgb_bpp = 3; -+ if (output_format == CI_RGB666_PACKED) { -+ rgb_f = 1; -+ } -+ break; -+ case CI_RGB888: -+ case CI_RGB888_PACKED: -+ cspace = 1; -+ rgb_bpp = 4; -+ switch (output_format) { -+ case CI_RGB888_PACKED: -+ rgb_f = 1; -+ break; -+ case CI_RGBT888_0: -+ rgbt_conv = 1; -+ tbit = 0; -+ break; -+ case CI_RGBT888_1: -+ rgbt_conv = 1; -+ tbit = 1; -+ break; -+ case CI_RGB666: -+ rgb_conv = 1; -+ break; -+// RGB666 PACKED - JamesL -+ case CI_RGB666_PACKED: -+ rgb_conv = 1; -+ rgb_f = 1; -+ break; -+// end -+ case CI_RGB565: -+ rgb_conv = 2; -+ break; -+ case CI_RGB555: -+ rgb_conv = 3; -+ break; -+ case CI_RGB444: -+ rgb_conv = 4; -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ value |= (tbit == 1) ? CI_CICR1_TBIT : 0; -+ value |= rgbt_conv << CI_CICR1_RGBT_CONV_SHIFT; -+ value |= rgb_conv << CI_CICR1_RGB_CONV_SHIFT; -+ value |= (rgb_f == 1) ? CI_CICR1_RBG_F : 0; -+ value |= (ycbcr_f == 1) ? CI_CICR1_YCBCR_F : 0; -+ value |= rgb_bpp << CI_CICR1_RGB_BPP_SHIFT; -+ value |= raw_bpp << CI_CICR1_RAW_BPP_SHIFT; -+ value |= cspace << CI_CICR1_COLOR_SP_SHIFT; -+ CICR1 = value; -+ -+ return; -+} -+ -+void ci_set_mode(CI_MODE mode, CI_DATA_WIDTH data_width) -+{ -+ unsigned int value; -+ -+ // write mode field in cicr0 -+ value = CICR0; -+ value &= ~(CI_CICR0_SIM_SMASK << CI_CICR0_SIM_SHIFT); -+ value |= (unsigned int) mode << CI_CICR0_SIM_SHIFT; -+ CICR0 = value; -+ -+ // write data width cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_DW_SMASK << CI_CICR1_DW_SHIFT); -+ value |= ((unsigned) data_width) << CI_CICR1_DW_SHIFT; -+ CICR1 = value; -+ return; -+} -+ -+void ci_configure_mp(unsigned int ppl, unsigned int lpf, CI_MP_TIMING * timing) -+{ -+ unsigned int value; -+ -+ // write ppl field in cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT); -+ value |= (ppl & CI_CICR1_PPL_SMASK) << CI_CICR1_PPL_SHIFT; -+ CICR1 = value; -+ -+ // write BLW, ELW in cicr2 -+ value = CICR2; -+ value &= ~(CI_CICR2_BLW_SMASK << CI_CICR2_BLW_SHIFT | CI_CICR2_ELW_SMASK << CI_CICR2_ELW_SHIFT); -+ value |= (timing->BLW & CI_CICR2_BLW_SMASK) << CI_CICR2_BLW_SHIFT; -+ CICR2 = value; -+ -+ // write BFW, LPF in cicr3 -+ value = CICR3; -+ value &= ~(CI_CICR3_BFW_SMASK << CI_CICR3_BFW_SHIFT | CI_CICR3_LPF_SMASK << CI_CICR3_LPF_SHIFT); -+ value |= (timing->BFW & CI_CICR3_BFW_SMASK) << CI_CICR3_BFW_SHIFT; -+ value |= (lpf & CI_CICR3_LPF_SMASK) << CI_CICR3_LPF_SHIFT; -+ CICR3 = value; -+ return; -+} -+ -+void ci_configure_sp(unsigned int ppl, unsigned int lpf, CI_SP_TIMING * timing) -+{ -+ unsigned int value; -+ -+ // write ppl field in cicr1 -+ value = CICR1; -+ value &= ~(CI_CICR1_PPL_SMASK << CI_CICR1_PPL_SHIFT); -+ value |= (ppl & CI_CICR1_PPL_SMASK) << CI_CICR1_PPL_SHIFT; -+ CICR1 = value; -+ -+ // write cicr2 -+ value = CICR2; -+ value |= (timing->BLW & CI_CICR2_BLW_SMASK) << CI_CICR2_BLW_SHIFT; -+ value |= (timing->ELW & CI_CICR2_ELW_SMASK) << CI_CICR2_ELW_SHIFT; -+ value |= (timing->HSW & CI_CICR2_HSW_SMASK) << CI_CICR2_HSW_SHIFT; -+ value |= (timing->BFPW & CI_CICR2_BFPW_SMASK) << CI_CICR2_BFPW_SHIFT; -+ value |= (timing->FSW & CI_CICR2_FSW_SMASK) << CI_CICR2_FSW_SHIFT; -+ CICR2 = value; -+ -+ // write cicr3 -+ value = CICR3; -+ value |= (timing->BFW & CI_CICR3_BFW_SMASK) << CI_CICR3_BFW_SHIFT; -+ value |= (timing->EFW & CI_CICR3_EFW_SMASK) << CI_CICR3_EFW_SHIFT; -+ value |= (timing->VSW & CI_CICR3_VSW_SMASK) << CI_CICR3_VSW_SHIFT; -+ value |= (lpf & CI_CICR3_LPF_SMASK) << CI_CICR3_LPF_SHIFT; -+ CICR3 = value; -+ return; -+} -+ -+void ci_configure_ms(unsigned int ppl, unsigned int lpf, CI_MS_TIMING * timing) -+{ -+ // the operation is same as Master-Parallel -+ ci_configure_mp(ppl, lpf, (CI_MP_TIMING *) timing); -+} -+ -+void ci_configure_ep(int parity_check) -+{ -+ unsigned int value; -+ -+ // write parity_enable field in cicr0 -+ value = CICR0; -+ if (parity_check) { -+ value |= CI_CICR0_PAR_EN; -+ } else { -+ value &= ~CI_CICR0_PAR_EN; -+ } -+ CICR0 = value; -+ return; -+} -+ -+void ci_configure_es(int parity_check) -+{ -+ // the operationi is same as Embedded-Parallel -+ ci_configure_ep(parity_check); -+} -+ -+void ci_set_clock(unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz) -+{ -+ unsigned int ciclk = 0, value, div, cccr_l, K; -+ -+ // determine the LCLK frequency programmed into the CCCR. -+ cccr_l = (CCCR & 0x0000001F); -+ -+ if (cccr_l < 8) // L = [2 - 7] -+ ciclk = (13 * cccr_l) * 100; -+ else if (cccr_l < 17) // L = [8 - 16] -+ ciclk = ((13 * cccr_l) * 100) >> 1; -+ else if (cccr_l < 32) // L = [17 - 31] -+ ciclk = ((13 * cccr_l) * 100) >> 2; -+ DPRINTK("the mclk_khz = %d \n", mclk_khz); -+ -+ // want a divisor that gives us a clock rate as close to, but not more than the given mclk. -+ div = (ciclk + mclk_khz) / (2 * mclk_khz) - 1; -+ -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | CI_CICR4_DIV_SMASK << CI_CICR4_DIV_SHIFT); -+ value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0; -+ value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0; -+ value |= div << CI_CICR4_DIV_SHIFT; -+ CICR4 = value; -+ return; -+} -+ -+ -+void ci_set_polarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low) -+{ -+ unsigned int value; -+ -+ // write cicr4 -+ value = CICR4; -+ value &= ~(CI_CICR4_PCP | CI_CICR4_HSP | CI_CICR4_VSP); -+ value |= (pclk_sample_falling) ? CI_CICR4_PCP : 0; -+ value |= (hsync_active_low) ? CI_CICR4_HSP : 0; -+ value |= (vsync_active_low) ? CI_CICR4_VSP : 0; -+ CICR4 = value; -+ return; -+} -+ -+void ci_set_fifo(unsigned int timeout, CI_FIFO_THRESHOLD threshold, int fifo1_enable, int fifo2_enable) -+{ -+ unsigned int value; -+ -+ // write citor -+ CITOR = timeout; -+ -+ // write cifr: always enable fifo 0! also reset input fifo -+ value = CIFR; -+ value &= ~(CI_CIFR_FEN0 | CI_CIFR_FEN1 | CI_CIFR_FEN2 | CI_CIFR_RESETF | -+ CI_CIFR_THL_0_SMASK << CI_CIFR_THL_0_SHIFT); -+ value |= (unsigned int) threshold << CI_CIFR_THL_0_SHIFT; -+ value |= (fifo1_enable) ? CI_CIFR_FEN1 : 0; -+ value |= (fifo2_enable) ? CI_CIFR_FEN2 : 0; -+ value |= CI_CIFR_RESETF | CI_CIFR_FEN0; -+ CIFR = value; -+ return; -+} -+ -+void ci_reset_fifo() -+{ -+ unsigned int value; -+ value = CIFR; -+ value |= CI_CIFR_RESETF; -+ CIFR = value; -+} -+ -+void ci_set_int_mask(unsigned int mask) -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value &= ~CI_CICR0_INTERRUPT_MASK; -+ value |= (mask & CI_CICR0_INTERRUPT_MASK); -+ CICR0 = value; -+ return; -+} -+ -+unsigned int ci_get_int_mask() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ return (value & CI_CICR0_INTERRUPT_MASK); -+} -+ -+void ci_clear_int_status(unsigned int status) -+{ -+ // write 1 to clear -+ CISR = status; -+} -+ -+unsigned int ci_get_int_status() -+{ -+ int value; -+ -+ value = CISR; -+ -+ return value; -+} -+ -+void ci_set_reg_value(unsigned int reg_offset, unsigned int value) -+{ -+ CI_REG((u32) (ci_regs_base) + reg_offset) = value; -+} -+ -+int ci_get_reg_value(unsigned int reg_offset) -+{ -+ int value; -+ -+ value = CI_REG((u32) (ci_regs_base) + reg_offset); -+ return value; -+} -+ -+//------------------------------------------------------------------------------------------------------- -+// Control APIs -+//------------------------------------------------------------------------------------------------------- -+int ci_init() -+{ -+ // clear all CI registers -+ CICR0 = 0x3FF; // disable all interrupts -+ CICR1 = 0; -+ CICR2 = 0; -+ CICR3 = 0; -+ CICR4 = 0; -+ CISR = ~0; -+ CIFR = 0; -+ CITOR = 0; -+ -+ // enable CI clock -+ CKEN |= CKEN24_CAMERA; -+ return 0; -+} -+ -+void ci_deinit() -+{ -+ // disable CI clock -+ CKEN &= ~CKEN24_CAMERA; -+} -+ -+void ci_enable(int dma_en) -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value |= CI_CICR0_ENB; -+ if (dma_en) { -+ value |= CI_CICR0_DMA_EN; -+ } -+ CICR0 = value; -+ return; -+} -+ -+int ci_disable(int quick) -+{ -+ volatile unsigned int value, mask; -+ int retry; -+ -+ // write control bit in cicr0 -+ value = CICR0; -+ if (quick) { -+ value &= ~CI_CICR0_ENB; -+ mask = CI_CISR_CQD; -+ } else { -+ value |= CI_CICR0_DIS; -+ mask = CI_CISR_CDD; -+ } -+ CICR0 = value; -+ -+ // wait shutdown complete -+ retry = 50; -+ while (retry-- > 0) { -+ value = CISR; -+ if (value & mask) { -+ CISR = mask; -+ return 0; -+ } -+ mdelay(10); -+ } -+ -+ return -1; -+} -+ -+void ci_slave_capture_enable() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value |= CI_CICR0_SL_CAP_EN; -+ CICR0 = value; -+ return; -+} -+ -+void ci_slave_capture_disable() -+{ -+ unsigned int value; -+ -+ // write mask in cicr0 -+ value = CICR0; -+ value &= ~CI_CICR0_SL_CAP_EN; -+ CICR0 = value; -+ return; -+} -+ -+void pxa_ci_dma_irq_y(int channel, void *data, struct pt_regs *regs) -+{ -+ int dcsr; -+ static int dma_repeated = 0; -+ static unsigned int count = 0; -+ -+ camera_context_t *cam_ctx = g_camera_context; -+ -+ dcsr = DCSR(channel); -+ DCSR(channel) = dcsr & ~DCSR_STOPIRQEN; -+ if (!((count++) % 100)) -+ DPRINTK("int occure\n"); -+ if (still_image_mode == 1) { -+ DPRINTK("pxa_ci_dma_irq_y interrupt,task_waiting =%d, still_image_rdy=%d\n", -+ task_waiting, still_image_rdy); -+ if (task_waiting == 1) { -+ DPRINTK("task waiting"); -+ wake_up_interruptible(&camera_wait_q); -+ task_waiting = 0; -+ } -+ still_image_rdy = 1; -+ } else if (dma_repeated == 0 && (cam_ctx->block_tail == ((cam_ctx->block_header + 2) % cam_ctx->block_number))) { -+ dma_repeated = 1; -+ pxa_dma_repeat(cam_ctx); -+ cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ } else if (dma_repeated == 1 && (cam_ctx->block_tail != ((cam_ctx->block_header + 1) % cam_ctx->block_number)) -+ && (cam_ctx->block_tail != ((cam_ctx->block_header + 2) % cam_ctx->block_number))) { -+ pxa_dma_continue(cam_ctx); -+ dma_repeated = 0; -+ } else if (dma_repeated == 0) { -+ cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ } -+ if (task_waiting == 1 && !(cam_ctx->block_header == cam_ctx->block_tail)) { -+ wake_up_interruptible(&camera_wait_q); -+ task_waiting = 0; -+ } -+} -+ -+void pxa_ci_dma_irq_cb(int channel, void *data, struct pt_regs *regs) -+{ -+ return; -+} -+ -+void pxa_ci_dma_irq_cr(int channel, void *data, struct pt_regs *regs) -+{ -+ return; -+} -+ -+inline static void pxa_ci_dma_stop(camera_context_t * cam_ctx) -+{ -+ int ch0, ch1, ch2; -+ -+ ch0 = cam_ctx->dma_channels[0]; -+ ch1 = cam_ctx->dma_channels[1]; -+ ch2 = cam_ctx->dma_channels[2]; -+ DCSR(ch0) &= ~DCSR_RUN; -+ DCSR(ch1) &= ~DCSR_RUN; -+ DCSR(ch2) &= ~DCSR_RUN; -+} -+ -+ -+void pxa_dma_start(camera_context_t * cam_ctx) -+{ -+ unsigned char cnt_blk; -+ pxa_dma_desc *cnt_desc; -+ -+ cam_ctx->block_header = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+ cnt_blk = (unsigned char) cam_ctx->block_header; -+ -+ cnt_desc = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_physical + cnt_blk * cam_ctx->fifo0_num_descriptors; -+ -+ DDADR(cam_ctx->dma_channels[0]) = cnt_desc; -+ DCSR(cam_ctx->dma_channels[0]) |= DCSR_RUN; -+ -+ if (cam_ctx->fifo1_num_descriptors) { -+ cnt_desc = -+ (pxa_dma_desc *) cam_ctx->fifo1_descriptors_physical + cnt_blk * cam_ctx->fifo1_num_descriptors; -+ DDADR(cam_ctx->dma_channels[1]) = cnt_desc; -+ DCSR(cam_ctx->dma_channels[1]) |= DCSR_RUN; -+ } -+ -+ if (cam_ctx->fifo2_num_descriptors) { -+ cnt_desc = -+ (pxa_dma_desc *) cam_ctx->fifo2_descriptors_physical + cnt_blk * cam_ctx->fifo2_num_descriptors; -+ DDADR(cam_ctx->dma_channels[2]) = cnt_desc; -+ DCSR(cam_ctx->dma_channels[2]) |= DCSR_RUN; -+ } -+ -+ return; -+} -+ -+ -+void pxa_camera_irq(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ int cisr; -+ static int dma_started = 0; -+ -+ disable_irq(IRQ_CAMERA); -+ -+ cisr = CISR; -+ if (cisr & CI_CISR_SOF) { -+ DPRINTK("CI_CISR_SOF \n"); -+ if (dma_started == 0) { -+ dma_started = 1; -+ } -+ CISR |= CI_CISR_SOF; -+ } -+ if (cisr & CI_CISR_EOF) { -+ DPRINTK("CI_CISR_EOF\n"); -+ CISR |= CI_CISR_EOF; -+ //wake_up_interruptible(&camera_wait_q); -+ } -+ enable_irq(IRQ_CAMERA); -+} -+ -+void pxa_dma_repeat(camera_context_t * cam_ctx) -+{ -+ pxa_dma_desc *cnt_head, *cnt_tail; -+ int cnt_block; -+ -+ cnt_block = (cam_ctx->block_header + 1) % cam_ctx->block_number; -+// FIFO0 -+ (pxa_dma_desc *) cnt_head = -+ (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual + cnt_block * cam_ctx->fifo0_num_descriptors; -+ cnt_tail = cnt_head + cam_ctx->fifo0_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+// FIFO1 -+ if (cam_ctx->fifo1_transfer_size) { -+ cnt_head = -+ (pxa_dma_desc *) cam_ctx->fifo1_descriptors_virtual + cnt_block * cam_ctx->fifo1_num_descriptors; -+ cnt_tail = cnt_head + cam_ctx->fifo1_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+ } -+// FIFO2 -+ if (cam_ctx->fifo2_transfer_size) { -+ cnt_head = -+ (pxa_dma_desc *) cam_ctx->fifo2_descriptors_virtual + cnt_block * cam_ctx->fifo2_num_descriptors; -+ cnt_tail = cnt_head + cam_ctx->fifo2_num_descriptors - 1; -+ cnt_tail->ddadr = cnt_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ return; -+} -+ -+void pxa_dma_continue(camera_context_t * cam_ctx) -+{ -+ pxa_dma_desc *cnt_head, *cnt_tail; -+ pxa_dma_desc *next_head; -+ int cnt_block, next_block; -+ -+ cnt_block = cam_ctx->block_header; -+ next_block = (cnt_block + 1) % cam_ctx->block_number; -+// FIFO0 -+ cnt_head = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual + cnt_block * cam_ctx->fifo0_num_descriptors; -+ cnt_tail = cnt_head + cam_ctx->fifo0_num_descriptors - 1; -+ next_head = (pxa_dma_desc *) cam_ctx->fifo0_descriptors_virtual + next_block * cam_ctx->fifo0_num_descriptors; -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+// FIFO1 -+ if (cam_ctx->fifo1_transfer_size) { -+ cnt_head = -+ (pxa_dma_desc *) cam_ctx->fifo1_descriptors_virtual + cnt_block * cam_ctx->fifo1_num_descriptors; -+ cnt_tail = cnt_head + cam_ctx->fifo1_num_descriptors - 1; -+ next_head = -+ (pxa_dma_desc *) cam_ctx->fifo1_descriptors_virtual + next_block * cam_ctx->fifo1_num_descriptors; -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+ } -+// FIFO2 -+ if (cam_ctx->fifo2_transfer_size) { -+ cnt_head = -+ (pxa_dma_desc *) cam_ctx->fifo2_descriptors_virtual + cnt_block * cam_ctx->fifo2_num_descriptors; -+ cnt_tail = cnt_head + cam_ctx->fifo2_num_descriptors - 1; -+ next_head = -+ (pxa_dma_desc *) cam_ctx->fifo2_descriptors_virtual + next_block * cam_ctx->fifo2_num_descriptors; -+ cnt_tail->ddadr = next_head->ddadr - sizeof(pxa_dma_desc); -+ } -+ return; -+ -+} -+ -+void ci_dump(void) -+{ -+ DPRINTK("CICR0 = 0x%8x \n", CICR0); -+ DPRINTK("CICR1 = 0x%8x \n", CICR1); -+ DPRINTK("CICR2 = 0x%8x \n", CICR2); -+ DPRINTK("CICR3 = 0x%8x \n", CICR3); -+ DPRINTK("CICR4 = 0x%8x \n", CICR4); -+ DPRINTK("CISR = 0x%8x \n", CISR); -+ DPRINTK("CITOR = 0x%8x \n", CITOR); -+ DPRINTK("CIFR = 0x%8x \n", CIFR); -+} -+ -+module_init(pxa_camera_init); -+module_exit(pxa_camera_exit); -+ -+MODULE_DESCRIPTION("Bulverde Camera Interface driver"); -+MODULE_LICENSE("GPL"); -+EXPORT_NO_SYMBOLS; -diff -Nru --exclude-from=/sunbeam/home/laforge/scripts/dontdiff linux-2.6.16.5/include/linux/pxa_camera.h linux-2.6.16.5-exz/include/linux/pxa_camera.h ---- linux-2.6.16.5/include/linux/pxa_camera.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16.5-exz/include/linux/pxa_camera.h 2006-04-16 18:49:29.000000000 +0200 -@@ -0,0 +1,445 @@ -+/*================================================================================ -+ -+ Module Name: pxa-camera.h -+ -+General Description: E680/A780 camera driver header -+ -+================================================================================== -+ Motorola Confidential Proprietary -+ Advanced Technology and Software Operations -+ (c) Copyright Motorola 1999, All Rights Reserved -+ -+Revision History: -+ Modification Tracking -+Author Date Number Description of Changes -+---------------- ------------ ---------- ------------------------- -+Wang Fei/w20239 12/19/2003 LIBdd35749 Created -+Wang Fei/w20239 02/05/2004 LIBdd74309 Set frame rate in video mode -+Wang Fei/w20239 03/08/2004 LIBdd84578 Photo effects setting -+Wang Fei/w20239 11/01/2004 LIBxxxxxxx Change to SDK style -+ -+================================================================================== -+ INCLUDE FILES -+================================================================================*/ -+#ifndef __PXA_CAMERA_H__ -+#define __PXA_CAMERA_H__ -+ -+/*! -+ * General description of the Motorola A780/E680 video device driver: -+ * -+ * The Motorola A780/E680 video device is based on V4L (video for linux) 1.0, however not -+ * all V4L features are supported. -+ * There are also some additional extensions included for specific requirements beyond V4L. -+ * -+ * The video device driver has a "character special" file named /dev/video0. Developers can -+ * access the video device via the file operator interfaces. -+ * Six file operator interfaces are supported: -+ * open -+ * ioctl -+ * mmap -+ * poll/select -+ * read -+ * close -+ * For information on using these fuctions, please refer to the standard linux -+ * development documents. -+ * -+ * These four ioctl interfaces are important for getting the video device to work properly: -+ * VIDIOCGCAP Gets the video device capability -+ * VIDIOCCAPTURE Starts/stops the video capture -+ * VIDIOCGMBUF Gets the image frame buffer map info -+ * VIDIOCSWIN Sets the picture size -+ * These interfaces are compatible with V4L 1.0. Please refer to V4L documents for more details. -+ * sample.c demonstrates their use. -+ * -+ * The following ioctl interfaces are Motorola-specific extensions. These are not compatible with V4L 1.0. -+ * WCAM_VIDIOCSCAMREG -+ * WCAM_VIDIOCGCAMREG -+ * WCAM_VIDIOCSCIREG -+ * WCAM_VIDIOCGCIREG -+ * WCAM_VIDIOCSINFOR -+ * WCAM_VIDIOCGINFOR -+ * WCAM_VIDIOCSSSIZE -+ * WCAM_VIDIOCSOSIZE -+ * WCAM_VIDIOCGSSIZE -+ * WCAM_VIDIOCGOSIZE -+ * WCAM_VIDIOCSFPS -+ * WCAM_VIDIOCSNIGHTMODE -+ * WCAM_VIDIOCSSTYLE -+ * WCAM_VIDIOCSLIGHT -+ * WCAM_VIDIOCSBRIGHT -+ * WCAM_VIDIOCSBUFCOUNT -+ * WCAM_VIDIOCGCURFRMS -+ * WCAM_VIDIOCGSTYPE -+ * WCAM_VIDIOCSCONTRAST -+ * WCAM_VIDIOCSFLICKER -+ * Detailed information about these constants are described below. -+ * -+ * sample.c demonstrates most features of the Motorola A780/E680 video device driver. -+ * - Opening/closing the video device -+ * - Initializing the video device driver -+ * - Displaying the video image on a A780/E680 LCD screen -+ * - Changing the image size -+ * - Changing the style -+ * - Changing the light mode -+ * - Changing the brightness -+ * - Capturing and saving a still picture -+ */ -+ -+/*! -+ * These are the registers for the read/write camera module and the CIF -+ * (Intel PXA27x processer quick capture interface) -+ * The following 4 ioctl interfaces are used for debugging and are not open to developers -+ */ -+#define WCAM_VIDIOCSCAMREG 211 -+#define WCAM_VIDIOCGCAMREG 212 -+#define WCAM_VIDIOCSCIREG 213 -+#define WCAM_VIDIOCGCIREG 214 -+ -+/*! -+ * WCAM_VIDIOCSINFOR Sets the image data format -+ * -+ * The following code sets the image format to YCbCr422_planar -+ * -+ * struct {int val1, val2;}format; -+ * format.val1 = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ * format.val2 = CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR; -+ * //dev is the video device handle -+ * ioctl(dev, WCAM_VIDIOCSINFOR, &format); -+ * -+ * Remarks: -+ * val1 is the output format of the camera module, val2 is the output format of the CIF (capture -+ * interface). Image data from the camera module can be converted to other formats through -+ * the CIF. val2 specifies the final output format of the video device. -+ * -+ * For more description on CIF please refer to the Intel PXA27x processor family developer's manual. -+ * http://www.intel.com/design/pca/prodbref/253820.html -+ */ -+#define WCAM_VIDIOCSINFOR 215 -+ -+/* -+ * WCAM_VIDIOCGINFOR Gets the image data format -+ * -+ * struct {int val1, val2;}format; -+ * ioctl(dev, WCAM_VIDIOCGINFOR, &format); -+ */ -+#define WCAM_VIDIOCGINFOR 216 -+ -+/*! -+ * WCAM_VIDIOCSSSIZE Sets the sensor window size -+ * -+ * The following code sets the sensor size to 640 X 480: -+ * -+ * struct {unsigned short w, h;}sensor_size; -+ * sensor_size.w = 640; -+ * sensor_size.h = 480; -+ * //dev is the video device handle -+ * ioctl(dev, WCAM_VIDIOCSSSIZE, &sensor_size); -+ * -+ * Remarks: -+ * The sensor size is restricted by the video device capability. -+ * VIDIOCGCAP can get the video device capability. -+ * The sensor size must be an even of multiple of 8. If not, the driver changes the sensor size to a multiple of 8. -+ */ -+#define WCAM_VIDIOCSSSIZE 217 -+ -+/*! -+ * WCAM_VIDIOCSOSIZE Sets output size of the video device -+ * -+ * The following code segment shows how to set the output size to 240 X 320: -+ * -+ * struct {unsigned short w, h;}out_size; -+ * out_size.w = 240; -+ * out_size.h = 320; -+ * //dev is the video device handle -+ * ioctl(dev, WCAM_VIDIOCSSSIZE, &out_size); -+ * -+ * Remarks: -+ * In video mode, the output size must be less than 240X320. However, in still mode, the output -+ * size is restricted by the video device capability and the sensor size. -+ * The output size must always be less than the sensor size, so if the developer changes the output size -+ * to be greater than the sensor size, the video device driver may work abnormally. -+ * The width and height must also be a multiple of 8. If it is not, the driver changes the width and height size to a multiple of 8. -+ * The developer can modify the sensor size and the output size to create a digital zoom. -+ */ -+#define WCAM_VIDIOCSOSIZE 218 -+ -+/*! -+ * WCAM_VIDIOCGSSIZE Gets the current sensor size. -+ * -+ * The following code segment shows how to use this function: -+ * -+ * struct {unsigned short w, h;}sensor_size; -+ * //dev is the video device handle -+ * ioctl(dev, WCAM_VIDIOCGSSIZE, &sensor_size); -+ * printf("sensor width is %d, sensor_height is %d\n", sensor_size.w, sensor_size.h); -+ * -+ */ -+#define WCAM_VIDIOCGSSIZE 219 -+ -+/*! -+ * WCAM_VIDIOCGOSIZE Gets the current output size. -+ * -+ * The following code segment shows how to use this function: -+ * -+ * struct {unsigned short w, h;}out_size; -+ * //dev is the video device handle -+ * ioctl(dev, WCAM_VIDIOCGOSIZE, &out_size); -+ * printf("output width is %d, output height is %d\n", out_size.w, out_size.h); -+ * -+ */ -+#define WCAM_VIDIOCGOSIZE 220 -+ -+/*! -+ * WCAM_VIDIOCSFPS Sets the output frame rate (fps- frames per second) of the video device -+ * -+ * The following code segment shows how to use this function: -+ * -+ * struct {int maxfps, minfps;}fps; -+ * fps.maxfps = 15; -+ * fps.minfps = 12; -+ * ioctl(dev, WCAM_VIDIOCSFPS, &fps); -+ * -+ * Remarks: -+ * The minimum value of maxfps is 1; the maximum value is 15. minfps must not exceed maxfps. -+ * The default value of fps is [15, 10]. -+ * minfps and maxfps only suggest a fps range. The video device driver will select -+ * an appropriate value automatically. The actual fps depends on environmental circumstances -+ * such as brightness, illumination, etc. -+ * sample.c illustrates how to calculate actual frame rate. -+ * -+ */ -+#define WCAM_VIDIOCSFPS 221 -+ -+/*! -+ * WCAM_VIDIOCSNIGHTMODE Sets the video device capture mode. -+ * -+ * The capture mode can use the following values -+ * -+ * V4l_NM_AUTO Auto mode(default value) -+ * V4l_NM_NIGHT Night mode -+ * V4l_NM_ACTION Action mode -+ * -+ * The following code segment shows how to set the video device to night mode: -+ * -+ * ioctl(dev, WCAM_VIDIOCSNIGHTMODE, V4l_NM_NIGHT); -+ * -+ * Remarks: -+ * Different capture modes represent different sensor exposure times. Night mode represents a longer -+ * exposure time. Setting the video device to night mode can capture high quality image data in low light environments. -+ * Action mode represents a shorter exposure time. This is used for capture moving objects. When working in auto mode, the -+ * video device will select an appropriate exposure time automatically. -+ * -+ * Not all camera modules support this interface. Developers can also use WCAM_VIDIOCSFPS to achieve similar results. -+ * Smaller minfps represent longer exposure times. -+ * -+ */ -+#define WCAM_VIDIOCSNIGHTMODE 222 -+ -+/*! -+ * WCAM_VIDIOCSSTYLE Sets the image style. -+ * -+ * The following styles are supported: -+ * -+ * V4l_STYLE_NORMAL Normal (default value) -+ * V4l_STYLE_BLACK_WHITE Black and white -+ * V4l_STYLE_SEPIA Sepia -+ * V4l_STYLE_SOLARIZE Solarized (not supported by all camera modules) -+ * V4l_STYLE_NEG_ART Negative (not supported by all camera modules) -+ * -+ * The following code segment demonstrates how to set the image style to black and white: -+ * -+ * ioctl(dev, WCAM_VIDIOCSSTYLE, V4l_STYLE_BLACK_WHITE); -+ * -+ */ -+#define WCAM_VIDIOCSSTYLE 250 -+ -+/*! -+ * WCAM_VIDIOCSLIGHT Sets the image light mode -+ * -+ * The following light modes are supported: -+ * V4l_WB_AUTO Auto mode(default) -+ * V4l_WB_DIRECT_SUN Direct sun -+ * V4l_WB_INCANDESCENT Incandescent -+ * V4l_WB_FLUORESCENT Fluorescent -+ * -+ * The following code sets the image light mode to incandescent: -+ * ioctl(dev, WCAM_VIDIOCSLIGHT, V4l_WB_INCANDESCENT); -+ */ -+#define WCAM_VIDIOCSLIGHT 251 -+ -+/*! -+ * WCAM_VIDIOCSBRIGHT Sets the brightness of the image (exposure compensation value) -+ * -+ * parameter value exposure value -+ * -4 -2.0 EV -+ * -3 -1.5 EV -+ * -2 -1.0 EV -+ * -1 -0.5 EV -+ * 0 0.0 EV(default value) -+ * 1 +0.5 EV -+ * 2 +1.0 EV -+ * 3 +1.5 EV -+ * 4 +2.0 EV -+ * -+ * The following code segment sets the brightness to 2.0 EV -+ * ioctl(dev, WCAM_VIDIOCSBRIGHT, 4); -+ */ -+#define WCAM_VIDIOCSBRIGHT 252 -+ -+/*! -+ * Sets the frame buffer count for video mode. The default value is 3. -+ * -+ * Remarks: -+ * The video device driver maintains some memory for buffering image data in the kernel space. When working in video mode, -+ * there are at least 3 frame buffers in the driver. In still mode, there is only 1 frame buffer. -+ * This interface is not open to SDK developers. -+ * -+ */ -+#define WCAM_VIDIOCSBUFCOUNT 253 -+ -+/*! -+ * Gets the current available frames -+ * -+ * The following code demonstrates getting the current available frames: -+ * -+ * struct {int first, last;}cur_frms; -+ * ioctl(dev, WCAM_VIDIOCGCURFRMS, &cur_frms); -+ * -+ * Remarks: -+ * cur_frms.first represents the earliest frame in frame buffer -+ * cur_frms.last represents the latest or most recent frame in frame buffer. -+ */ -+#define WCAM_VIDIOCGCURFRMS 254 -+ -+/*! -+ * Gets the camera sensor type -+ * -+ * unsigned int sensor_type -+ * ioctl(dev, WCAM_VIDIOCGSTYPE, &sensor_type); -+ * if(sensor_type == CAMERA_TYPE_ADCM_2700) -+ * { -+ * printf("Agilent ADCM2700"); -+ * } -+ * -+ * Remarks: -+ * For all possible values of sensor_type please refer to the sensor definitions below. -+ */ -+#define WCAM_VIDIOCGSTYPE 255 -+ -+/*! -+ * Sets the image contrast -+ * Not open to SDK developers -+ */ -+#define WCAM_VIDIOCSCONTRAST 256 -+ -+/*! -+ * Sets the flicker frequency(50hz/60hz) -+ * Not open to SDK developers -+ */ -+#define WCAM_VIDIOCSFLICKER 257 -+ -+ -+ -+typedef enum V4l_NIGHT_MODE -+{ -+ V4l_NM_AUTO, -+ V4l_NM_NIGHT, -+ V4l_NM_ACTION -+}V4l_NM; -+ -+typedef enum V4l_PIC_STYLE -+{ -+ V4l_STYLE_NORMAL, -+ V4l_STYLE_BLACK_WHITE, -+ V4l_STYLE_SEPIA, -+ V4l_STYLE_SOLARIZE, -+ V4l_STYLE_NEG_ART -+}V4l_PIC_STYLE; -+ -+typedef enum V4l_PIC_WB -+{ -+ V4l_WB_AUTO, -+ V4l_WB_DIRECT_SUN, -+ V4l_WB_INCANDESCENT, -+ V4l_WB_FLUORESCENT -+}V4l_PIC_WB; -+ -+ -+ -+/*! -+ *Image format definitions -+ *Remarks: -+ * Although not all formats are supported by all camera modules, YCBCR422_PLANAR is widely supported. -+ * For detailed information on each format please refer to the Intel PXA27x processor family developer's manual. -+ * http://www.intel.com/design/pca/prodbref/253820.html -+ * -+ */ -+#define CAMERA_IMAGE_FORMAT_RAW8 0 -+#define CAMERA_IMAGE_FORMAT_RAW9 1 -+#define CAMERA_IMAGE_FORMAT_RAW10 2 -+ -+#define CAMERA_IMAGE_FORMAT_RGB444 3 -+#define CAMERA_IMAGE_FORMAT_RGB555 4 -+#define CAMERA_IMAGE_FORMAT_RGB565 5 -+#define CAMERA_IMAGE_FORMAT_RGB666_PACKED 6 -+#define CAMERA_IMAGE_FORMAT_RGB666_PLANAR 7 -+#define CAMERA_IMAGE_FORMAT_RGB888_PACKED 8 -+#define CAMERA_IMAGE_FORMAT_RGB888_PLANAR 9 -+#define CAMERA_IMAGE_FORMAT_RGBT555_0 10 //RGB+Transparent bit 0 -+#define CAMERA_IMAGE_FORMAT_RGBT888_0 11 -+#define CAMERA_IMAGE_FORMAT_RGBT555_1 12 //RGB+Transparent bit 1 -+#define CAMERA_IMAGE_FORMAT_RGBT888_1 13 -+ -+#define CAMERA_IMAGE_FORMAT_YCBCR400 14 -+#define CAMERA_IMAGE_FORMAT_YCBCR422_PACKED 15 -+#define CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR 16 -+#define CAMERA_IMAGE_FORMAT_YCBCR444_PACKED 17 -+#define CAMERA_IMAGE_FORMAT_YCBCR444_PLANAR 18 -+ -+/*! -+ *VIDIOCCAPTURE arguments -+ */ -+#define STILL_IMAGE 1 -+#define VIDEO_START 0 -+#define VIDEO_STOP -1 -+ -+/*! -+ *Sensor type definitions -+ */ -+#define CAMERA_TYPE_ADCM_2650 1 -+#define CAMERA_TYPE_ADCM_2670 2 -+#define CAMERA_TYPE_ADCM_2700 3 -+#define CAMERA_TYPE_OMNIVISION_9640 4 -+#define CAMERA_TYPE_MT9M111 5 -+#define CAMERA_TYPE_MT9V111 6 -+#define CAMERA_TYPE_ADCM3800 7 -+#define CAMERA_TYPE_OV9650 8 -+#define CAMERA_TYPE_MAX CAMERA_TYPE_OV9650 -+ -+ -+/* -+ * Definitions of the camera's i2c device -+ */ -+#define CAMERA_I2C_WRITEW 101 -+#define CAMERA_I2C_WRITEB 102 -+#define CAMERA_I2C_READW 103 -+#define CAMERA_I2C_READB 104 -+#define CAMERA_I2C_DETECTID 105 -+ -+struct camera_i2c_register { -+ unsigned short addr; -+ union { -+ unsigned short w; -+ unsigned char b; -+ } value; -+}; -+ -+struct camera_i2c_detectid { -+ int buflen; -+ char data[256]; -+}; -+ -+//End of the camera's i2c device -+ -+#endif // __PXA_CAMERA_H__ -+ |