|
From: <hap...@us...> - 2007-06-12 13:19:26
|
Revision: 1030
http://svn.sourceforge.net/hackndev/?rev=1030&view=rev
Author: happy-slapin
Date: 2007-06-12 06:19:23 -0700 (Tue, 12 Jun 2007)
Log Message:
-----------
PXA27x: camera: Added more code
Modified Paths:
--------------
linux4palm/linux/trunk/drivers/media/video/pxa_camera.c
Added Paths:
-----------
linux4palm/linux/trunk/drivers/media/video/pxa_ci_types.h
Modified: linux4palm/linux/trunk/drivers/media/video/pxa_camera.c
===================================================================
--- linux4palm/linux/trunk/drivers/media/video/pxa_camera.c 2007-06-11 22:47:38 UTC (rev 1029)
+++ linux4palm/linux/trunk/drivers/media/video/pxa_camera.c 2007-06-12 13:19:23 UTC (rev 1030)
@@ -11,7 +11,7 @@
* MontaVista Software, Inc.
* so...@mv...
* Motorola Inc.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -79,73 +79,83 @@
#include <linux/videodev.h>
#endif
+#include "pxa_ci_types"
+
/***********************************************************************************
-* Application interface *
-***********************************************************************************/
+ * Application interface *
+ ***********************************************************************************/
static int pxa_camera_open(struct inode *inode, struct file *file)
{
- return -EIO;
+ return -EIO;
}
+
static int pxa_camera_close(struct inode *inode, struct file *file)
{
- return 0;
+ return 0;
}
+
static ssize_t pxa_camera_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+size_t count, loff_t *ppos)
{
- return 0;
+ return 0;
}
-static unsigned int pxa_camera_poll(struct file *file, poll_table *wait)
+
+static unsigned int pxa_camera_poll(struct file *file, poll_table *wait)
{
- return 0;
+ return 0;
}
+
static int pxa_camera_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+unsigned int cmd, unsigned long arg)
{
- return 0;
+ return 0;
}
+
static int pxa_camera_mmap(struct file *file, struct vm_area_struct *vma)
{
- return -EFAULT;
+ return -EFAULT;
}
+
static ssize_t pxa_camera_write(struct file *file, const char __user *data,
- size_t count, loff_t *ppos)
+size_t count, loff_t *ppos)
{
- return -EINVAL;
+ return -EINVAL;
}
-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 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 = "PXA camera",
- .type = VID_TYPE_CAPTURE,
-/*
- .hardware = VID_HARDWARE_PXA_CAMERA, /* FIXME */
-*/
- .hardware = 0;
- .fops = &vd_fops,
- .minor = -1,
+static struct video_device vd =
+{
+ .owner = THIS_MODULE,
+ .name = "PXA camera",
+ .type = VID_TYPE_CAPTURE,
+ /*
+ .hardware = VID_HARDWARE_PXA_CAMERA, /* FIXME */
+ */
+ .hardware = 0;
+ .fops = &vd_fops,
+ .minor = -1,
};
-
static irqreturn_t pxa_camera_irq(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned int cisr;
@@ -153,38 +163,445 @@
disable_irq(IRQ_CAMERA);
cisr = CISR;
- if (cisr & CI_CISR_SOF)
- CISR |= CI_CISR_SOF;
+ if (cisr & CI_CISR_SOF)
+ CISR |= CI_CISR_SOF;
- if (cisr & CI_CISR_EOF)
- CISR |= CI_CISR_EOF;
+ if (cisr & CI_CISR_EOF)
+ CISR |= CI_CISR_EOF;
enable_irq(IRQ_CAMERA);
return IRQ_HANDLED;
}
+
static int __init pxa_camera_init(void)
{
- if (request_irq(IRQ_CAMERA, pxa_camera_irq, 0, "PXA Camera", &vd)) {
+ 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");
-
- if(video_register_device(&vd, VFL_TYPE_GRABBER, 0) < 0)
- {
- dbg_print("PXA_CAMERA: video_register_device failed\n");
- return -EIO;
- }
+ }
+ dbg_print ("Camera interrupt register successful \n");
- dbg_print("PXA_CAMERA: video_register_device successfully. /dev/video%d \n", 0);
-
- return 0;
+ if(video_register_device(&vd, VFL_TYPE_GRABBER, 0) < 0)
+ {
+ dbg_print("PXA_CAMERA: video_register_device failed\n");
+ return -EIO;
+ }
+
+ dbg_print("PXA_CAMERA: video_register_device successfully. /dev/video%d \n", 0);
+
+ return 0;
}
+
static void __exit pxa_camera_exit(void)
{
- free_irq(IRQ_CAMERA, &vd);
- video_unregister_device(&vd);
+ free_irq(IRQ_CAMERA, &vd);
+ 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;
+}
Added: linux4palm/linux/trunk/drivers/media/video/pxa_ci_types.h
===================================================================
--- linux4palm/linux/trunk/drivers/media/video/pxa_ci_types.h (rev 0)
+++ linux4palm/linux/trunk/drivers/media/video/pxa_ci_types.h 2007-06-12 13:19:23 UTC (rev 1030)
@@ -0,0 +1,692 @@
+/*
+ * camera.h
+ *
+ * Bulverde Processor Camera Interface driver.
+ *
+ * Copyright (C) 2003, Intel Corporation
+ * Copyright (C) 2003, Montavista Software Inc.
+ * Copyright (C) 2003-2006 Motorola Inc.
+ *
+ * Author: Intel Corporation Inc.
+ * MontaVista Software, Inc.
+ * so...@mv...
+ * Motorola Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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.
+ *
+
+Revision History:
+ Modification Tracking
+ Date Description of Changes
+ ------------ -------------------------
+ 12/19/2003 Created
+ 02/26/2004 Update algorithm for DMA transfer
+ 04/12/2006 fix sensor name
+
+*/
+
+/*================================================================================
+ INCLUDE FILES
+================================================================================*/
+#ifndef PXA_CI_TYPES_H_
+#define PXA_CI_TYPES_H_
+
+#include <linux/pxa_camera.h>
+
+#define DEBUG 1
+
+/*
+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);
+unsigned int ci_set_clock(unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_mhz);
+unsigned int ci_get_clock(void);
+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);
+void pxa_fvgpio_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+#define err_print(fmt, args...) printk(KERN_ERR "fun %s "fmt"\n", __FUNCTION__, ##args)
+
+#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
+
+ /* subject to change */
+#define VID_HARDWARE_PXA_CAMERA 50
+
+#define STATUS_FAILURE (0)
+#define STATUS_SUCCESS (1)
+#define STATUS_WRONG_PARAMETER -1
+
+/*
+Macros
+*/
+
+/*
+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
+
+#define CAMERA_ERROR_NONE 0
+#define CAMERA_ERROR_FVNOTSYNC -1
+#define CAMERA_ERROR_FIFONOTEMPTY -2
+#define CAMERA_ERROR_UNEXPECTEDINT -3
+
+/*
+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 still_width;
+ unsigned int still_height;
+
+ unsigned int camera_width;
+ unsigned int camera_height;
+
+ unsigned int capture_input_format;
+ unsigned int capture_output_format;
+ unsigned int still_input_format;
+ unsigned int still_output_format;
+
+ unsigned int capture_digital_zoom;
+ unsigned int still_digital_zoom;
+
+ int plane_number;
+
+ int still_image_mode;
+ int camera_mode;
+
+ int jpeg_quality;
+
+ int waiting_frame;
+ int fv_rising_edge;
+ int preferred_block_num;
+ int still_image_rdy;
+ int task_waiting;
+ int detected_sensor_type;
+
+ 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;
+
+ unsigned planeOffset[VIDEO_MAX_FRAME][3];
+ unsigned planeBytes[VIDEO_MAX_FRAME][3];
+
+ /*
+ * 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, int set_sensor );
+
+// 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, int set_sensor);
+
+// disable motion video image capture
+void camera_stop_video_capture( p_camera_context_t camera_context );
+
+// skip frame before capture video or still image
+void camera_skip_frame( p_camera_context_t camera_context, int skip_frame_num );
+
+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);
+
+// power management deep idle
+#define USE_CAM_IPM_HOOK
+extern int cam_ipm_hook(void);
+extern void cam_ipm_unhook(void);
+
+// lock functions
+extern void camera_lock(void);
+extern void camera_unlock(void);
+extern int camera_trylock(void);
+#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|