mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-09-12 09:33:20 +03:00
(stable-branch of Openmoko) git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13613 3c298f89-4303-0410-b956-a3cf2f4a3e73
5900 lines
153 KiB
Diff
5900 lines
153 KiB
Diff
From 8602650d636b32c01fd11337dffc1df310f024e6 Mon Sep 17 00:00:00 2001
|
|
From: SW.LEE <hitchcar@samsung.com>
|
|
Date: Wed, 2 Jul 2008 22:36:46 +0100
|
|
Subject: [PATCH] introduce-samsung-camera-unit-driver.patch
|
|
|
|
This is the kernel side of an old (2004) samsung camera driver for 2440
|
|
It doesn't compile on modern kernel yet, this patch introduces it into the
|
|
kernel tree without gross mods, so it is broken code we can start to work on
|
|
---
|
|
arch/arm/mach-s3c2440/Kconfig | 4 +-
|
|
arch/arm/mach-s3c2440/Makefile | 26 +-
|
|
arch/arm/mach-s3c2440/camera/Kconfig | 7 +
|
|
arch/arm/mach-s3c2440/camera/Makefile | 9 +
|
|
arch/arm/mach-s3c2440/camera/bits.h | 48 ++
|
|
arch/arm/mach-s3c2440/camera/cam_reg.h | 220 ++++++
|
|
arch/arm/mach-s3c2440/camera/camif.c | 978 +++++++++++++++++++++++++++
|
|
arch/arm/mach-s3c2440/camera/camif.h | 304 +++++++++
|
|
arch/arm/mach-s3c2440/camera/camif_fsm.c | 427 ++++++++++++
|
|
arch/arm/mach-s3c2440/camera/imgsensor.c | 255 +++++++
|
|
arch/arm/mach-s3c2440/camera/miscdevice.h | 18 +
|
|
arch/arm/mach-s3c2440/camera/qt-driver.c | 169 +++++
|
|
arch/arm/mach-s3c2440/camera/qt.h | 18 +
|
|
arch/arm/mach-s3c2440/camera/s5x532.h | 143 ++++
|
|
arch/arm/mach-s3c2440/camera/s5x532_rev36.h | 208 ++++++
|
|
arch/arm/mach-s3c2440/camera/sensor.h | 20 +
|
|
arch/arm/mach-s3c2440/camera/sxga.h | 504 ++++++++++++++
|
|
arch/arm/mach-s3c2440/camera/userapp.h | 44 ++
|
|
arch/arm/mach-s3c2440/camera/v4l2_api.c | 311 +++++++++
|
|
arch/arm/mach-s3c2440/camera/video-driver.c | 591 ++++++++++++++++
|
|
arch/arm/mach-s3c2440/camera/videodev.c | 342 ++++++++++
|
|
arch/arm/mach-s3c2440/camera/videodev.h | 110 +++
|
|
arch/arm/mach-s3c2440/camera/videodev2.h | 938 +++++++++++++++++++++++++
|
|
23 files changed, 5668 insertions(+), 26 deletions(-)
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/Kconfig
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/Makefile
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/bits.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/cam_reg.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/camif.c
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/camif.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/camif_fsm.c
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/imgsensor.c
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/miscdevice.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/qt-driver.c
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/qt.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/s5x532.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/s5x532_rev36.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/sensor.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/sxga.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/userapp.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/v4l2_api.c
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/video-driver.c
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/videodev.c
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/videodev.h
|
|
create mode 100644 arch/arm/mach-s3c2440/camera/videodev2.h
|
|
|
|
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
|
|
index c40aaca..c350511 100644
|
|
--- a/arch/arm/mach-s3c2440/Kconfig
|
|
+++ b/arch/arm/mach-s3c2440/Kconfig
|
|
@@ -30,6 +30,9 @@ config S3C2440_C_FIQ
|
|
Support for S3C2440 FIQ support in C -- see
|
|
./arch/arm/macs3c2440/fiq_c_isr.c
|
|
|
|
+source "arch/arm/mach-s3c2440/camera/Kconfig"
|
|
+
|
|
+
|
|
menu "S3C2440 Machines"
|
|
|
|
config MACH_ANUBIS
|
|
@@ -99,4 +102,3 @@ config NEO1973_GTA02_2440
|
|
of the FIC/Openmoko Neo1973 GTA02 GSM Phone.
|
|
|
|
endmenu
|
|
-
|
|
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
|
|
index e3ca9e3..7112231 100644
|
|
--- a/arch/arm/mach-s3c2440/Makefile
|
|
+++ b/arch/arm/mach-s3c2440/Makefile
|
|
@@ -1,26 +1,2 @@
|
|
-# arch/arm/mach-s3c2440/Makefile
|
|
-#
|
|
-# Copyright 2007 Simtec Electronics
|
|
-#
|
|
-# Licensed under GPLv2
|
|
+obj-y += camera/
|
|
|
|
-obj-y :=
|
|
-obj-m :=
|
|
-obj-n :=
|
|
-obj- :=
|
|
-
|
|
-obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o
|
|
-obj-$(CONFIG_CPU_S3C2440) += irq.o
|
|
-obj-$(CONFIG_CPU_S3C2440) += clock.o
|
|
-obj-$(CONFIG_S3C2440_DMA) += dma.o
|
|
-obj-$(CONFIG_S3C2440_C_FIQ) += fiq_c_isr.o
|
|
-
|
|
-# Machine support
|
|
-
|
|
-obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
|
|
-obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
|
|
-obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
|
|
-obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
|
|
-obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
|
|
-obj-$(CONFIG_MACH_HXD8) += mach-hxd8.o
|
|
-obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
|
|
diff --git a/arch/arm/mach-s3c2440/camera/Kconfig b/arch/arm/mach-s3c2440/camera/Kconfig
|
|
new file mode 100644
|
|
index 0000000..36f127d
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/Kconfig
|
|
@@ -0,0 +1,7 @@
|
|
+
|
|
+config S3C2440_CAMERA
|
|
+ bool "S3C24xx Camera interface"
|
|
+ depends on ARCH_S3C2410
|
|
+ help
|
|
+ Camera driver for S3C2440 camera unit
|
|
+
|
|
diff --git a/arch/arm/mach-s3c2440/camera/Makefile b/arch/arm/mach-s3c2440/camera/Makefile
|
|
new file mode 100644
|
|
index 0000000..a46d3be
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/Makefile
|
|
@@ -0,0 +1,9 @@
|
|
+obj-$(CONFIG_S3C2440_CAMERA) += \
|
|
+ videodev.o \
|
|
+ imgsensor.o \
|
|
+ videodrv.o \
|
|
+ video-driver.o \
|
|
+ camif.o \
|
|
+ camif_fsm.o \
|
|
+ qt-driver.o
|
|
+
|
|
diff --git a/arch/arm/mach-s3c2440/camera/bits.h b/arch/arm/mach-s3c2440/camera/bits.h
|
|
new file mode 100644
|
|
index 0000000..8d83c2e
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/bits.h
|
|
@@ -0,0 +1,48 @@
|
|
+/*
|
|
+ * Copyright (C) Samsung Electroincs 2003
|
|
+ * Author: SW.LEE <hitchcar@samsung.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.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef __SW_BITS_H
|
|
+#define __SW_BITS_H
|
|
+
|
|
+#define BIT0 0x00000001
|
|
+#define BIT1 0x00000002
|
|
+#define BIT2 0x00000004
|
|
+#define BIT3 0x00000008
|
|
+#define BIT4 0x00000010
|
|
+#define BIT5 0x00000020
|
|
+#define BIT6 0x00000040
|
|
+#define BIT7 0x00000080
|
|
+#define BIT8 0x00000100
|
|
+#define BIT9 0x00000200
|
|
+#define BIT10 0x00000400
|
|
+#define BIT11 0x00000800
|
|
+#define BIT12 0x00001000
|
|
+#define BIT13 0x00002000
|
|
+#define BIT14 0x00004000
|
|
+#define BIT15 0x00008000
|
|
+#define BIT16 0x00010000
|
|
+#define BIT17 0x00020000
|
|
+#define BIT18 0x00040000
|
|
+#define BIT19 0x00080000
|
|
+#define BIT20 0x00100000
|
|
+#define BIT21 0x00200000
|
|
+#define BIT22 0x00400000
|
|
+#define BIT23 0x00800000
|
|
+#define BIT24 0x01000000
|
|
+#define BIT25 0x02000000
|
|
+#define BIT26 0x04000000
|
|
+#define BIT27 0x08000000
|
|
+#define BIT28 0x10000000
|
|
+#define BIT29 0x20000000
|
|
+#define BIT30 0x40000000
|
|
+#define BIT31 0x80000000
|
|
+
|
|
+#endif
|
|
diff --git a/arch/arm/mach-s3c2440/camera/cam_reg.h b/arch/arm/mach-s3c2440/camera/cam_reg.h
|
|
new file mode 100644
|
|
index 0000000..7247a4e
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/cam_reg.h
|
|
@@ -0,0 +1,220 @@
|
|
+ /*----------------------------------------------------------
|
|
+ * (C) 2004 Samsung Electronics
|
|
+ * SW.LEE < hitchcar@samsung.com>
|
|
+ *
|
|
+ ----------------------------------------------------------- */
|
|
+
|
|
+#ifndef __FIMC20_CAMERA_H__
|
|
+#define __FIMC20_CAMERA_H__
|
|
+
|
|
+
|
|
+#ifdef CONFIG_ARCH_S3C24A0
|
|
+#define CAM_BASE_ADD 0x48000000
|
|
+#else /* S3C2440A */
|
|
+#define CAM_BASE_ADD 0x4F000000
|
|
+#endif
|
|
+
|
|
+
|
|
+/*
|
|
+ * CAMERA IP
|
|
+ * P-port is used as RGB Capturing device which including scale and crop
|
|
+ * those who want to see(preview ) the image on display needs RGB image.
|
|
+ *
|
|
+ * C-port is used as YCbCr(4:2:0, 4:2:2) Capturing device which including the scale and crop
|
|
+ * the prefix of C-port have the meaning of "Codec" ex. mpeg4, h263.. which requries the
|
|
+ YCBCB format not RGB
|
|
+ */
|
|
+
|
|
+#define CISRCFMT __REG(CAM_BASE_ADD+0x00) // RW Input Source Format
|
|
+#define CIWDOFST __REG(CAM_BASE_ADD+0x04) // Window offset register
|
|
+#define CIGCTRL __REG(CAM_BASE_ADD+0x08) // Global control register
|
|
+#define CICOYSA0 __REG(CAM_BASE_ADD+0x18) // Y 1 st frame start address
|
|
+#define CICOYSA1 __REG(CAM_BASE_ADD+0x1C) // Y 2 nd frame start address
|
|
+#define CICOYSA2 __REG(CAM_BASE_ADD+0x20) // Y 3 rd frame start address
|
|
+#define CICOYSA3 __REG(CAM_BASE_ADD+0x24) // Y 4 th frame start address
|
|
+#define CICOCBSA0 __REG(CAM_BASE_ADD+0x28) // Cb 1 st frame start address
|
|
+#define CICOCBSA1 __REG(CAM_BASE_ADD+0x2C) // Cb 2 nd frame start address
|
|
+#define CICOCBSA2 __REG(CAM_BASE_ADD+0x30) // Cb 3 rd frame start address
|
|
+#define CICOCBSA3 __REG(CAM_BASE_ADD+0x34) // Cb 4 th frame start address
|
|
+#define CICOCRSA0 __REG(CAM_BASE_ADD+0x38) // Cr 1 st frame start address
|
|
+#define CICOCRSA1 __REG(CAM_BASE_ADD+0x3C) // Cr 2 nd frame start address
|
|
+#define CICOCRSA2 __REG(CAM_BASE_ADD+0x40) // Cr 3 rd frame start address
|
|
+#define CICOCRSA3 __REG(CAM_BASE_ADD+0x44) // Cr 4 th frame start address
|
|
+#define CICOTRGFMT __REG(CAM_BASE_ADD+0x48) // Target image format of codec
|
|
+#define CICOCTRL __REG(CAM_BASE_ADD+0x4C) // Codec DMA control related
|
|
+#define CICOSCPRERATIO __REG(CAM_BASE_ADD+0x50) // Codec pre-scaler ratio control
|
|
+#define CICOSCPREDST __REG(CAM_BASE_ADD+0x54) // Codec pre-scaler destination
|
|
+#define CICOSCCTRL __REG(CAM_BASE_ADD+0x58) // Codec main-scaler control
|
|
+#define CICOTAREA __REG(CAM_BASE_ADD+0x5C) // Codec pre-scaler destination
|
|
+#define CICOSTATUS __REG(CAM_BASE_ADD+0x64) // Codec path status
|
|
+#define CIPRCLRSA0 __REG(CAM_BASE_ADD+0x6C) // RGB 1 st frame start address
|
|
+#define CIPRCLRSA1 __REG(CAM_BASE_ADD+0x70) // RGB 2 nd frame start address
|
|
+#define CIPRCLRSA2 __REG(CAM_BASE_ADD+0x74) // RGB 3 rd frame start address
|
|
+#define CIPRCLRSA3 __REG(CAM_BASE_ADD+0x78) // RGB 4 th frame start address
|
|
+#define CIPRTRGFMT __REG(CAM_BASE_ADD+0x7C) // Target image format of preview
|
|
+#define CIPRCTRL __REG(CAM_BASE_ADD+0x80) // Preview DMA control related
|
|
+#define CIPRSCPRERATIO __REG(CAM_BASE_ADD+0x84) // Preview pre-scaler ratio control
|
|
+#define CIPRSCPREDST __REG(CAM_BASE_ADD+0x88) // Preview pre-scaler destination
|
|
+#define CIPRSCCTRL __REG(CAM_BASE_ADD+0x8C) // Preview main-scaler control
|
|
+#define CIPRTAREA __REG(CAM_BASE_ADD+0x90) // Preview pre-scaler destination
|
|
+#define CIPRSTATUS __REG(CAM_BASE_ADD+0x98) // Preview path status
|
|
+#define CIIMGCPT __REG(CAM_BASE_ADD+0xA0) // Image capture enable command
|
|
+
|
|
+#define CICOYSA(__x) __REG(CAM_BASE_ADD+0x18 + (__x)*4 )
|
|
+#define CICOCBSA(__x) __REG(CAM_BASE_ADD+0x28 + (__x)*4 )
|
|
+#define CICOCRSA(__x) __REG(CAM_BASE_ADD+0x38 + (__x)*4 )
|
|
+#define CIPRCLRSA(__x) __REG(CAM_BASE_ADD+0x6C + (__x)*4 )
|
|
+
|
|
+/* CISRCFMT BitField */
|
|
+#define SRCFMT_ITU601 BIT31
|
|
+#define SRCFMT_ITU656 0
|
|
+#define SRCFMT_UVOFFSET_128 BIT30
|
|
+#define fCAM_SIZE_H Fld(13, 16)
|
|
+#define fCAM_SIZE_V Fld(13, 0)
|
|
+#define SOURCE_HSIZE(x) FInsrt((x), fCAM_SIZE_H)
|
|
+#define SOURCE_VSIZE(x) FInsrt((x), fCAM_SIZE_V)
|
|
+
|
|
+
|
|
+/* Window Option Register */
|
|
+#define WINOFEN BIT31
|
|
+#define CO_FIFO_Y BIT30
|
|
+#define CO_FIFO_CB BIT15
|
|
+#define CO_FIFO_CR BIT14
|
|
+#define PR_FIFO_CB BIT13
|
|
+#define PR_FIFO_CR BIT12
|
|
+#define fWINHOR Fld(11, 16)
|
|
+#define fWINVER Fld(11, 0)
|
|
+#define WINHOROFST(x) FInsrt((x), fWINHOR)
|
|
+#define WINVEROFST(x) FInsrt((x), fWINVER)
|
|
+
|
|
+/* Global Control Register */
|
|
+#define GC_SWRST BIT31
|
|
+#define GC_CAMRST BIT30
|
|
+#define GC_INVPOLPCLK BIT26
|
|
+#define GC_INVPOLVSYNC BIT25
|
|
+#define GC_INVPOLHREF BIT24
|
|
+
|
|
+/*--------------------------------------------------
|
|
+ REGISTER BIT FIELD DEFINITION TO
|
|
+ YCBCR and RGB
|
|
+----------------------------------------------------*/
|
|
+/* Codec Target Format Register */
|
|
+#define IN_YCBCR420 0
|
|
+#define IN_YCBCR422 BIT31
|
|
+#define OUT_YCBCR420 0
|
|
+#define OUT_YCBCR422 BIT30
|
|
+
|
|
+#if 0
|
|
+#define FLIP_NORMAL 0
|
|
+#define FLIP_X (BIT14)
|
|
+#define FLIP_Y (BIT15)
|
|
+#define FLIP_MIRROR (BIT14|BIT15)
|
|
+#endif
|
|
+
|
|
+/** BEGIN ************************************/
|
|
+/* Cotents: Common in both P and C port */
|
|
+#define fTARGET_HSIZE Fld(13,16)
|
|
+#define TARGET_HSIZE(x) FInsrt((x), fTARGET_HSIZE)
|
|
+#define fTARGET_VSIZE Fld(13,0)
|
|
+#define TARGET_VSIZE(x) FInsrt((x), fTARGET_VSIZE)
|
|
+#define FLIP_X_MIRROR BIT14
|
|
+#define FLIP_Y_MIRROR BIT15
|
|
+#define FLIP_180_MIRROR (BIT14 | BIT15)
|
|
+/** END *************************************/
|
|
+
|
|
+/* Codec DMA Control Register */
|
|
+#define fYBURST_M Fld(5,19)
|
|
+#define fYBURST_R Fld(5,14)
|
|
+#define fCBURST_M Fld(5,9)
|
|
+#define fCBURST_R Fld(5,4)
|
|
+#define YBURST_M(x) FInsrt((x), fYBURST_M)
|
|
+#define CBURST_M(x) FInsrt((x), fCBURST_M)
|
|
+#define YBURST_R(x) FInsrt((x), fYBURST_R)
|
|
+#define CBURST_R(x) FInsrt((x), fCBURST_R)
|
|
+#define LAST_IRQ_EN BIT2 /* Common in both P and C port */
|
|
+/*
|
|
+ * Check the done signal of capturing image for JPEG
|
|
+ * !!! AutoClear Bit
|
|
+ */
|
|
+
|
|
+
|
|
+/* (Codec, Preview ) Pre-Scaler Control Register 1 */
|
|
+#define fSHIFT Fld(4,28)
|
|
+#define PRE_SHIFT(x) FInsrt((x), fSHIFT)
|
|
+#define fRATIO_H Fld(7,16)
|
|
+#define PRE_HRATIO(x) FInsrt((x), fRATIO_H)
|
|
+#define fRATIO_V Fld(7,0)
|
|
+#define PRE_VRATIO(x) FInsrt((x), fRATIO_V)
|
|
+
|
|
+/* (Codec, Preview ) Pre-Scaler Control Register 2*/
|
|
+#define fDST_WIDTH Fld(12,16)
|
|
+#define fDST_HEIGHT Fld(12,0)
|
|
+#define PRE_DST_WIDTH(x) FInsrt((x), fDST_WIDTH)
|
|
+#define PRE_DST_HEIGHT(x) FInsrt((x), fDST_HEIGHT)
|
|
+
|
|
+
|
|
+/* (Codec, Preview) Main-scaler control Register */
|
|
+#define S_METHOD BIT31 /* Sampling method only for P-port */
|
|
+#define SCALERSTART BIT15
|
|
+/* Codec scaler bypass for upper 2048x2048
|
|
+ where ImgCptEn_CoSC and ImgCptEn_PrSC should be 0
|
|
+*/
|
|
+
|
|
+#define SCALERBYPASS BIT31
|
|
+#define RGB_FMT24 BIT30
|
|
+#define RGB_FMT16 0
|
|
+
|
|
+/*
|
|
+#define SCALE_UP_H BIT29
|
|
+#define SCALE_UP_V BIT28
|
|
+*/
|
|
+
|
|
+#define fMAIN_HRATIO Fld(9, 16)
|
|
+#define MAIN_HRATIO(x) FInsrt((x), fMAIN_HRATIO)
|
|
+
|
|
+#define SCALER_START BIT15
|
|
+
|
|
+#define fMAIN_VRATIO Fld(9, 0)
|
|
+#define MAIN_VRATIO(x) FInsrt((x), fMAIN_VRATIO)
|
|
+
|
|
+/* (Codec, Preview ) DMA Target AREA Register */
|
|
+#define fCICOTAREA Fld(26,0)
|
|
+#define TARGET_DMA_AREA(x) FInsrt((x), fCICOTAREA)
|
|
+
|
|
+/* Preview DMA Control Register */
|
|
+#define fRGBURST_M Fld(5,19)
|
|
+#define fRGBURST_R Fld(5,14)
|
|
+#define RGBURST_M(x) FInsrt((x), fRGBURST_M)
|
|
+#define RGBURST_R(x) FInsrt((x), fRGBURST_R)
|
|
+
|
|
+
|
|
+/* (Codec, Preview) Status Register */
|
|
+#define CO_OVERFLOW_Y BIT31
|
|
+#define CO_OVERFLOW_CB BIT30
|
|
+#define CO_OVERFLOW_CR BIT29
|
|
+#define PR_OVERFLOW_CB BIT31
|
|
+#define PR_OVERFLOW_CR BIT30
|
|
+
|
|
+#define VSYNC BIT28
|
|
+
|
|
+#define fFRAME_CNT Fld(2,26)
|
|
+#define FRAME_CNT(x) FExtr((x),fFRAME_CNT)
|
|
+
|
|
+#define WIN_OFF_EN BIT25
|
|
+#define fFLIP_MODE Fld(2,23)
|
|
+#define FLIP_MODE(x) EExtr((x), fFLIP_MODE)
|
|
+#define CAP_STATUS_CAMIF BIT22
|
|
+#define CAP_STATUS_CODEC BIT21
|
|
+#define CAP_STATUS_PREVIEW BIT21
|
|
+#define VSYNC_A BIT20
|
|
+#define VSYNC_B BIT19
|
|
+
|
|
+/* Image Capture Enable Regiser */
|
|
+#define CAMIF_CAP_ON BIT31
|
|
+#define CAMIF_CAP_CODEC_ON BIT30
|
|
+#define CAMIF_CAP_PREVIEW_ON BIT29
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+#endif /* S3C2440_CAMER_H */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/camif.c b/arch/arm/mach-s3c2440/camera/camif.c
|
|
new file mode 100644
|
|
index 0000000..36d4ccc
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/camif.c
|
|
@@ -0,0 +1,978 @@
|
|
+/*
|
|
+ * Copyright (C) 2004 Samsung Electronics
|
|
+ * SW.LEE <hitchcar@samsung.com>
|
|
+ *
|
|
+ * This file is subject to the terms and conditions of the GNU General Public
|
|
+ * License 2. See the file COPYING in the main directory of this archive
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+#include <linux/config.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/irq.h>
|
|
+#include <linux/tqueue.h>
|
|
+#include <linux/locks.h>
|
|
+#include <linux/completion.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/vmalloc.h>
|
|
+#include <linux/miscdevice.h>
|
|
+#include <linux/wait.h>
|
|
+#include <linux/miscdevice.h>
|
|
+#include <asm/io.h>
|
|
+#include <asm/semaphore.h>
|
|
+#include <asm/hardware.h>
|
|
+#include <asm/uaccess.h>
|
|
+
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+#include <asm/arch/S3C24A0.h>
|
|
+#include <asm/arch/clocks.h>
|
|
+#else
|
|
+#include <asm/arch/S3C2440.h>
|
|
+#include <asm/arch/clocks.h>
|
|
+#endif
|
|
+
|
|
+#include "cam_reg.h"
|
|
+//#define SW_DEBUG
|
|
+#include "camif.h"
|
|
+#include "videodev.h"
|
|
+#include "miscdevice.h"
|
|
+
|
|
+
|
|
+static int camif_dma_burst(camif_cfg_t *);
|
|
+static int camif_scaler(camif_cfg_t *);
|
|
+
|
|
+static const char *camif_version =
|
|
+ "$Id: camif.c,v 1.10 2004/06/04 04:24:14 swlee Exp $";
|
|
+
|
|
+/* For SXGA Image */
|
|
+#define RESERVE_MEM 15*1024*1024
|
|
+#define YUV_MEM 10*1024*1024
|
|
+#define RGB_MEM (RESERVE_MEM - YUV_MEM)
|
|
+
|
|
+static int camif_malloc(camif_cfg_t *cfg)
|
|
+{
|
|
+ unsigned int t_size;
|
|
+ unsigned int daon = cfg->target_x *cfg->target_y;
|
|
+
|
|
+ if(cfg->dma_type & CAMIF_CODEC) {
|
|
+ if (cfg->fmt & CAMIF_OUT_YCBCR420) {
|
|
+ t_size = daon * 3 / 2 ;
|
|
+ }
|
|
+ else { t_size = daon * 2; /* CAMIF_OUT_YCBCR422 */ }
|
|
+ t_size = t_size *cfg->pp_num;
|
|
+
|
|
+#ifndef SAMSUNG_SXGA_CAM
|
|
+ cfg->pp_virt_buf = consistent_alloc(GFP_KERNEL, t_size, &cfg->pp_phys_buf);
|
|
+#else
|
|
+ printk(KERN_INFO "Reserving High RAM Addresses \n");
|
|
+ cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM);
|
|
+ cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,YUV_MEM);
|
|
+#endif
|
|
+
|
|
+ if ( !cfg->pp_virt_buf ) {
|
|
+ printk(KERN_ERR"CAMERA:Failed to request YCBCR MEM\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ memset(cfg->pp_virt_buf, 0, t_size);
|
|
+ cfg->pp_totalsize = t_size;
|
|
+ return 0;
|
|
+ }
|
|
+ if ( cfg->dma_type & CAMIF_PREVIEW ) {
|
|
+ if (cfg->fmt & CAMIF_RGB16)
|
|
+ t_size = daon * 2; /* 4byte per two pixel*/
|
|
+ else {
|
|
+ assert(cfg->fmt & CAMIF_RGB24);
|
|
+ t_size = daon * 4; /* 4byte per one pixel */
|
|
+ }
|
|
+ t_size = t_size * cfg->pp_num;
|
|
+#ifndef SAMSUNG_SXGA_CAM
|
|
+ cfg->pp_virt_buf = consistent_alloc(GFP_KERNEL, t_size, &cfg->pp_phys_buf);
|
|
+#else
|
|
+ printk(KERN_INFO "Reserving High RAM Addresses \n");
|
|
+ cfg->pp_phys_buf = PHYS_OFFSET + (MEM_SIZE - RESERVE_MEM ) + YUV_MEM;
|
|
+ cfg->pp_virt_buf = ioremap_nocache(cfg->pp_phys_buf,RGB_MEM);
|
|
+#endif
|
|
+ if ( !cfg->pp_virt_buf ) {
|
|
+ printk(KERN_ERR"CAMERA:Failed to request RGB MEM\n");
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ memset(cfg->pp_virt_buf, 0, t_size);
|
|
+ cfg->pp_totalsize = t_size;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 0; /* Never come. */
|
|
+}
|
|
+
|
|
+static int camif_demalloc(camif_cfg_t *cfg)
|
|
+{
|
|
+#ifndef SAMSUNG_SXGA_CAM
|
|
+ if ( cfg->pp_virt_buf ) {
|
|
+ consistent_free(cfg->pp_virt_buf,cfg->pp_totalsize,cfg->pp_phys_buf);
|
|
+ cfg->pp_virt_buf = 0;
|
|
+ }
|
|
+#else
|
|
+ iounmap(cfg->pp_virt_buf);
|
|
+ cfg->pp_virt_buf = 0;
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * advise a person to use this func in ISR
|
|
+ * index value indicates the next frame count to be used
|
|
+ */
|
|
+int camif_g_frame_num(camif_cfg_t *cfg)
|
|
+{
|
|
+ int index = 0;
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_CODEC ) {
|
|
+ index = FRAME_CNT(CICOSTATUS);
|
|
+ DPRINTK("CAMIF_CODEC frame %d \n", index);
|
|
+ }
|
|
+ else {
|
|
+ assert(cfg->dma_type & CAMIF_PREVIEW );
|
|
+ index = FRAME_CNT(CIPRSTATUS);
|
|
+ DPRINTK("CAMIF_PREVIEW frame %d 0x%08X \n", index, CIPRSTATUS);
|
|
+ }
|
|
+ cfg->now_frame_num = (index + 2) % 4; /* When 4 PingPong */
|
|
+ return index; /* meaningless */
|
|
+}
|
|
+
|
|
+static int camif_pp_codec(camif_cfg_t *cfg)
|
|
+{
|
|
+ u32 i, c_size; /* Cb,Cr size */
|
|
+ u32 one_p_size;
|
|
+ u32 daon = cfg->target_x * cfg->target_y;
|
|
+ if (cfg->fmt & CAMIF_OUT_YCBCR420) {
|
|
+ c_size = daon /4;
|
|
+ }
|
|
+ else {
|
|
+ assert(cfg->fmt & CAMIF_OUT_YCBCR422);
|
|
+ c_size = daon /2;
|
|
+ }
|
|
+ switch ( cfg->pp_num ) {
|
|
+ case 1 :
|
|
+ for ( i =0 ; i < 4; i=i+1) {
|
|
+ cfg->img_buf[i].virt_y = cfg->pp_virt_buf;
|
|
+ cfg->img_buf[i].phys_y = cfg->pp_phys_buf;
|
|
+ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon;
|
|
+ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon;
|
|
+ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size;
|
|
+ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size;
|
|
+ CICOYSA(i) = cfg->img_buf[i].phys_y;
|
|
+ CICOCBSA(i) = cfg->img_buf[i].phys_cb;
|
|
+ CICOCRSA(i) = cfg->img_buf[i].phys_cr;
|
|
+ }
|
|
+ break;
|
|
+ case 2:
|
|
+#define TRY (( i%2 ) ? 1 :0)
|
|
+ one_p_size = daon + 2*c_size;
|
|
+ for (i = 0; i < 4 ; i++) {
|
|
+ cfg->img_buf[i].virt_y = cfg->pp_virt_buf + TRY * one_p_size;
|
|
+ cfg->img_buf[i].phys_y = cfg->pp_phys_buf + TRY * one_p_size;
|
|
+ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon + TRY * one_p_size;
|
|
+ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon + TRY * one_p_size;
|
|
+ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size + TRY * one_p_size;
|
|
+ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size + TRY * one_p_size;
|
|
+ CICOYSA(i) = cfg->img_buf[i].phys_y;
|
|
+ CICOCBSA(i) = cfg->img_buf[i].phys_cb;
|
|
+ CICOCRSA(i) = cfg->img_buf[i].phys_cr;
|
|
+ }
|
|
+ break;
|
|
+ case 4:
|
|
+ one_p_size = daon + 2*c_size;
|
|
+ for (i = 0; i < 4 ; i++) {
|
|
+ cfg->img_buf[i].virt_y = cfg->pp_virt_buf + i * one_p_size;
|
|
+ cfg->img_buf[i].phys_y = cfg->pp_phys_buf + i * one_p_size;
|
|
+ cfg->img_buf[i].virt_cb = cfg->pp_virt_buf + daon + i * one_p_size;
|
|
+ cfg->img_buf[i].phys_cb = cfg->pp_phys_buf + daon + i * one_p_size;
|
|
+ cfg->img_buf[i].virt_cr = cfg->pp_virt_buf + daon + c_size + i * one_p_size;
|
|
+ cfg->img_buf[i].phys_cr = cfg->pp_phys_buf + daon + c_size + i * one_p_size;
|
|
+ CICOYSA(i) = cfg->img_buf[i].phys_y;
|
|
+ CICOCBSA(i) = cfg->img_buf[i].phys_cb;
|
|
+ CICOCRSA(i) = cfg->img_buf[i].phys_cr;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ printk("Invalid PingPong Number %d \n",cfg->pp_num);
|
|
+ panic("halt\n");
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* RGB Buffer Allocation */
|
|
+static int camif_pp_preview(camif_cfg_t *cfg)
|
|
+{
|
|
+ int i;
|
|
+ u32 daon = cfg->target_x * cfg->target_y;
|
|
+
|
|
+ if(cfg->fmt & CAMIF_RGB24)
|
|
+ daon = daon * 4 ;
|
|
+ else {
|
|
+ assert (cfg->fmt & CAMIF_RGB16);
|
|
+ daon = daon *2;
|
|
+ }
|
|
+ switch ( cfg->pp_num ) {
|
|
+ case 1:
|
|
+ for ( i = 0; i < 4 ; i++ ) {
|
|
+ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf ;
|
|
+ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf ;
|
|
+ CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
|
|
+ }
|
|
+ break;
|
|
+ case 2:
|
|
+ for ( i = 0; i < 4 ; i++) {
|
|
+ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + TRY * daon;
|
|
+ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + TRY * daon;
|
|
+ CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
|
|
+ }
|
|
+ break;
|
|
+ case 4:
|
|
+ for ( i = 0; i < 4 ; i++) {
|
|
+ cfg->img_buf[i].virt_rgb = cfg->pp_virt_buf + i * daon;
|
|
+ cfg->img_buf[i].phys_rgb = cfg->pp_phys_buf + i * daon;
|
|
+ CIPRCLRSA(i) = cfg->img_buf[i].phys_rgb;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ printk("Invalid PingPong Number %d \n",cfg->pp_num);
|
|
+ panic("halt\n");
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int camif_pingpong(camif_cfg_t *cfg)
|
|
+{
|
|
+ if (cfg->dma_type & CAMIF_CODEC ) {
|
|
+ camif_pp_codec(cfg);
|
|
+ }
|
|
+
|
|
+ if ( cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ camif_pp_preview(cfg);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/*********** Image Convert *******************************/
|
|
+/* Return Format
|
|
+ * Supported by Hardware
|
|
+ * V4L2_PIX_FMT_YUV420,
|
|
+ * V4L2_PIX_FMT_YUV422P,
|
|
+ * V4L2_PIX_FMT_BGR32 (BGR4)
|
|
+ * -----------------------------------
|
|
+ * V4L2_PIX_FMT_RGB565(X)
|
|
+ * Currenly 2byte --> BGR656 Format
|
|
+ * S3C2440A,S3C24A0 supports vairants with reversed FMT_RGB565
|
|
+ i.e blue toward the least, red towards the most significant bit
|
|
+ -- by SW.LEE
|
|
+ */
|
|
+
|
|
+
|
|
+/*
|
|
+ * After calling camif_g_frame_num,
|
|
+ * this func must be called
|
|
+ */
|
|
+u8 * camif_g_frame(camif_cfg_t *cfg)
|
|
+{
|
|
+ u8 * ret = NULL;
|
|
+ int cnt = cfg->now_frame_num;
|
|
+
|
|
+ if(cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ ret = cfg->img_buf[cnt].virt_rgb;
|
|
+ }
|
|
+ if (cfg->dma_type & CAMIF_CODEC) {
|
|
+ ret = cfg->img_buf[cnt].virt_y;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* This function must be called in module initial time */
|
|
+static int camif_source_fmt(camif_gc_t *gc)
|
|
+{
|
|
+ u32 cmd = 0;
|
|
+
|
|
+ /* Configure CISRCFMT --Source Format */
|
|
+ if (gc->itu_fmt & CAMIF_ITU601) {
|
|
+ cmd = CAMIF_ITU601;
|
|
+ }
|
|
+ else {
|
|
+ assert ( gc->itu_fmt & CAMIF_ITU656);
|
|
+ cmd = CAMIF_ITU656;
|
|
+ }
|
|
+ cmd |= SOURCE_HSIZE(gc->source_x)| SOURCE_VSIZE(gc->source_y);
|
|
+ /* Order422 */
|
|
+ cmd |= gc->order422;
|
|
+ CISRCFMT = cmd;
|
|
+
|
|
+ return 0 ;
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * Codec Input YCBCR422 will be Fixed
|
|
+ */
|
|
+static int camif_target_fmt(camif_cfg_t *cfg)
|
|
+{
|
|
+ u32 cmd = 0;
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_CODEC) {
|
|
+ /* YCBCR setting */
|
|
+ cmd = TARGET_HSIZE(cfg->target_x)| TARGET_VSIZE(cfg->target_y);
|
|
+ if ( cfg->fmt & CAMIF_OUT_YCBCR420 ) {
|
|
+ cmd |= OUT_YCBCR420|IN_YCBCR422;
|
|
+ }
|
|
+ else {
|
|
+ assert(cfg->fmt & CAMIF_OUT_YCBCR422);
|
|
+ cmd |= OUT_YCBCR422|IN_YCBCR422;
|
|
+ }
|
|
+ CICOTRGFMT = cmd | cfg->flip;
|
|
+ }
|
|
+ else {
|
|
+ assert(cfg->dma_type & CAMIF_PREVIEW);
|
|
+ CIPRTRGFMT =
|
|
+ TARGET_HSIZE(cfg->target_x)|TARGET_VSIZE(cfg->target_y)|cfg->flip;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void camif_change_flip(camif_cfg_t *cfg)
|
|
+{
|
|
+ u32 cmd = 0;
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_CODEC ) {
|
|
+ /* YCBCR setting */
|
|
+ cmd = CICOTRGFMT;
|
|
+ cmd &= ~(BIT14|BIT15); /* Clear FLIP Mode */
|
|
+ cmd |= cfg->flip;
|
|
+ CICOTRGFMT = cmd;
|
|
+ }
|
|
+ else {
|
|
+ cmd = CIPRTRGFMT;
|
|
+ cmd &= ~(BIT14|BIT15);
|
|
+ cmd |= cfg->flip;
|
|
+ CICOTRGFMT = cmd;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+/* Must:
|
|
+ * Before calling this function,
|
|
+ * you must use "camif_dynamic_open"
|
|
+ * If you want to enable both CODEC and preview
|
|
+ * you must do it at the same time.
|
|
+ */
|
|
+int camif_capture_start(camif_cfg_t *cfg)
|
|
+{
|
|
+ u32 n_cmd = 0; /* Next Command */
|
|
+
|
|
+ switch(cfg->exec) {
|
|
+ case CAMIF_BOTH_DMA_ON:
|
|
+ camif_reset(CAMIF_RESET,0); /* Flush Camera Core Buffer */
|
|
+ CIPRSCCTRL |= SCALERSTART;
|
|
+ CICOSCCTRL |= SCALERSTART;
|
|
+ n_cmd = CAMIF_CAP_PREVIEW_ON|CAMIF_CAP_CODEC_ON;
|
|
+ break;
|
|
+ case CAMIF_DMA_ON:
|
|
+ camif_reset(CAMIF_RESET,0); /* Flush Camera Core Buffer */
|
|
+ if (cfg->dma_type&CAMIF_CODEC) {
|
|
+ CICOSCCTRL |= SCALERSTART;
|
|
+ n_cmd = CAMIF_CAP_CODEC_ON;
|
|
+ }else {
|
|
+ CIPRSCCTRL |= SCALERSTART;
|
|
+ n_cmd = CAMIF_CAP_PREVIEW_ON;
|
|
+ }
|
|
+
|
|
+ /* wait until Sync Time expires */
|
|
+ /* First settting, to wait VSYNC fall */
|
|
+ /* By VESA spec,in 640x480 @60Hz
|
|
+ MAX Delay Time is around 64us which "while" has.*/
|
|
+ while(VSYNC & CICOSTATUS);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ CIIMGCPT = n_cmd|CAMIF_CAP_ON;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int camif_capture_stop(camif_cfg_t *cfg)
|
|
+{
|
|
+ u32 n_cmd = CIIMGCPT; /* Next Command */
|
|
+
|
|
+ switch(cfg->exec) {
|
|
+ case CAMIF_BOTH_DMA_OFF:
|
|
+ CIPRSCCTRL &= ~SCALERSTART;
|
|
+ CICOSCCTRL &= ~SCALERSTART;
|
|
+ n_cmd = 0;
|
|
+ break;
|
|
+ case CAMIF_DMA_OFF_L_IRQ: /* fall thru */
|
|
+ case CAMIF_DMA_OFF:
|
|
+ if (cfg->dma_type&CAMIF_CODEC) {
|
|
+ CICOSCCTRL &= ~SCALERSTART;
|
|
+ n_cmd &= ~CAMIF_CAP_CODEC_ON;
|
|
+ if (!(n_cmd & CAMIF_CAP_PREVIEW_ON))
|
|
+ n_cmd = 0;
|
|
+ }else {
|
|
+ CIPRSCCTRL &= ~SCALERSTART;
|
|
+ n_cmd &= ~CAMIF_CAP_PREVIEW_ON;
|
|
+ if (!(n_cmd & CAMIF_CAP_CODEC_ON))
|
|
+ n_cmd = 0;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ panic("Unexpected \n");
|
|
+ }
|
|
+ CIIMGCPT = n_cmd;
|
|
+ if(cfg->exec == CAMIF_DMA_OFF_L_IRQ) { /* Last IRQ */
|
|
+ if (cfg->dma_type & CAMIF_CODEC)
|
|
+ CICOCTRL |= LAST_IRQ_EN;
|
|
+ else
|
|
+ CIPRCTRL |= LAST_IRQ_EN;
|
|
+ }
|
|
+#if 0
|
|
+ else { /* to make internal state machine of CAMERA stop */
|
|
+ camif_reset(CAMIF_RESET, 0);
|
|
+ }
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/* LastIRQEn is autoclear */
|
|
+void camif_last_irq_en(camif_cfg_t *cfg)
|
|
+{
|
|
+ if(cfg->exec == CAMIF_BOTH_DMA_ON) {
|
|
+ CIPRCTRL |= LAST_IRQ_EN;
|
|
+ CICOCTRL |= LAST_IRQ_EN;
|
|
+ }
|
|
+ else {
|
|
+ if (cfg->dma_type & CAMIF_CODEC)
|
|
+ CICOCTRL |= LAST_IRQ_EN;
|
|
+ else
|
|
+ CIPRCTRL |= LAST_IRQ_EN;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int
|
|
+camif_scaler_internal(u32 srcWidth, u32 dstWidth, u32 *ratio, u32 *shift)
|
|
+{
|
|
+ if(srcWidth>=64*dstWidth){
|
|
+ printk(KERN_ERR"CAMERA:out of prescaler range: srcWidth /dstWidth = %d(< 64)\n",
|
|
+ srcWidth/dstWidth);
|
|
+ return 1;
|
|
+ }
|
|
+ else if(srcWidth>=32*dstWidth){
|
|
+ *ratio=32;
|
|
+ *shift=5;
|
|
+ }
|
|
+ else if(srcWidth>=16*dstWidth){
|
|
+ *ratio=16;
|
|
+ *shift=4;
|
|
+ }
|
|
+ else if(srcWidth>=8*dstWidth){
|
|
+ *ratio=8;
|
|
+ *shift=3;
|
|
+ }
|
|
+ else if(srcWidth>=4*dstWidth){
|
|
+ *ratio=4;
|
|
+ *shift=2;
|
|
+ }
|
|
+ else if(srcWidth>=2*dstWidth){
|
|
+ *ratio=2;
|
|
+ *shift=1;
|
|
+ }
|
|
+ else {
|
|
+ *ratio=1;
|
|
+ *shift=0;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int camif_g_fifo_status(camif_cfg_t *cfg)
|
|
+{
|
|
+ u32 reg;
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_CODEC) {
|
|
+ u32 flag = CO_OVERFLOW_Y|CO_OVERFLOW_CB|CO_OVERFLOW_CR;
|
|
+ reg = CICOSTATUS;
|
|
+ if (reg & flag) {
|
|
+ printk("CODEC: FIFO error(0x%08x) and corrected\n",reg);
|
|
+ /* FIFO Error Count ++ */
|
|
+ CIWDOFST |= CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR;
|
|
+ CIWDOFST &= ~(CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR);
|
|
+ return 1; /* Error */
|
|
+ }
|
|
+ }
|
|
+ if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ u32 flag = PR_OVERFLOW_CB|PR_OVERFLOW_CR;
|
|
+ reg = CIPRSTATUS;
|
|
+ if (reg & flag) {
|
|
+ printk("PREVIEW:FIFO error(0x%08x) and corrected\n",reg);
|
|
+ CIWDOFST |= PR_FIFO_CB|PR_FIFO_CR;
|
|
+ CIWDOFST &= ~(CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR);
|
|
+ /* FIFO Error Count ++ */
|
|
+ return 1; /* Error */
|
|
+ }
|
|
+ }
|
|
+ return 0; /* No Error */
|
|
+}
|
|
+
|
|
+
|
|
+/* Policy:
|
|
+ * if codec or preview define the win offset,
|
|
+ * other must follow that value.
|
|
+ */
|
|
+int camif_win_offset(camif_gc_t *gc )
|
|
+{
|
|
+ u32 h = gc->win_hor_ofst;
|
|
+ u32 v = gc->win_ver_ofst;
|
|
+
|
|
+ /*Clear Overflow */
|
|
+ CIWDOFST = CO_FIFO_Y|CO_FIFO_CB|CO_FIFO_CR|PR_FIFO_CB|PR_FIFO_CB;
|
|
+ CIWDOFST = 0; /* ? Dummy */
|
|
+ if (!h && !v) {
|
|
+ CIWDOFST = 0;
|
|
+ return 0;
|
|
+ }
|
|
+ CIWDOFST = WINOFEN | WINHOROFST(h) | WINVEROFST(v);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * when you change the resolution in a specific camera,
|
|
+ * sometimes, it is necessary to change the polarity
|
|
+ * -- SW.LEE
|
|
+ */
|
|
+static void camif_polarity(camif_gc_t *gc)
|
|
+{
|
|
+ u32 cmd = CIGCTRL;
|
|
+
|
|
+ cmd = cmd & ~(BIT26|BIT25|BIT24); /* clear polarity */
|
|
+ if (gc->polarity_pclk)
|
|
+ cmd |= GC_INVPOLPCLK;
|
|
+ if (gc->polarity_vsync)
|
|
+ cmd |= GC_INVPOLVSYNC;
|
|
+ if (gc->polarity_href)
|
|
+ cmd |= GC_INVPOLHREF;
|
|
+ CIGCTRL |= cmd;
|
|
+}
|
|
+
|
|
+
|
|
+int camif_dynamic_open(camif_cfg_t *cfg)
|
|
+{
|
|
+ camif_win_offset(cfg->gc);
|
|
+ camif_polarity(cfg->gc);
|
|
+
|
|
+ if(camif_scaler(cfg)) {
|
|
+ printk(KERN_ERR "CAMERA:Preview Scaler, Change WinHorOfset or Target Size\n");
|
|
+ return 1;
|
|
+ }
|
|
+ camif_target_fmt(cfg);
|
|
+ if (camif_dma_burst(cfg)) {
|
|
+ printk(KERN_ERR "CAMERA:DMA Busrt Length Error \n");
|
|
+ return 1;
|
|
+ }
|
|
+ if(camif_malloc(cfg) ) {
|
|
+ printk(KERN_ERR " Instead of using consistent_alloc()\n"
|
|
+ " lease use dedicated memory allocation for DMA memory\n");
|
|
+ return -1;
|
|
+ }
|
|
+ camif_pingpong(cfg);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int camif_dynamic_close(camif_cfg_t *cfg)
|
|
+{
|
|
+ camif_demalloc(cfg);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int camif_target_area(camif_cfg_t *cfg)
|
|
+{
|
|
+ u32 rect = cfg->target_x * cfg->target_y;
|
|
+ if (cfg->dma_type & CAMIF_CODEC ) {
|
|
+ CICOTAREA = rect;
|
|
+ }
|
|
+ if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ CIPRTAREA = rect;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int inline camif_hw_reg(camif_cfg_t *cfg)
|
|
+{
|
|
+ u32 cmd = 0;
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_CODEC) {
|
|
+ CICOSCPRERATIO = PRE_SHIFT(cfg->sc.shfactor)
|
|
+ |PRE_HRATIO(cfg->sc.prehratio)|PRE_VRATIO(cfg->sc.prevratio);
|
|
+ CICOSCPREDST =
|
|
+ PRE_DST_WIDTH(cfg->sc.predst_x)|PRE_DST_HEIGHT(cfg->sc.predst_y);
|
|
+
|
|
+ /* Differ from Preview */
|
|
+ if (cfg->sc.scalerbypass)
|
|
+ cmd |= SCALERBYPASS;
|
|
+ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
|
|
+ cmd |= BIT30|BIT29;
|
|
+ CICOSCCTRL = cmd | MAIN_HRATIO(cfg->sc.mainhratio)
|
|
+ |MAIN_VRATIO(cfg->sc.mainvratio);
|
|
+ return 0;
|
|
+ }
|
|
+ else if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ CIPRSCPRERATIO = PRE_SHIFT(cfg->sc.shfactor)
|
|
+ |PRE_HRATIO(cfg->sc.prehratio)|PRE_VRATIO(cfg->sc.prevratio);
|
|
+ CIPRSCPREDST =
|
|
+ PRE_DST_WIDTH(cfg->sc.predst_x)|PRE_DST_HEIGHT(cfg->sc.predst_y);
|
|
+ /* Differ from Codec */
|
|
+ if (cfg->fmt & CAMIF_RGB24) {
|
|
+ cmd |= RGB_FMT24;
|
|
+ }
|
|
+ else {
|
|
+ /* RGB16 */;
|
|
+ }
|
|
+ if (cfg->sc.scaleup_h & cfg->sc.scaleup_v)
|
|
+ cmd |= BIT29|BIT28;
|
|
+ CIPRSCCTRL = cmd |MAIN_HRATIO(cfg->sc.mainhratio)|S_METHOD
|
|
+ |MAIN_VRATIO(cfg->sc.mainvratio);
|
|
+ }else {
|
|
+ panic("CAMERA:DMA_TYPE Wrong \n");
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/* Configure Pre-scaler control & main scaler control register */
|
|
+static int camif_scaler(camif_cfg_t *cfg)
|
|
+{
|
|
+ int tx = cfg->target_x,ty=cfg->target_y;
|
|
+ int sx, sy;
|
|
+
|
|
+ if (tx <= 0 || ty<= 0) panic("CAMERA: Invalid target size \n");
|
|
+
|
|
+ sx = cfg->gc->source_x - 2*cfg->gc->win_hor_ofst;
|
|
+ sy = cfg->gc->source_y - 2*cfg->gc->win_ver_ofst;
|
|
+ if (sx <= 0 || sy<= 0) panic("CAMERA: Invalid source size \n");
|
|
+ cfg->sc.modified_src_x = sx;
|
|
+ cfg->sc.modified_src_y = sy;
|
|
+
|
|
+ /* Pre-scaler control register 1 */
|
|
+ camif_scaler_internal(sx,tx,&cfg->sc.prehratio,&cfg->sc.hfactor);
|
|
+ camif_scaler_internal(sy,ty,&cfg->sc.prevratio,&cfg->sc.vfactor);
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ if ( (sx /cfg->sc.prehratio) <= 640 ) {}
|
|
+ else {
|
|
+ printk(KERN_INFO "CAMERA: Internal Preview line buffer is 640 pixels\n");
|
|
+ return 1; /* Error */
|
|
+ }
|
|
+ }
|
|
+
|
|
+ cfg->sc.shfactor = 10-(cfg->sc.hfactor+cfg->sc.vfactor);
|
|
+ /* Pre-scaler control register 2 */
|
|
+ cfg->sc.predst_x = sx / cfg->sc.prehratio;
|
|
+ cfg->sc.predst_y = sy / cfg->sc.prevratio;
|
|
+
|
|
+ /* Main-scaler control register */
|
|
+ cfg->sc.mainhratio = (sx << 8)/(tx << cfg->sc.hfactor);
|
|
+ cfg->sc.mainvratio = (sy << 8)/(ty << cfg->sc.vfactor);
|
|
+ DPRINTK(" sx %d, sy %d tx %d ty %d \n",sx,sy,tx,ty);
|
|
+ DPRINTK(" hfactor %d vfactor %d \n",cfg->sc.hfactor,cfg->sc.vfactor);
|
|
+
|
|
+ cfg->sc.scaleup_h = (sx <= tx) ? 1: 0;
|
|
+ cfg->sc.scaleup_v = (sy <= ty) ? 1: 0;
|
|
+ if ( cfg->sc.scaleup_h != cfg->sc.scaleup_v)
|
|
+ printk(KERN_ERR "scaleup_h must be same to scaleup_v \n");
|
|
+ camif_hw_reg(cfg);
|
|
+ camif_target_area(cfg);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/******************************************************
|
|
+ CalculateBurstSize - Calculate the busrt lengths
|
|
+ Description:
|
|
+ - dstHSize: the number of the byte of H Size.
|
|
+********************************************************/
|
|
+static void camif_g_bsize(u32 hsize, u32 *mburst, u32 *rburst)
|
|
+{
|
|
+ u32 tmp;
|
|
+
|
|
+ tmp = (hsize/4) % 16;
|
|
+ switch(tmp) {
|
|
+ case 0:
|
|
+ *mburst=16;
|
|
+ *rburst=16;
|
|
+ break;
|
|
+ case 4:
|
|
+ *mburst=16;
|
|
+ *rburst=4;
|
|
+ break;
|
|
+ case 8:
|
|
+ *mburst=16;
|
|
+ *rburst=8;
|
|
+ break;
|
|
+ default:
|
|
+ tmp=(hsize/4)%8;
|
|
+ switch(tmp) {
|
|
+ case 0:
|
|
+ *mburst=8;
|
|
+ *rburst=8;
|
|
+ break;
|
|
+ case 4:
|
|
+ *mburst=8;
|
|
+ *rburst=4;
|
|
+ default:
|
|
+ *mburst=4;
|
|
+ tmp=(hsize/4)%4;
|
|
+ *rburst= (tmp) ? tmp: 4;
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* SXGA 1028x1024*/
|
|
+/* XGA 1024x768 */
|
|
+/* SVGA 800x600 */
|
|
+/* VGA 640x480 */
|
|
+/* CIF 352x288 */
|
|
+/* QVGA 320x240 */
|
|
+/* QCIF 176x144 */
|
|
+/* ret val
|
|
+ 1 : DMA Size Error
|
|
+*/
|
|
+#define BURST_ERR 1
|
|
+static int camif_dma_burst(camif_cfg_t *cfg)
|
|
+{
|
|
+ int width = cfg->target_x;
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_CODEC ) {
|
|
+ u32 yburst_m, yburst_r;
|
|
+ u32 cburst_m, cburst_r;
|
|
+ /* CODEC DMA WIDHT is multiple of 16 */
|
|
+ if (width %16 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
|
|
+ camif_g_bsize(width,&yburst_m,&yburst_r);
|
|
+ camif_g_bsize(width/2,&cburst_m,&cburst_r);
|
|
+ CICOCTRL =YBURST_M(yburst_m)|CBURST_M(cburst_m)
|
|
+ |YBURST_R(yburst_r)|CBURST_R(cburst_r);
|
|
+ }
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ u32 rgburst_m, rgburst_r;
|
|
+ if(cfg->fmt == CAMIF_RGB24) {
|
|
+ if (width %2 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
|
|
+ camif_g_bsize(width*4,&rgburst_m,&rgburst_r);
|
|
+ }
|
|
+ else { /* CAMIF_RGB16 */
|
|
+ if ((width/2) %2 != 0 ) return BURST_ERR; /* DMA Burst Length Error */
|
|
+ camif_g_bsize(width*2,&rgburst_m,&rgburst_r);
|
|
+ }
|
|
+ CIPRCTRL = RGBURST_M(rgburst_m) | RGBURST_R(rgburst_r);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int camif_gpio_init(void)
|
|
+{
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+ /* S3C24A0A has the dedicated signal pins for Camera */
|
|
+#else
|
|
+ set_gpio_ctrl(GPIO_CAMDATA0);
|
|
+ set_gpio_ctrl(GPIO_CAMDATA1);
|
|
+ set_gpio_ctrl(GPIO_CAMDATA2);
|
|
+ set_gpio_ctrl(GPIO_CAMDATA3);
|
|
+ set_gpio_ctrl(GPIO_CAMDATA4);
|
|
+ set_gpio_ctrl(GPIO_CAMDATA5);
|
|
+ set_gpio_ctrl(GPIO_CAMDATA6);
|
|
+ set_gpio_ctrl(GPIO_CAMDATA7);
|
|
+ set_gpio_ctrl(GPIO_CAMPCLKIN);
|
|
+ set_gpio_ctrl(GPIO_CAMVSYNC);
|
|
+ set_gpio_ctrl(GPIO_CAMHREF);
|
|
+ set_gpio_ctrl(GPIO_CAMPCLKOUT);
|
|
+ set_gpio_ctrl(GPIO_CAMRESET);
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+#define ROUND_ADD 0x100000
|
|
+
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+int camif_clock_init(camif_gc_t *gc)
|
|
+{
|
|
+ unsigned int upll, camclk_div, camclk;
|
|
+
|
|
+ if (!gc) camclk = 24000000;
|
|
+ else {
|
|
+ camclk = gc->camclk;
|
|
+ if (camclk > 48000000)
|
|
+ printk(KERN_ERR "Wrong Camera Clock\n");
|
|
+ }
|
|
+
|
|
+ CLKCON |= CLKCON_CAM_UPLL | CLKCON_CAM_HCLK;
|
|
+ upll = get_bus_clk(GET_UPLL);
|
|
+ printk(KERN_INFO "CAMERA:Default UPLL %08d and Assing 96Mhz to UPLL\n",upll);
|
|
+ UPLLCON = FInsrt(56, fPLL_MDIV) | FInsrt(2, fPLL_PDIV)| FInsrt(1, fPLL_SDIV);
|
|
+ upll = get_bus_clk(GET_UPLL);
|
|
+
|
|
+ camclk_div = (upll+ROUND_ADD) / camclk - 1;
|
|
+ CLKDIVN = (CLKDIVN & 0xFF) | CLKDIVN_CAM(camclk_div);
|
|
+ printk(KERN_INFO"CAMERA:upll %d MACRO 0x%08X CLKDIVN 0x%08X \n",
|
|
+ upll, CLKDIVN_CAM(camclk_div),CLKDIVN);
|
|
+ CIIMGCPT = 0; /* Dummy ? */
|
|
+ return 0;
|
|
+}
|
|
+#else
|
|
+int camif_clock_init(camif_gc_t *gc)
|
|
+{
|
|
+ unsigned int upll, camclk_div, camclk;
|
|
+ if (!gc) camclk = 24000000;
|
|
+ else {
|
|
+ camclk = gc->camclk;
|
|
+ if (camclk > 48000000)
|
|
+ printk(KERN_ERR "Wrong Camera Clock\n");
|
|
+ }
|
|
+
|
|
+ CLKCON |= CLKCON_CAMIF;
|
|
+ upll = elfin_get_bus_clk(GET_UPLL);
|
|
+ printk(KERN_INFO "CAMERA:Default UPLL %08d and Assing 96Mhz to UPLL\n",upll);
|
|
+ {
|
|
+ UPLLCON = FInsrt(60, fPLL_MDIV) | FInsrt(4, fPLL_PDIV)| FInsrt(1, fPLL_SDIV);
|
|
+ CLKDIVN |= DIVN_UPLL; /* For USB */
|
|
+ upll = elfin_get_bus_clk(GET_UPLL);
|
|
+ }
|
|
+
|
|
+ camclk_div = (upll+ROUND_ADD) /(camclk * 2) -1;
|
|
+ CAMDIVN = CAMCLK_SET_DIV|(camclk_div&0xf);
|
|
+ printk(KERN_INFO "CAMERA:upll %08d cam_clk %08d CAMDIVN 0x%08x \n",upll,camclk, CAMDIVN);
|
|
+ CIIMGCPT = 0; /* Dummy ? */
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ Reset Camera IP in CPU
|
|
+ Reset External Sensor
|
|
+ */
|
|
+void camif_reset(int is, int delay)
|
|
+{
|
|
+ switch (is) {
|
|
+ case CAMIF_RESET:
|
|
+ CIGCTRL |= GC_SWRST;
|
|
+ mdelay(1);
|
|
+ CIGCTRL &= ~GC_SWRST;
|
|
+ break;
|
|
+ case CAMIF_EX_RESET_AH: /*Active High */
|
|
+ CIGCTRL &= ~GC_CAMRST;
|
|
+ udelay(200);
|
|
+ CIGCTRL |= GC_CAMRST;
|
|
+ udelay(delay);
|
|
+ CIGCTRL &= ~GC_CAMRST;
|
|
+ break;
|
|
+ case CAMIF_EX_RESET_AL: /*Active Low */
|
|
+ CIGCTRL |= GC_CAMRST;
|
|
+ udelay(200);
|
|
+ CIGCTRL &= ~GC_CAMRST;
|
|
+ udelay(delay);
|
|
+ CIGCTRL |= GC_CAMRST;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* For Camera Operation,
|
|
+ * we can give the high priority to REQ2 of ARBITER1
|
|
+ */
|
|
+
|
|
+/* Please move me into proper place
|
|
+ * camif_gc_t is not because "rmmod imgsenor" will delete the instance of camif_gc_t
|
|
+ */
|
|
+static u32 old_priority;
|
|
+
|
|
+static void camif_bus_priority(int flag)
|
|
+{
|
|
+ if (flag) {
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+ old_priority = PRIORITY0;
|
|
+ PRIORITY0 = PRIORITY_I_FIX;
|
|
+ PRIORITY1 = PRIORITY_I_FIX;
|
|
+
|
|
+#else
|
|
+ old_priority = PRIORITY;
|
|
+ PRIORITY &= ~(3<<7);
|
|
+ PRIORITY |= (1<<7); /* Arbiter 1, REQ2 first */
|
|
+ PRIORITY &= ~(1<<1); /* Disable Priority Rotate */
|
|
+#endif
|
|
+ }
|
|
+ else {
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+ PRIORITY0 = old_priority;
|
|
+ PRIORITY1 = old_priority;
|
|
+#else
|
|
+ PRIORITY = old_priority;
|
|
+#endif
|
|
+ }
|
|
+}
|
|
+
|
|
+static void inline camif_clock_off(void)
|
|
+{
|
|
+ CIIMGCPT = 0;
|
|
+#if defined (CONFIG_ARCH_S3C24A0A)
|
|
+ CLKCON &= ~CLKCON_CAM_UPLL;
|
|
+ CLKCON &= ~CLKCON_CAM_HCLK;
|
|
+#else
|
|
+ CLKCON &= ~CLKCON_CAMIF;
|
|
+#endif
|
|
+}
|
|
+
|
|
+
|
|
+/* Init external image sensor
|
|
+ * Before make some value into image senor,
|
|
+ * you must set up the pixel clock.
|
|
+ */
|
|
+void camif_setup_sensor(void)
|
|
+{
|
|
+ camif_reset(CAMIF_RESET, 0);
|
|
+ camif_gpio_init();
|
|
+ camif_clock_init(NULL);
|
|
+/* Sometimes ,Before loading I2C module, we need the reset signal */
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+ camif_reset(CAMIF_EX_RESET_AL,1000);
|
|
+#else
|
|
+ camif_reset(CAMIF_EX_RESET_AH,1000);
|
|
+#endif
|
|
+}
|
|
+
|
|
+void camif_hw_close(camif_cfg_t *cfg)
|
|
+{
|
|
+ camif_bus_priority(0);
|
|
+ camif_clock_off();
|
|
+}
|
|
+
|
|
+void camif_hw_open(camif_gc_t *gc)
|
|
+{
|
|
+ camif_source_fmt(gc);
|
|
+ camif_win_offset(gc);
|
|
+ camif_bus_priority(1);
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * tab-width: 8
|
|
+ * c-indent-level: 8
|
|
+ * c-basic-offset: 8
|
|
+ * c-set-style: "K&R"
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/camif.h b/arch/arm/mach-s3c2440/camera/camif.h
|
|
new file mode 100644
|
|
index 0000000..8b4f9aa
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/camif.h
|
|
@@ -0,0 +1,304 @@
|
|
+/*
|
|
+ FIMC2.0 Camera Header File
|
|
+
|
|
+ Copyright (C) 2003 Samsung Electronics (SW.LEE: hitchcar@samsung.com)
|
|
+
|
|
+ Author : SW.LEE <hitchcar@samsung.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.
|
|
+*
|
|
+*/
|
|
+
|
|
+
|
|
+#ifndef __FIMC20_CAMIF_H_
|
|
+#define __FIMC20_CAMIF_H_
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+
|
|
+#include "bits.h"
|
|
+#include "videodev.h"
|
|
+#include <asm/types.h>
|
|
+#include <linux/i2c.h>
|
|
+
|
|
+#endif /* __KERNEL__ */
|
|
+
|
|
+#ifndef O_NONCAP
|
|
+#define O_NONCAP O_TRUNC
|
|
+#endif
|
|
+
|
|
+/* Codec or Preview Status */
|
|
+#define CAMIF_STARTED BIT1
|
|
+#define CAMIF_STOPPED BIT2
|
|
+#define CAMIF_INT_HAPPEN BIT3
|
|
+
|
|
+/* Codec or Preview : Interrupt FSM */
|
|
+#define CAMIF_1nd_INT BIT7
|
|
+#define CAMIF_Xnd_INT BIT8
|
|
+#define CAMIF_Ynd_INT BIT9
|
|
+#define CAMIF_Znd_INT BIT10
|
|
+#define CAMIF_NORMAL_INT BIT11
|
|
+#define CAMIF_DUMMY_INT BIT12
|
|
+#define CAMIF_PENDING_INT 0
|
|
+
|
|
+
|
|
+/* CAMIF RESET Definition */
|
|
+#define CAMIF_RESET BIT0
|
|
+#define CAMIF_EX_RESET_AL BIT1 /* Active Low */
|
|
+#define CAMIF_EX_RESET_AH BIT2 /* Active High */
|
|
+
|
|
+
|
|
+enum camif_itu_fmt {
|
|
+ CAMIF_ITU601 = BIT31,
|
|
+ CAMIF_ITU656 = 0
|
|
+};
|
|
+
|
|
+/* It is possbie to use two device simultaneously */
|
|
+enum camif_dma_type {
|
|
+ CAMIF_PREVIEW = BIT0,
|
|
+ CAMIF_CODEC = BIT1,
|
|
+};
|
|
+
|
|
+enum camif_order422 {
|
|
+ CAMIF_YCBYCR = 0,
|
|
+ CAMIF_YCRYCB = BIT14,
|
|
+ CAMIF_CBYCRY = BIT15,
|
|
+ CAMIF_CRYCBY = BIT14 | BIT15
|
|
+};
|
|
+
|
|
+enum flip_mode {
|
|
+ CAMIF_FLIP = 0,
|
|
+ CAMIF_FLIP_X = BIT14,
|
|
+ CAMIF_FLIP_Y = BIT15,
|
|
+ CAMIF_FLIP_MIRROR = BIT14 |BIT15,
|
|
+};
|
|
+
|
|
+enum camif_codec_fmt {
|
|
+ /* Codec part */
|
|
+ CAMIF_IN_YCBCR420 = BIT0, /* Currently IN_YCBCR format fixed */
|
|
+ CAMIF_IN_YCBCR422 = BIT1,
|
|
+ CAMIF_OUT_YCBCR420 = BIT4,
|
|
+ CAMIF_OUT_YCBCR422 = BIT5,
|
|
+ /* Preview Part */
|
|
+ CAMIF_RGB16 = BIT2,
|
|
+ CAMIF_RGB24 = BIT3,
|
|
+};
|
|
+
|
|
+enum camif_capturing {
|
|
+ CAMIF_BOTH_DMA_ON = BIT4,
|
|
+ CAMIF_DMA_ON = BIT3,
|
|
+ CAMIF_BOTH_DMA_OFF = BIT1,
|
|
+ CAMIF_DMA_OFF = BIT0,
|
|
+ /*------------------------*/
|
|
+ CAMIF_DMA_OFF_L_IRQ= BIT5,
|
|
+};
|
|
+
|
|
+typedef struct camif_performance
|
|
+{
|
|
+ int frames;
|
|
+ int framesdropped;
|
|
+ __u64 bytesin;
|
|
+ __u64 bytesout;
|
|
+ __u32 reserved[4];
|
|
+} camif_perf_t;
|
|
+
|
|
+
|
|
+typedef struct {
|
|
+ dma_addr_t phys_y;
|
|
+ dma_addr_t phys_cb;
|
|
+ dma_addr_t phys_cr;
|
|
+ u8 *virt_y;
|
|
+ u8 *virt_cb;
|
|
+ u8 *virt_cr;
|
|
+ dma_addr_t phys_rgb;
|
|
+ u8 *virt_rgb;
|
|
+}img_buf_t;
|
|
+
|
|
+
|
|
+/* this structure convers the CIWDOFFST, prescaler, mainscaler */
|
|
+typedef struct {
|
|
+ u32 modified_src_x; /* After windows applyed to source_x */
|
|
+ u32 modified_src_y;
|
|
+ u32 hfactor;
|
|
+ u32 vfactor;
|
|
+ u32 shfactor; /* SHfactor = 10 - ( hfactor + vfactor ) */
|
|
+ u32 prehratio;
|
|
+ u32 prevratio;
|
|
+ u32 predst_x;
|
|
+ u32 predst_y;
|
|
+ u32 scaleup_h;
|
|
+ u32 scaleup_v;
|
|
+ u32 mainhratio;
|
|
+ u32 mainvratio;
|
|
+ u32 scalerbypass; /* only codec */
|
|
+} scaler_t;
|
|
+
|
|
+
|
|
+enum v4l2_status {
|
|
+ CAMIF_V4L2_INIT = BIT0,
|
|
+ CAMIF_v4L2_DIRTY = BIT1,
|
|
+};
|
|
+
|
|
+
|
|
+/* Global Status Definition */
|
|
+#define PWANT2START BIT0
|
|
+#define CWANT2START BIT1
|
|
+#define BOTH_STARTED (PWANT2START|CWANT2START)
|
|
+#define PNOTWORKING BIT4
|
|
+#define C_WORKING BIT5
|
|
+
|
|
+typedef struct {
|
|
+ struct semaphore lock;
|
|
+ enum camif_itu_fmt itu_fmt;
|
|
+ enum camif_order422 order422;
|
|
+ u32 win_hor_ofst;
|
|
+ u32 win_ver_ofst;
|
|
+ u32 camclk; /* External Image Sensor Camera Clock */
|
|
+ u32 source_x;
|
|
+ u32 source_y;
|
|
+ u32 polarity_pclk;
|
|
+ u32 polarity_vsync;
|
|
+ u32 polarity_href;
|
|
+ struct i2c_client *sensor;
|
|
+ u32 user; /* MAX 2 (codec, preview) */
|
|
+ u32 old_priority; /* BUS PRIORITY register */
|
|
+ u32 status;
|
|
+ u32 init_sensor;/* initializing sensor */
|
|
+ void *other; /* Codec camif_cfg_t */
|
|
+ u32 reset_type; /* External Sensor Reset Type */
|
|
+ u32 reset_udelay;
|
|
+} camif_gc_t; /* gobal control register */
|
|
+
|
|
+
|
|
+/* when App want to change v4l2 parameter,
|
|
+ * we instantly store it into v4l2_t v2
|
|
+ * and then reflect it to hardware
|
|
+ */
|
|
+typedef struct v4l2 {
|
|
+ struct v4l2_fmtdesc *fmtdesc;
|
|
+ struct v4l2_pix_format fmt; /* current pixel format */
|
|
+ struct v4l2_input input;
|
|
+ struct video_picture picture;
|
|
+ enum v4l2_status status;
|
|
+ int used_fmt ; /* used format index */
|
|
+} v4l2_t;
|
|
+
|
|
+
|
|
+typedef struct camif_c_t {
|
|
+ struct video_device *v;
|
|
+ /* V4L2 param only for v4l2 driver */
|
|
+ v4l2_t v2;
|
|
+ camif_gc_t *gc; /* Common between Codec and Preview */
|
|
+ /* logical parameter */
|
|
+ wait_queue_head_t waitq;
|
|
+ u32 status; /* Start/Stop */
|
|
+ u32 fsm; /* Start/Stop */
|
|
+ u32 open_count; /* duplicated */
|
|
+ int irq;
|
|
+ char shortname[16];
|
|
+ u32 target_x;
|
|
+ u32 target_y;
|
|
+ scaler_t sc;
|
|
+ enum flip_mode flip;
|
|
+ enum camif_dma_type dma_type;
|
|
+ /* 4 pingpong Frame memory */
|
|
+ u8 *pp_virt_buf;
|
|
+ dma_addr_t pp_phys_buf;
|
|
+ u32 pp_totalsize;
|
|
+ u32 pp_num; /* used pingpong memory number */
|
|
+ img_buf_t img_buf[4];
|
|
+ enum camif_codec_fmt fmt;
|
|
+ enum camif_capturing exec;
|
|
+ camif_perf_t perf;
|
|
+ u32 now_frame_num;
|
|
+ u32 auto_restart; /* Only For Preview */
|
|
+} camif_cfg_t;
|
|
+
|
|
+#ifdef SW_DEBUG
|
|
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
|
|
+#else
|
|
+#define DPRINTK(fmt, args...)
|
|
+#endif
|
|
+
|
|
+
|
|
+#ifdef SW_DEBUG
|
|
+#define assert(expr) \
|
|
+ if(!(expr)) { \
|
|
+ printk( "Assertion failed! %s,%s,%s,line=%d\n", \
|
|
+ #expr,__FILE__,__FUNCTION__,__LINE__); \
|
|
+ }
|
|
+#else
|
|
+#define assert(expr)
|
|
+#endif
|
|
+
|
|
+
|
|
+
|
|
+extern int camif_capture_start(camif_cfg_t *);
|
|
+extern int camif_capture_stop(camif_cfg_t *);
|
|
+extern int camif_g_frame_num(camif_cfg_t *);
|
|
+extern u8 * camif_g_frame(camif_cfg_t *);
|
|
+extern int camif_win_offset(camif_gc_t *);
|
|
+extern void camif_hw_open(camif_gc_t *);
|
|
+extern void camif_hw_close(camif_cfg_t *);
|
|
+extern int camif_dynamic_open(camif_cfg_t *);
|
|
+extern int camif_dynamic_close(camif_cfg_t *);
|
|
+extern void camif_reset(int,int);
|
|
+extern void camif_setup_sensor(void);
|
|
+extern int camif_g_fifo_status(camif_cfg_t *);
|
|
+extern void camif_last_irq_en(camif_cfg_t *);
|
|
+extern void camif_change_flip(camif_cfg_t *);
|
|
+
|
|
+
|
|
+/* Todo
|
|
+ * API Interface function to both Character and V4L2 Drivers
|
|
+ */
|
|
+extern int camif_do_write(struct file *,const char *, size_t, loff_t *);
|
|
+extern int camif_do_ioctl(struct inode *, struct file *,unsigned int, void *);
|
|
+
|
|
+
|
|
+/*
|
|
+ * API for Decoder (S5x532, OV7620..)
|
|
+ */
|
|
+void camif_register_decoder(struct i2c_client *);
|
|
+void camif_unregister_decoder(struct i2c_client*);
|
|
+
|
|
+
|
|
+
|
|
+/* API for FSM */
|
|
+#define INSTANT_SKIP 0
|
|
+#define INSTANT_GO 1
|
|
+
|
|
+extern ssize_t camif_p_1fsm_start(camif_cfg_t *);
|
|
+extern ssize_t camif_p_2fsm_start(camif_cfg_t *);
|
|
+extern ssize_t camif_4fsm_start(camif_cfg_t *);
|
|
+extern ssize_t camif_p_stop(camif_cfg_t *);
|
|
+extern int camif_enter_p_4fsm(camif_cfg_t *);
|
|
+extern int camif_enter_c_4fsm(camif_cfg_t *);
|
|
+extern int camif_enter_2fsm(camif_cfg_t *);
|
|
+extern int camif_enter_1fsm(camif_cfg_t *);
|
|
+extern int camif_check_preview(camif_cfg_t *);
|
|
+extern int camif_callback_start(camif_cfg_t *);
|
|
+extern int camif_clock_init(camif_gc_t *);
|
|
+
|
|
+/*
|
|
+ * V4L2 Part
|
|
+ */
|
|
+#define VID_HARDWARE_SAMSUNG_FIMC20 236
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * tab-width: 8
|
|
+ * c-indent-level: 8
|
|
+ * c-basic-offset: 8
|
|
+ * c-set-style: "K&R"
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/camif_fsm.c b/arch/arm/mach-s3c2440/camera/camif_fsm.c
|
|
new file mode 100644
|
|
index 0000000..3e2b71a
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/camif_fsm.c
|
|
@@ -0,0 +1,427 @@
|
|
+/*
|
|
+ Copyright (C) 2004 Samsung Electronics
|
|
+ SW.LEE <hitchcar@sec.samsung.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.
|
|
+*/
|
|
+
|
|
+#include <linux/version.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/fs.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/major.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/poll.h>
|
|
+#include <linux/signal.h>
|
|
+#include <linux/ioport.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/interrupt.h>
|
|
+#include <linux/kmod.h>
|
|
+#include <linux/vmalloc.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/pagemap.h>
|
|
+#include <asm/io.h>
|
|
+#include <asm/irq.h>
|
|
+#include <asm/semaphore.h>
|
|
+#include <linux/miscdevice.h>
|
|
+
|
|
+//#define SW_DEBUG
|
|
+
|
|
+#include "camif.h"
|
|
+const char *fsm_version =
|
|
+ "$Id: camif_fsm.c,v 1.3 2004/04/27 10:26:28 swlee Exp $";
|
|
+
|
|
+
|
|
+/*
|
|
+ * FSM function is the place where Synchronization in not necessary
|
|
+ * because IRS calls this functions.
|
|
+ */
|
|
+
|
|
+ssize_t camif_p_1fsm_start(camif_cfg_t *cfg)
|
|
+{
|
|
+ //camif_reset(CAMIF_RESET,0);
|
|
+ cfg->exec = CAMIF_DMA_ON;
|
|
+ camif_capture_start(cfg);
|
|
+ camif_last_irq_en(cfg);
|
|
+ cfg->status = CAMIF_STARTED;
|
|
+ cfg->fsm = CAMIF_1nd_INT;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+ssize_t camif_p_2fsm_start(camif_cfg_t *cfg)
|
|
+{
|
|
+ camif_reset(CAMIF_RESET,0);/* FIFO Count goes to zero */
|
|
+ cfg->exec = CAMIF_DMA_ON;
|
|
+ camif_capture_start(cfg);
|
|
+ cfg->status = CAMIF_STARTED;
|
|
+ cfg->fsm = CAMIF_1nd_INT;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+ssize_t camif_4fsm_start(camif_cfg_t *cfg)
|
|
+{
|
|
+ camif_reset(CAMIF_RESET,0); /* FIFO Count goes to zero */
|
|
+ cfg->exec = CAMIF_DMA_ON;
|
|
+ camif_capture_start(cfg);
|
|
+ cfg->status = CAMIF_STARTED;
|
|
+ cfg->fsm = CAMIF_1nd_INT;
|
|
+ cfg->perf.frames = 0;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/* Policy:
|
|
+ cfg->perf.frames set in camif_fsm.c
|
|
+ cfg->status set in video-driver.c
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Don't insert camif_reset(CAM_RESET, 0 ) into this func
|
|
+ */
|
|
+ssize_t camif_p_stop(camif_cfg_t *cfg)
|
|
+{
|
|
+ cfg->exec = CAMIF_DMA_OFF;
|
|
+// cfg->status = CAMIF_STOPPED;
|
|
+ camif_capture_stop(cfg);
|
|
+ cfg->perf.frames = 0; /* Dupplicated ? */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* When C working, P asks C to play togehter */
|
|
+/* Only P must call this function */
|
|
+void camif_start_c_with_p (camif_cfg_t *cfg, camif_cfg_t *other)
|
|
+{
|
|
+// cfg->gc->other = get_camif(CODEC_MINOR);
|
|
+ cfg->gc->other = other;
|
|
+ camif_start_p_with_c(cfg);
|
|
+}
|
|
+
|
|
+static void camif_start_p_with_c(camif_cfg_t *cfg)
|
|
+{
|
|
+ camif_cfg_t *other = (camif_cfg_t *)cfg->gc->other;
|
|
+ /* Preview Stop */
|
|
+ cfg->exec = CAMIF_DMA_OFF;
|
|
+ camif_capture_stop(cfg);
|
|
+ /* Start P and C */
|
|
+ camif_reset(CAMIF_RESET, 0);
|
|
+ cfg->exec =CAMIF_BOTH_DMA_ON;
|
|
+ camif_capture_start(cfg);
|
|
+ cfg->fsm = CAMIF_1nd_INT; /* For Preview */
|
|
+ if(!other) panic("Unexpected Error \n");
|
|
+ other->fsm = CAMIF_1nd_INT; /* For Preview */
|
|
+}
|
|
+
|
|
+static void camif_auto_restart(camif_cfg_t *cfg)
|
|
+{
|
|
+// if (cfg->dma_type & CAMIF_CODEC) return;
|
|
+ if (cfg->auto_restart)
|
|
+ camif_start_p_with_c(cfg);
|
|
+}
|
|
+
|
|
+
|
|
+/* Supposed that PREVIEW already running
|
|
+ * request PREVIEW to start with Codec
|
|
+ */
|
|
+static int camif_check_global(camif_cfg_t *cfg)
|
|
+{
|
|
+ int ret = 0;
|
|
+
|
|
+ if (down_interruptible(&cfg->gc->lock))
|
|
+ return -ERESTARTSYS;
|
|
+ if ( cfg->gc->status & CWANT2START ) {
|
|
+ cfg->gc->status &= ~CWANT2START;
|
|
+ cfg->auto_restart = 1;
|
|
+ ret = 1;
|
|
+ }
|
|
+ else {
|
|
+ ret = 0; /* There is no codec */
|
|
+ cfg->auto_restart = 0; /* Duplicated ..Dummy */
|
|
+ }
|
|
+
|
|
+ up(&cfg->gc->lock);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * 1nd INT : Start Interrupt
|
|
+ * Xnd INT : enable Last IRQ : pingpong get the valid data
|
|
+ * Ynd INT : Stop Codec or Preview : pingpong get the valid data
|
|
+ * Znd INT : Last IRQ : valid data
|
|
+ */
|
|
+#define CHECK_FREQ 5
|
|
+int camif_enter_p_4fsm(camif_cfg_t *cfg)
|
|
+{
|
|
+ int ret = 0;
|
|
+
|
|
+ cfg->perf.frames++;
|
|
+ if (cfg->fsm == CAMIF_NORMAL_INT)
|
|
+ if (cfg->perf.frames % CHECK_FREQ == 0)
|
|
+ ret = camif_check_global(cfg);
|
|
+ if (ret > 0) cfg->fsm = CAMIF_Xnd_INT; /* Codec wait for Preview */
|
|
+
|
|
+ switch (cfg->fsm) {
|
|
+ case CAMIF_1nd_INT: /* Start IRQ */
|
|
+ cfg->fsm = CAMIF_NORMAL_INT;
|
|
+ ret = INSTANT_SKIP;
|
|
+ DPRINTK(KERN_INFO "1nd INT \n");
|
|
+ break;
|
|
+ case CAMIF_NORMAL_INT:
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ cfg->fsm = CAMIF_NORMAL_INT;
|
|
+ ret = INSTANT_GO;
|
|
+ DPRINTK(KERN_INFO "NORMAL INT \n");
|
|
+ break;
|
|
+ case CAMIF_Xnd_INT:
|
|
+ camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ cfg->fsm = CAMIF_Ynd_INT;
|
|
+ ret = INSTANT_GO;
|
|
+ DPRINTK(KERN_INFO "Xnd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Ynd_INT: /* Capture Stop */
|
|
+ cfg->exec = CAMIF_DMA_OFF;
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ camif_capture_stop(cfg);
|
|
+ cfg->fsm = CAMIF_Znd_INT;
|
|
+ ret = INSTANT_GO;
|
|
+ DPRINTK(KERN_INFO "Ynd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
|
|
+ cfg->fsm = CAMIF_DUMMY_INT;
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ ret = INSTANT_GO;
|
|
+ camif_auto_restart(cfg); /* Automatically Restart Camera */
|
|
+ DPRINTK(KERN_INFO "Znd INT \n");
|
|
+ break;
|
|
+ case CAMIF_DUMMY_INT:
|
|
+ cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
|
|
+ ret = INSTANT_SKIP;
|
|
+// DPRINTK(KERN_INFO "Dummy INT \n");
|
|
+ break;
|
|
+ default:
|
|
+ printk(KERN_INFO "Unexpect INT %d \n",cfg->fsm);
|
|
+ ret = INSTANT_SKIP;
|
|
+ break;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * NO autorestart included in this function
|
|
+ */
|
|
+int camif_enter_c_4fsm(camif_cfg_t *cfg)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ cfg->perf.frames++;
|
|
+#if 0
|
|
+ if ( (cfg->fsm==CAMIF_NORMAL_INT)
|
|
+ && (cfg->perf.frames>cfg->restart_limit-1)
|
|
+ )
|
|
+ cfg->fsm = CAMIF_Xnd_INT;
|
|
+#endif
|
|
+ switch (cfg->fsm) {
|
|
+ case CAMIF_1nd_INT: /* Start IRQ */
|
|
+ cfg->fsm = CAMIF_NORMAL_INT;
|
|
+// cfg->status = CAMIF_STARTED; /* need this to meet auto-restart */
|
|
+ ret = INSTANT_SKIP;
|
|
+ DPRINTK(KERN_INFO "1nd INT \n");
|
|
+ break;
|
|
+ case CAMIF_NORMAL_INT:
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ cfg->fsm = CAMIF_NORMAL_INT;
|
|
+ ret = INSTANT_GO;
|
|
+ DPRINTK(KERN_INFO "NORMALd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Xnd_INT:
|
|
+ camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ cfg->fsm = CAMIF_Ynd_INT;
|
|
+ ret = INSTANT_GO;
|
|
+ DPRINTK(KERN_INFO "Xnd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Ynd_INT: /* Capture Stop */
|
|
+ cfg->exec = CAMIF_DMA_OFF;
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ camif_capture_stop(cfg);
|
|
+ cfg->fsm = CAMIF_Znd_INT;
|
|
+ ret = INSTANT_GO;
|
|
+ DPRINTK(KERN_INFO "Ynd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
|
|
+ cfg->fsm = CAMIF_DUMMY_INT;
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ ret = INSTANT_GO;
|
|
+ DPRINTK(KERN_INFO "Znd INT \n");
|
|
+ break;
|
|
+ case CAMIF_DUMMY_INT:
|
|
+ cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
|
|
+ ret = INSTANT_SKIP;
|
|
+ break;
|
|
+ default:
|
|
+ printk(KERN_INFO "Unexpect INT %d \n",cfg->fsm);
|
|
+ ret = INSTANT_SKIP;
|
|
+ break;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* 4 Interrups State Machine is for two pingpong
|
|
+ * 1nd INT : Start Interrupt
|
|
+ * Xnd INT : enable Last IRQ : pingpong get the valid data
|
|
+ * Ynd INT : Stop Codec or Preview : pingpong get the valid data
|
|
+ * Znd INT : Last IRQ : valid data
|
|
+ *
|
|
+ * Note:
|
|
+ * Before calling this func, you must call camif_reset
|
|
+ */
|
|
+
|
|
+int camif_enter_2fsm(camif_cfg_t *cfg) /* Codec FSM */
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ cfg->perf.frames++;
|
|
+ switch (cfg->fsm) {
|
|
+ case CAMIF_1nd_INT: /* Start IRQ */
|
|
+ cfg->fsm = CAMIF_Xnd_INT;
|
|
+ ret = INSTANT_SKIP;
|
|
+// printk(KERN_INFO "1nd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Xnd_INT:
|
|
+ camif_last_irq_en(cfg);/* IRQ for Enabling LAST IRQ */
|
|
+ cfg->now_frame_num = 0;
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ cfg->fsm = CAMIF_Ynd_INT;
|
|
+ ret = INSTANT_GO;
|
|
+// printk(KERN_INFO "2nd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Ynd_INT: /* Capture Stop */
|
|
+ cfg->exec = CAMIF_DMA_OFF;
|
|
+ cfg->now_frame_num = 1;
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ camif_capture_stop(cfg);
|
|
+ cfg->fsm = CAMIF_Znd_INT;
|
|
+ ret = INSTANT_GO;
|
|
+// printk(KERN_INFO "Ynd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
|
|
+ cfg->now_frame_num = 0;
|
|
+// cfg->fsm = CAMIF_DUMMY_INT;
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ ret = INSTANT_GO;
|
|
+// printk(KERN_INFO "Znd INT \n");
|
|
+ break;
|
|
+ case CAMIF_DUMMY_INT:
|
|
+ cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
|
|
+ ret = INSTANT_SKIP;
|
|
+ printk(KERN_INFO "Dummy INT \n");
|
|
+ break;
|
|
+ default: /* CAMIF_PENDING_INT */
|
|
+ printk(KERN_INFO "Unexpect INT \n");
|
|
+ ret = INSTANT_SKIP;
|
|
+ break;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+/* 2 Interrups State Machine is for one pingpong
|
|
+ * 1nd INT : Stop Codec or Preview : pingpong get the valid data
|
|
+ * 2nd INT : Last IRQ : dummy data
|
|
+ */
|
|
+int camif_enter_1fsm(camif_cfg_t *cfg) /* Codec FSM */
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ cfg->perf.frames++;
|
|
+ switch (cfg->fsm) {
|
|
+ case CAMIF_Ynd_INT: /* IRQ for Enabling LAST IRQ */
|
|
+ cfg->exec = CAMIF_DMA_OFF;
|
|
+ camif_capture_stop(cfg);
|
|
+ cfg->fsm = CAMIF_Znd_INT;
|
|
+ ret = INSTANT_SKIP;
|
|
+ // printk(KERN_INFO "Ynd INT \n");
|
|
+ break;
|
|
+ case CAMIF_Znd_INT: /* LAST IRQ (Dummy IRQ */
|
|
+ cfg->fsm = CAMIF_DUMMY_INT;
|
|
+ cfg->status = CAMIF_INT_HAPPEN;
|
|
+ ret = INSTANT_GO;
|
|
+ // printk(KERN_INFO "Znd INT \n");
|
|
+ break;
|
|
+ case CAMIF_DUMMY_INT:
|
|
+ cfg->status = CAMIF_STOPPED; /* Dupplicate ? */
|
|
+ ret = INSTANT_SKIP;
|
|
+ printk(KERN_INFO "Dummy INT \n");
|
|
+ break;
|
|
+ default:
|
|
+ printk(KERN_INFO "Unexpect INT \n");
|
|
+ ret = INSTANT_SKIP;
|
|
+ break;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * GLOBAL STATUS CONTROL FUNCTION
|
|
+ *
|
|
+ */
|
|
+
|
|
+
|
|
+/* Supposed that PREVIEW already running
|
|
+ * request PREVIEW to start with Codec
|
|
+ */
|
|
+int camif_callback_start(camif_cfg_t *cfg)
|
|
+{
|
|
+ int doit = 1;
|
|
+ while (doit) {
|
|
+ if (down_interruptible(&cfg->gc->lock)) {
|
|
+ return -ERESTARTSYS;
|
|
+ }
|
|
+ cfg->gc->status = CWANT2START;
|
|
+ cfg->gc->other = cfg;
|
|
+ up(&cfg->gc->lock);
|
|
+ doit = 0;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Return status of Preview Machine
|
|
+ ret value :
|
|
+ 0: Preview is not working
|
|
+ X: Codec must follow PREVIEW start
|
|
+*/
|
|
+int camif_check_preview(camif_cfg_t *cfg)
|
|
+{
|
|
+ int ret = 0;
|
|
+
|
|
+ if (down_interruptible(&cfg->gc->lock)) {
|
|
+ ret = -ERESTARTSYS;
|
|
+ return ret;
|
|
+ }
|
|
+ if (cfg->gc->user == 1) ret = 0;
|
|
+ // else if (cfg->gc->status & PNOTWORKING) ret = 0;
|
|
+ else ret = 1;
|
|
+ up(&cfg->gc->lock);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * c-basic-offset: 8
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/imgsensor.c b/arch/arm/mach-s3c2440/camera/imgsensor.c
|
|
new file mode 100644
|
|
index 0000000..44b7bee
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/imgsensor.c
|
|
@@ -0,0 +1,255 @@
|
|
+/*
|
|
+ * Copyright (C) 2004 Samsung Electronics
|
|
+ * SW.LEE <hitchcar@samsung.com>
|
|
+ *
|
|
+ * Copyright (C) 2000 Russell King : pcf8583.c
|
|
+ *
|
|
+ * 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.
|
|
+ *
|
|
+ * Driver for FIMC20 Camera Decoder
|
|
+ */
|
|
+
|
|
+#include <linux/config.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/i2c.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/delay.h>
|
|
+
|
|
+
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+#else
|
|
+#include <asm/arch/S3C2440.h>
|
|
+#endif
|
|
+
|
|
+#define SW_DEBUG
|
|
+#include "camif.h"
|
|
+#include "sensor.h"
|
|
+
|
|
+#ifndef SAMSUNG_SXGA_CAM
|
|
+#include "s5x532_rev36.h"
|
|
+#else
|
|
+#include "sxga.h"
|
|
+#endif
|
|
+
|
|
+static const char *sensor_version =
|
|
+ "$Id: imgsensor.c,v 1.11 2004/06/10 12:45:40 swlee Exp $";
|
|
+
|
|
+
|
|
+static struct i2c_driver s5x532_driver;
|
|
+static camif_gc_t data = {
|
|
+ itu_fmt: CAMIF_ITU601,
|
|
+ order422: CAMIF_YCBYCR,
|
|
+ camclk: 24000000,
|
|
+#ifndef SAMSUNG_SXGA_CAM
|
|
+ source_x: 640,
|
|
+ source_y: 480,
|
|
+ win_hor_ofst: 112,
|
|
+ win_ver_ofst: 20,
|
|
+#else
|
|
+ source_x: 1280,
|
|
+ source_y: 1024,
|
|
+ win_hor_ofst: 0,
|
|
+ win_ver_ofst: 0,
|
|
+#endif
|
|
+ polarity_pclk:1,
|
|
+ polarity_href:0,
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+ reset_type:CAMIF_EX_RESET_AL, /* Active Low */
|
|
+#else
|
|
+ reset_type:CAMIF_EX_RESET_AH, /* Ref board has inverted signal */
|
|
+#endif
|
|
+ reset_udelay:2000,
|
|
+};
|
|
+
|
|
+#define CAM_ID 0x5a
|
|
+
|
|
+static unsigned short ignore[] = { I2C_CLIENT_END };
|
|
+static unsigned short normal_addr[] = { (CAM_ID>>1), I2C_CLIENT_END };
|
|
+static struct i2c_client_address_data addr_data = {
|
|
+ normal_i2c: normal_addr,
|
|
+ normal_i2c_range: ignore,
|
|
+ probe: ignore,
|
|
+ probe_range: ignore,
|
|
+ ignore: ignore,
|
|
+ ignore_range: ignore,
|
|
+ force: ignore,
|
|
+};
|
|
+
|
|
+s5x532_t s5x532_regs_mirror[S5X532_REGS];
|
|
+
|
|
+unsigned char
|
|
+s5x532_read(struct i2c_client *client,unsigned char subaddr)
|
|
+{
|
|
+ int ret;
|
|
+ unsigned char buf[1];
|
|
+ struct i2c_msg msg ={ client->addr, 0, 1, buf};
|
|
+ buf[0] = subaddr;
|
|
+
|
|
+ ret = i2c_transfer(client->adapter,&msg, 1) == 1 ? 0 : -EIO;
|
|
+ if (ret == -EIO) {
|
|
+ printk(" I2C write Error \n");
|
|
+ return -EIO;
|
|
+ }
|
|
+
|
|
+ msg.flags = I2C_M_RD;
|
|
+ ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
|
|
+
|
|
+ return buf[0];
|
|
+}
|
|
+
|
|
+
|
|
+static int
|
|
+s5x532_write(struct i2c_client *client,
|
|
+ unsigned char subaddr, unsigned char val)
|
|
+{
|
|
+ unsigned char buf[2];
|
|
+ struct i2c_msg msg = { client->addr, 0, 2, buf};
|
|
+
|
|
+ buf[0]= subaddr;
|
|
+ buf[1]= val;
|
|
+
|
|
+ return i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
|
|
+}
|
|
+
|
|
+void inline s5x532_init(struct i2c_client *sam_client)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ printk(KERN_ERR "s5x532_init \n");
|
|
+ for (i = 0; i < S5X532_INIT_REGS; i++) {
|
|
+ s5x532_write(sam_client,
|
|
+ s5x532_reg[i].subaddr, s5x532_reg[i].value );
|
|
+ }
|
|
+
|
|
+#ifdef YOU_WANT_TO_CHECK_IMG_SENSOR
|
|
+ for (i = 0; i < S5X532_INIT_REGS;i++) {
|
|
+ if ( s5x532_reg[i].subaddr == PAGE_ADDRESS ) {
|
|
+ s5x532_write(sam_client,
|
|
+ s5x532_reg[i].subaddr, s5x532_reg[i].value);
|
|
+
|
|
+ printk(KERN_ERR "Page: Subaddr %02x = 0x%02x\n",
|
|
+ s5x532_reg[i].subaddr, s5x532_regs_mirror[i].value);
|
|
+
|
|
+
|
|
+ } else
|
|
+ {
|
|
+ s5x532_regs_mirror[i].subaddr = s5x532_reg[i].subaddr;
|
|
+ s5x532_regs_mirror[i].value =
|
|
+ s5x532_read(sam_client,s5x532_reg[i].subaddr);
|
|
+ printk(KERN_ERR "Subaddr %02x = 0x%02x\n",
|
|
+ s5x532_reg[i].subaddr, s5x532_regs_mirror[i].value);
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
+}
|
|
+
|
|
+static int
|
|
+s5x532_attach(struct i2c_adapter *adap, int addr, unsigned short flags,int kind)
|
|
+{
|
|
+ struct i2c_client *c;
|
|
+
|
|
+ c = kmalloc(sizeof(*c), GFP_KERNEL);
|
|
+ if (!c) return -ENOMEM;
|
|
+
|
|
+ strcpy(c->name, "S5X532");
|
|
+ c->id = s5x532_driver.id;
|
|
+ c->flags = I2C_CLIENT_ALLOW_USE;
|
|
+ c->addr = addr;
|
|
+ c->adapter = adap;
|
|
+ c->driver = &s5x532_driver;
|
|
+ c->data = &data;
|
|
+ data.sensor = c;
|
|
+
|
|
+ camif_register_decoder(c);
|
|
+ return i2c_attach_client(c);
|
|
+}
|
|
+
|
|
+static int s5x532_probe(struct i2c_adapter *adap)
|
|
+{
|
|
+ return i2c_probe(adap, &addr_data, s5x532_attach);
|
|
+}
|
|
+
|
|
+static int s5x532_detach(struct i2c_client *client)
|
|
+{
|
|
+ i2c_detach_client(client);
|
|
+ camif_unregister_decoder(client);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+s5x532_command(struct i2c_client *client, unsigned int cmd, void *arg)
|
|
+{
|
|
+ switch (cmd) {
|
|
+ case SENSOR_INIT:
|
|
+ s5x532_init(client);
|
|
+ printk(KERN_INFO "CAMERA: S5X532 Sensor initialized\n");
|
|
+ break;
|
|
+ case USER_ADD:
|
|
+ MOD_INC_USE_COUNT;
|
|
+ break;
|
|
+ case USER_EXIT:
|
|
+ MOD_DEC_USE_COUNT;
|
|
+ break;
|
|
+/* Todo
|
|
+ case SENSOR_BRIGHTNESS:
|
|
+ change_sensor();
|
|
+ break;
|
|
+*/
|
|
+ default:
|
|
+ panic("Unexpect Sensor Command \n");
|
|
+ break;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct i2c_driver s5x532_driver = {
|
|
+ name: "S5X532",
|
|
+ id: I2C_ALGO_S3C,
|
|
+ flags: I2C_DF_NOTIFY,
|
|
+ attach_adapter: s5x532_probe,
|
|
+ detach_client: s5x532_detach,
|
|
+ command: s5x532_command
|
|
+};
|
|
+
|
|
+static void iic_gpio_port(void)
|
|
+{
|
|
+#ifdef CONFIG_ARCH_S3C24A0A
|
|
+#else
|
|
+ GPECON &= ~(0xf <<28);
|
|
+ GPECON |= 0xa <<28;
|
|
+#endif
|
|
+}
|
|
+
|
|
+static __init int camif_sensor_init(void)
|
|
+{
|
|
+ iic_gpio_port();
|
|
+ return i2c_add_driver(&s5x532_driver);
|
|
+}
|
|
+
|
|
+
|
|
+static __init void camif_sensor_exit(void)
|
|
+{
|
|
+ i2c_del_driver(&s5x532_driver);
|
|
+}
|
|
+
|
|
+module_init(camif_sensor_init)
|
|
+module_exit(camif_sensor_exit)
|
|
+
|
|
+MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
|
|
+MODULE_DESCRIPTION("I2C Client Driver For Fimc2.0 MISC Driver");
|
|
+MODULE_LICENSE("GPL");
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * c-basic-offset: 8
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/miscdevice.h b/arch/arm/mach-s3c2440/camera/miscdevice.h
|
|
new file mode 100644
|
|
index 0000000..2e1cfbc
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/miscdevice.h
|
|
@@ -0,0 +1,18 @@
|
|
+
|
|
+ /*----------------------------------------------------------
|
|
+ * (C) 2004 Samsung Electronics
|
|
+ * SW.LEE < hitchcar@samsung.com>
|
|
+ *
|
|
+ ----------------------------------------------------------- */
|
|
+
|
|
+#ifndef _LINUX_S3C_MISCDEVICE_H
|
|
+#define _LINUX_S3C_MISCDEVICE_H
|
|
+
|
|
+#define CODEC_MINOR 212
|
|
+#define PREVIEW_MINOR 213
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/arch/arm/mach-s3c2440/camera/qt-driver.c b/arch/arm/mach-s3c2440/camera/qt-driver.c
|
|
new file mode 100644
|
|
index 0000000..0c5dd40
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/qt-driver.c
|
|
@@ -0,0 +1,169 @@
|
|
+/*
|
|
+ * SW.LEE <hitchcar@samsung.com>
|
|
+ *
|
|
+ * This file is subject to the terms and conditions of the GNU General Public
|
|
+ * License 2. See the file COPYING in the main directory of this archive
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+#include <linux/version.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/fs.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/major.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/poll.h>
|
|
+#include <linux/signal.h>
|
|
+#include <linux/ioport.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/interrupt.h>
|
|
+#include <linux/kmod.h>
|
|
+#include <linux/vmalloc.h>
|
|
+#include <linux/init.h>
|
|
+#include <asm/io.h>
|
|
+#include <asm/page.h>
|
|
+#include <asm/irq.h>
|
|
+#include <asm/semaphore.h>
|
|
+#include <linux/miscdevice.h>
|
|
+
|
|
+//#define SW_DEBUG
|
|
+
|
|
+#include "camif.h"
|
|
+#include "videodev.h"
|
|
+#include "miscdevice.h"
|
|
+#include "cam_reg.h"
|
|
+#include "sensor.h"
|
|
+#include "userapp.h"
|
|
+
|
|
+
|
|
+/************************* Sharp Zarus API **************************
|
|
+* refering to Camera Driver API for SL-5000D/SL-5600 revision 1.00
|
|
+* April 11, 2002.
|
|
+ SW.LEE <hitchcar@sec.samsung.com>
|
|
+ I want to use Sharp Camera Application.
|
|
+*
|
|
+*/
|
|
+
|
|
+#define READ_MODE_STATUS 0x1
|
|
+#define READ_MODE_IMAGE 0x0
|
|
+#define CAPTURE_SPEED
|
|
+#define H_FLIP
|
|
+#define V_FLIP
|
|
+typedef enum sharp_readmode
|
|
+{
|
|
+ IMAGE = 0, STATUS = 1,
|
|
+ FASTER = 0, BETTER = 2,
|
|
+ XNOFLIP = 0, XFLIP = 4,
|
|
+ YNOFLIP = 0, YFLIP = 8,
|
|
+ AUTOMATICFLIP = -1
|
|
+} ReadMode_t;
|
|
+
|
|
+
|
|
+static struct sharp_param_t {
|
|
+ ReadMode_t readMode;
|
|
+ char CameraStatus[4];
|
|
+} sharp_param = { STATUS, {'s','m','c','A'}};
|
|
+
|
|
+
|
|
+camif_param_t qt_parm = { 640,480,240,320,16,0};
|
|
+
|
|
+static void setReadMode(const char *b,size_t count)
|
|
+{
|
|
+ int i = *(b+2) - 48 ;
|
|
+ if ( 4 == count ) {
|
|
+ i = (*(b+3) - 48) + i * 10;
|
|
+ }
|
|
+
|
|
+ // DPRINTK(" setReadMode %s conversion value %d \n",b , i);
|
|
+ if ( i & STATUS ) {
|
|
+ // DPRINTK(" STATUS MODE \n");
|
|
+ sharp_param.readMode = i;
|
|
+ }
|
|
+ else {
|
|
+ // DPRINTK(" IMAGE MODE \n");
|
|
+ sharp_param.readMode = i;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+extern ssize_t camif_p_read(struct file *, char *, size_t , loff_t *);
|
|
+
|
|
+ssize_t z_read(struct file *f, char *buf, size_t count, loff_t *pos)
|
|
+{
|
|
+ size_t end;
|
|
+
|
|
+ if (sharp_param.readMode & STATUS ) {
|
|
+ buf[0] = sharp_param.CameraStatus[0];
|
|
+ buf[1] = sharp_param.CameraStatus[1];
|
|
+ buf[2] = sharp_param.CameraStatus[2];
|
|
+ buf[3] = sharp_param.CameraStatus[3];
|
|
+ end = 4;
|
|
+ return end;
|
|
+ }
|
|
+ else { /* Image ReadMode */
|
|
+ /*
|
|
+ if (( sharp_param.readMode & (BETTER|X FLIP|YFLIP)))
|
|
+ DPRINTK(" Not Supporting BETTER|XFLIP|YFLIP\n");
|
|
+ */
|
|
+ return camif_p_read(f,buf,count,pos);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void z_config(camif_cfg_t *cfg,int x, int y)
|
|
+{
|
|
+ cfg->target_x = x;
|
|
+ cfg->target_y = y;
|
|
+ cfg->fmt = CAMIF_RGB16;
|
|
+ if (camif_dynamic_open(cfg)) {
|
|
+ panic(" Eror Happens \n");
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+ssize_t z_write(struct file *f, const char *b, size_t c, loff_t *pos)
|
|
+{
|
|
+ int array[5];
|
|
+ int zoom = 1;
|
|
+ camif_cfg_t *cfg;
|
|
+
|
|
+ cfg = get_camif(MINOR(f->f_dentry->d_inode->i_rdev));
|
|
+// DPRINTK(" param %s count %d \n",b, c );
|
|
+
|
|
+ switch(*b) {
|
|
+ case 'M':
|
|
+ setReadMode(b, c);
|
|
+ break;
|
|
+ case 'B': /* Clear the latch flag of shutter button */
|
|
+ DPRINTK(" clear latch flag of camera's shutter button\n");
|
|
+ sharp_param.CameraStatus[0]='s';
|
|
+ break;
|
|
+ case 'Y': /* I don't know how to set Shutter pressed */
|
|
+ DPRINTK(" set latch flag n");
|
|
+ sharp_param.CameraStatus[0]='S';
|
|
+ break;
|
|
+ case 'S': /* Camera Image Resolution */
|
|
+ case 'R': /* Donot support Rotation */
|
|
+ DPRINTK(" param %s count %d \n",b, c );
|
|
+ get_options((char *)(b+2), 5, array);
|
|
+ if ( array[3] == 512 ) zoom = 2;
|
|
+ z_config(cfg, array[1] * zoom , array[2] * zoom );
|
|
+ camif_4fsm_start(cfg);
|
|
+ break;
|
|
+ case 'C':
|
|
+ DPRINTK(" param %s count %d \n",b, c );
|
|
+ DPRINTK(" Start the camera to capture \n");
|
|
+ sharp_param.CameraStatus[2]='C';
|
|
+ camif_4fsm_start(cfg);
|
|
+ break;
|
|
+ default:
|
|
+ printk("Unexpected param %s count %d \n",b, c );
|
|
+ }
|
|
+
|
|
+ return c;
|
|
+}
|
|
+
|
|
diff --git a/arch/arm/mach-s3c2440/camera/qt.h b/arch/arm/mach-s3c2440/camera/qt.h
|
|
new file mode 100644
|
|
index 0000000..e58368a
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/qt.h
|
|
@@ -0,0 +1,18 @@
|
|
+/*
|
|
+ * SW.LEE <hitchcar@samsung.com>
|
|
+ *
|
|
+ * This file is subject to the terms and conditions of the GNU General Public
|
|
+ * License 2. See the file COPYING in the main directory of this archive
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+#ifndef __Z_API_H_
|
|
+#define __Z_API_H_
|
|
+
|
|
+extern ssize_t z_read(struct file *f, char *buf, size_t count, loff_t *pos);
|
|
+extern ssize_t z_write(struct file *f, const char *b, size_t c, loff_t *pos);
|
|
+
|
|
+
|
|
+
|
|
+#endif
|
|
+
|
|
diff --git a/arch/arm/mach-s3c2440/camera/s5x532.h b/arch/arm/mach-s3c2440/camera/s5x532.h
|
|
new file mode 100644
|
|
index 0000000..12725f4
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/s5x532.h
|
|
@@ -0,0 +1,143 @@
|
|
+/*
|
|
+ * 2004 (C) Samsung Electronics
|
|
+ * SW.LEE <hitchcar@sec.samsung.com>
|
|
+ * This file is subject to the terms and conditions of the GNU General Public
|
|
+ * License 2. See the file COPYING in the main directory of this archive
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+
|
|
+#ifndef _SMDK2440_S5X532_H_
|
|
+#define _SMDK2440_S5X532_H_
|
|
+
|
|
+
|
|
+#define CHIP_DELAY 0xFF
|
|
+
|
|
+typedef struct samsung_t{
|
|
+ unsigned char subaddr;
|
|
+ unsigned char value;
|
|
+ unsigned char page;
|
|
+} s5x532_t;
|
|
+
|
|
+s5x532_t s5x532_reg[] = {
|
|
+ // page 5
|
|
+ {0xec,0x05},
|
|
+ {0x08,0x55,0x5},
|
|
+ {0x0a,0x75,0x5},
|
|
+ {0x0c,0x90,0x5},
|
|
+ {0x0e,0x18,0x5},
|
|
+ {0x12,0x09,0x5},
|
|
+ {0x14,0x9d,0x5},
|
|
+ {0x16,0x90,0x5},
|
|
+ {0x1a,0x18,0x5},
|
|
+ {0x1c,0x0c,0x5},
|
|
+ {0x1e,0x09,0x5},
|
|
+ {0x20,0x06,0x5},
|
|
+ {0x22,0x20,0x5},
|
|
+ {0x2a,0x00,0x5},
|
|
+ {0x2d,0x04,0x5},
|
|
+ {0x12,0x24,0x5},
|
|
+ // page 3
|
|
+ {0xec,0x03,0x3},
|
|
+ {0x0c,0x09,0x3},
|
|
+ {0x6c,0x09,0x3},
|
|
+ {0x2b,0x10,0x3}, // momo clock inversion
|
|
+ // page 2
|
|
+ {0xec,0x02,0x2},
|
|
+ {0x03,0x09,0x2},
|
|
+ {0x05,0x08,0x2},
|
|
+ {0x06,0x01,0x2},
|
|
+ {0x07,0xf8,0x2},
|
|
+ {0x15,0x25,0x2},
|
|
+ {0x30,0x29,0x2},
|
|
+ {0x36,0x12,0x2},
|
|
+ {0x38,0x04,0x2},
|
|
+ {0x1b,0x77,0x2}, // 24MHz : 0x77, 12MHz : 0x22
|
|
+ {0x1c,0x77,0x2}, // 24MHz : 0x77, 12MHz : 0x22
|
|
+ // page 1
|
|
+ {0xec,0x01,0x1},
|
|
+ {0x00,0x03,0x1}, //
|
|
+ {0x0a,0x08,0x1}, // 0x0-QQVGA, 0x06-CIF, 0x02-QCIF, 0x08-VGA, 0x04-QVGA, 0x0a-SXGA
|
|
+ {0x0c,0x00,0x1}, // Pattern selectio. 0-CIS, 1-Color bar, 2-Ramp, 3-Blue screen
|
|
+ {0x10,0x27,0x1},
|
|
+ // 0x21-ITU-R656(CrYCbY), 0x25-ITU-R601(CrYCbY), 0x26-ITU-R601(YCbYCr)
|
|
+ {0x50,0x21,0x1}, // Hblank
|
|
+ {0x51,0x00,0x1}, // Hblank
|
|
+ {0x52,0xA1,0x1}, // Hblank
|
|
+ {0x53,0x02,0x1}, // Hblank
|
|
+ {0x54,0x01,0x1}, // Vblank
|
|
+ {0x55,0x00,0x1}, // Vblank
|
|
+ {0x56,0xE1,0x1}, // Vblank
|
|
+ {0x57,0x01,0x1}, // Vblank
|
|
+ {0x58,0x21,0x1}, // Hsync
|
|
+ {0x59,0x00,0x1}, // Hsync
|
|
+ {0x5a,0xA1,0x1}, // Hsync
|
|
+ {0x5b,0x02,0x1}, // Hsync
|
|
+ {0x5c,0x03,0x1}, // Vref
|
|
+ {0x5d,0x00,0x1}, // Vref
|
|
+ {0x5e,0x05,0x1}, // Vref
|
|
+ {0x5f,0x00,0x1}, // Vref
|
|
+ {0x70,0x0E,0x1},
|
|
+ {0x71,0xD6,0x1},
|
|
+ {0x72,0x30,0x1},
|
|
+ {0x73,0xDB,0x1},
|
|
+ {0x74,0x0E,0x1},
|
|
+ {0x75,0xD6,0x1},
|
|
+ {0x76,0x18,0x1},
|
|
+ {0x77,0xF5,0x1},
|
|
+ {0x78,0x0E,0x1},
|
|
+ {0x79,0xD6,0x1},
|
|
+ {0x7a,0x28,0x1},
|
|
+ {0x7b,0xE6,0x1},
|
|
+ {0x50,0x00,0x1},
|
|
+ {0x5c,0x00,0x1},
|
|
+
|
|
+ // page 0
|
|
+ {0xec,0x00,0x0},
|
|
+ {0x79,0x01,0x0},
|
|
+ {0x58,0x90,0x0},
|
|
+ {0x59,0xA0,0x0},
|
|
+ {0x5a,0x50,0x0},
|
|
+ {0x5b,0x70,0x0},
|
|
+ {0x5c,0xD0,0x0},
|
|
+ {0x5d,0xC0,0x0},
|
|
+ {0x5e,0x28,0x0},
|
|
+ {0x5f,0x08,0x0},
|
|
+ {0x50,0x90,0x0},
|
|
+ {0x51,0xA0,0x0},
|
|
+ {0x52,0x50,0x0},
|
|
+ {0x53,0x70,0x0},
|
|
+ {0x54,0xD0,0x0},
|
|
+ {0x55,0xC0,0x0},
|
|
+ {0x56,0x28,0x0},
|
|
+ {0x57,0x00,0x0},
|
|
+ {0x48,0x90,0x0},
|
|
+ {0x49,0xA0,0x0},
|
|
+ {0x4a,0x50,0x0},
|
|
+ {0x4b,0x70,0x0},
|
|
+ {0x4c,0xD0,0x0},
|
|
+ {0x4d,0xC0,0x0},
|
|
+ {0x4e,0x28,0x0},
|
|
+ {0x4f,0x08,0x0},
|
|
+ {0x72,0x82,0x0}, // main clock = 24MHz:0xd2, 16M:0x82, 12M:0x54
|
|
+ {0x75,0x05,0x0} // absolute vertical mirror. junon
|
|
+
|
|
+};
|
|
+
|
|
+
|
|
+#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
|
|
+#define S5X532_RISC_REGS 0xEB
|
|
+#define S5X532_ISP_REGS 0xFB /* S5C7323X */
|
|
+#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
|
|
+
|
|
+
|
|
+#define PAGE_ADDRESS 0xEC
|
|
+
|
|
+//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
|
|
+#define S5X532_REGS (0x1000)
|
|
+
|
|
+
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
diff --git a/arch/arm/mach-s3c2440/camera/s5x532_rev36.h b/arch/arm/mach-s3c2440/camera/s5x532_rev36.h
|
|
new file mode 100644
|
|
index 0000000..b662e9c
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/s5x532_rev36.h
|
|
@@ -0,0 +1,208 @@
|
|
+/*
|
|
+ * 2004 (C) Samsung Electronics
|
|
+ * SW.LEE <hitchcar@sec.samsung.com>
|
|
+ * This file is subject to the terms and conditions of the GNU General Public
|
|
+ * License 2. See the file COPYING in the main directory of this archive
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+
|
|
+#ifndef _SMDK2440_S5X532_H_
|
|
+#define _SMDK2440_S5X532_H_
|
|
+
|
|
+
|
|
+#define CHIP_DELAY 0xFF
|
|
+
|
|
+typedef struct samsung_t{
|
|
+ unsigned char subaddr;
|
|
+ unsigned char value;
|
|
+ unsigned char page;
|
|
+} s5x532_t;
|
|
+
|
|
+s5x532_t s5x532_reg[] = {
|
|
+
|
|
+ //=============== page0 ===============//
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x02,0x00,0x00},
|
|
+ {0x14,0x60,0x00},
|
|
+ {0x15,0x60,0x00},
|
|
+ {0x16,0x60,0x00},
|
|
+ {0x1b,0x20,0x00},
|
|
+ {0x1c,0x20,0x00},
|
|
+ {0x1d,0x20,0x00},
|
|
+ {0x1e,0x20,0x00},
|
|
+ {0x72,0xdc,0x00},
|
|
+ {0x73,0x11,0x00},
|
|
+ {0x76,0x82,0x00},
|
|
+ {0x77,0x90,0x00},
|
|
+ {0x78,0x6c,0x00},
|
|
+ {0x0a,0x02,0x00},
|
|
+ {0x34,0x0d,0x00},
|
|
+ {0x35,0x0a,0x00},
|
|
+ {0x36,0x05,0x00},
|
|
+ {0x37,0x05,0x00},
|
|
+ {0x38,0x06,0x00},
|
|
+ {0x39,0x08,0x00},
|
|
+ {0x3A,0x0d,0x00},
|
|
+ {0x3B,0x0d,0x00},
|
|
+ {0x3C,0x18,0x00},
|
|
+ {0x3D,0xE0,0x00},
|
|
+ {0x3E,0x20,0x00},
|
|
+ {0x66,0x02,0x00},
|
|
+ {0x6c,0x40,0x00},
|
|
+ {0x7c,0x01,0x00},
|
|
+ {0x0D,0x24,0x00},
|
|
+ {0x40,0x1B,0x00},
|
|
+ {0x41,0x4F,0x00},
|
|
+ {0x42,0x24,0x00},
|
|
+ {0x43,0x3E,0x00},
|
|
+ {0x44,0x32,0x00},
|
|
+ {0x45,0x30,0x00},
|
|
+ {0x48,0xa0,0x00},
|
|
+ {0x49,0xd0,0x00},
|
|
+ {0x4A,0x28,0x00},
|
|
+ {0x4B,0x7d,0x00},
|
|
+ {0x4C,0xd0,0x00},
|
|
+ {0x4D,0xe0,0x00},
|
|
+ {0x4E,0x1a,0x00},
|
|
+ {0x4F,0xa0,0x00},
|
|
+ {0x50,0xc0,0x00},
|
|
+ {0x51,0xc0,0x00},
|
|
+ {0x52,0x42,0x00},
|
|
+ {0x53,0x7e,0x00},
|
|
+ {0x54,0xc0,0x00},
|
|
+ {0x55,0xf0,0x00},
|
|
+ {0x56,0x1e,0x00},
|
|
+ {0x57,0xe0,0x00},
|
|
+ {0x58,0xc0,0x00},
|
|
+ {0x59,0xa0,0x00},
|
|
+ {0x5A,0x4a,0x00},
|
|
+ {0x5B,0x7e,0x00},
|
|
+ {0x5C,0xc0,0x00},
|
|
+ {0x5D,0xf0,0x00},
|
|
+ {0x5E,0x2a,0x00},
|
|
+ {0x5F,0x10,0x00},
|
|
+ {0x79,0x00,0x00},
|
|
+ {0x7a,0x00,0x00},
|
|
+ {0xe0,0x0f,0x00},
|
|
+ {0xe3,0x14,0x00},
|
|
+ {0xe5,0x48,0x00},
|
|
+ {0xe7,0x58,0x00},
|
|
+
|
|
+ //=============== page1 ===============//
|
|
+ {0xec,0x01,0x01},
|
|
+ {0x10,0x05,0x01},
|
|
+ {0x20,0xde,0x01},
|
|
+ {0x0b,0x06,0x01},
|
|
+ {0x30,0x00,0x01},
|
|
+ {0x31,0x00,0x01},
|
|
+ {0x32,0x00,0x01},
|
|
+ {0x24,0x28,0x01},
|
|
+ {0x25,0x3F,0x01},
|
|
+ {0x26,0x65,0x01},
|
|
+ {0x27,0xA1,0x01},
|
|
+ {0x28,0xFF,0x01},
|
|
+ {0x29,0x96,0x01},
|
|
+ {0x2A,0x85,0x01},
|
|
+ {0x2B,0xFF,0x01},
|
|
+ {0x2C,0x00,0x01},
|
|
+ {0x2D,0x1B,0x01},
|
|
+ {0xB0,0x28,0x01},
|
|
+ {0xB1,0x3F,0x01},
|
|
+ {0xB2,0x65,0x01},
|
|
+ {0xB3,0xA1,0x01},
|
|
+ {0xB4,0xFF,0x01},
|
|
+ {0xB5,0x96,0x01},
|
|
+ {0xB6,0x85,0x01},
|
|
+ {0xB7,0xFF,0x01},
|
|
+ {0xB8,0x00,0x01},
|
|
+ {0xB9,0x1B,0x01},
|
|
+ {0x15,0x15,0x01},
|
|
+ {0x18,0x85,0x01},
|
|
+ {0x1f,0x05,0x01},
|
|
+ {0x87,0x40,0x01},
|
|
+ {0x37,0x60,0x01},
|
|
+ {0x38,0xd5,0x01},
|
|
+ {0x48,0xa0,0x01},
|
|
+ {0x61,0x54,0x01},
|
|
+ {0x62,0x54,0x01},
|
|
+ {0x63,0x14,0x01},
|
|
+ {0x64,0x14,0x01},
|
|
+ {0x6d,0x12,0x01},
|
|
+ {0x78,0x09,0x01},
|
|
+ {0x79,0xD7,0x01},
|
|
+ {0x7A,0x14,0x01},
|
|
+ {0x7B,0xEE,0x01},
|
|
+
|
|
+ //=============== page2 ===============//
|
|
+ {0xec,0x02,0x02},
|
|
+ {0x2c,0x76,0x02},
|
|
+ {0x25,0x25,0x02},
|
|
+ {0x27,0x27,0x02},
|
|
+ {0x30,0x29,0x02},
|
|
+ {0x36,0x08,0x02},
|
|
+ {0x38,0x04,0x02},
|
|
+
|
|
+ //=============== page3 ===============//
|
|
+ {0xec,0x03,0x03},
|
|
+ {0x08,0x00,0x03},
|
|
+ {0x09,0x33,0x03},
|
|
+
|
|
+ //=============== page4 ===============//
|
|
+ {0xec,0x04,0x04},
|
|
+ {0x00,0x21,0x04},
|
|
+ {0x01,0x00,0x04},
|
|
+ {0x02,0x9d,0x04},
|
|
+ {0x03,0x02,0x04},
|
|
+ {0x04,0x04,0x04},
|
|
+ {0x05,0x00,0x04},
|
|
+ {0x06,0x1f,0x04},
|
|
+ {0x07,0x02,0x04},
|
|
+ {0x08,0x21,0x04},
|
|
+ {0x09,0x00,0x04},
|
|
+ {0x0a,0x9d,0x04},
|
|
+ {0x0b,0x02,0x04},
|
|
+ {0x0c,0x04,0x04},
|
|
+ {0x0d,0x00,0x04},
|
|
+ {0x0e,0x20,0x04},
|
|
+ {0x0f,0x02,0x04},
|
|
+ {0x1b,0x3c,0x04},
|
|
+ {0x1c,0x3c,0x04},
|
|
+
|
|
+ //=============== page5 ===============//
|
|
+ {0xec,0x05,0x05},
|
|
+ {0x1f,0x00,0x05},
|
|
+ {0x08,0x59,0x05},
|
|
+ {0x0a,0x71,0x05},
|
|
+ {0x1e,0x23,0x05},
|
|
+ {0x0e,0x3c,0x05},
|
|
+
|
|
+ //=============== page7 ===============//
|
|
+ {0xec,0x07,0x07},
|
|
+ {0x11,0xfe,0x07},
|
|
+
|
|
+ // added by junon
|
|
+ {0xec,0x01,0x07},
|
|
+ {0x10,0x26,0x07},
|
|
+ // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
|
|
+
|
|
+
|
|
+};
|
|
+
|
|
+
|
|
+#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
|
|
+#define S5X532_RISC_REGS 0xEB
|
|
+#define S5X532_ISP_REGS 0xFB /* S5C7323X */
|
|
+#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
|
|
+
|
|
+
|
|
+#define PAGE_ADDRESS 0xEC
|
|
+
|
|
+//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
|
|
+#define S5X532_REGS (0x1000)
|
|
+
|
|
+
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
diff --git a/arch/arm/mach-s3c2440/camera/sensor.h b/arch/arm/mach-s3c2440/camera/sensor.h
|
|
new file mode 100644
|
|
index 0000000..e28d01c
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/sensor.h
|
|
@@ -0,0 +1,20 @@
|
|
+/*
|
|
+ *
|
|
+ * Copyright (C) 2004 Samsung Electronics
|
|
+ * SW.LEE <hitchcar@sec.samsung.com>
|
|
+ *
|
|
+ * 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 __SENSOR_CMD_H_
|
|
+#define __SENSOR_CMD_H_
|
|
+
|
|
+#include "bits.h"
|
|
+
|
|
+#define SENSOR_INIT BIT0
|
|
+#define USER_ADD BIT1
|
|
+#define USER_EXIT BIT2
|
|
+
|
|
+#endif
|
|
diff --git a/arch/arm/mach-s3c2440/camera/sxga.h b/arch/arm/mach-s3c2440/camera/sxga.h
|
|
new file mode 100644
|
|
index 0000000..b41305a
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/sxga.h
|
|
@@ -0,0 +1,504 @@
|
|
+/*
|
|
+ * 2004 (C) Samsung Electronics
|
|
+ * SW.LEE <hitchcar@sec.samsung.com>
|
|
+ * This file is subject to the terms and conditions of the GNU General Public
|
|
+ * License 2. See the file COPYING in the main directory of this archive
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+
|
|
+#ifndef _SAMSUNG_SXGA_H_
|
|
+#define _SAMSUNG_SXGA_H_
|
|
+
|
|
+
|
|
+#define CHIP_DELAY 0xFF
|
|
+
|
|
+typedef struct samsung_t{
|
|
+ unsigned char subaddr;
|
|
+ unsigned char value;
|
|
+ unsigned char page;
|
|
+} s5x532_t;
|
|
+
|
|
+s5x532_t s5x532_reg[] = {
|
|
+ // page 0
|
|
+ {0xec,0x00,0x0},
|
|
+ {0x0c,0x38,0x0},
|
|
+ {0x0d,0x24,0x0},
|
|
+ {0x13,0x10,0x0},
|
|
+ {0x14,0x10,0x0},
|
|
+ {0x15,0x10,0x0},
|
|
+ {0x16,0x10,0x0},
|
|
+ {0x17,0x20,0x0},
|
|
+ {0x18,0x30,0x0},
|
|
+ {0x19,0x30,0x0},
|
|
+ {0x1a,0x10,0x0},
|
|
+ {0x1b,0x10,0x0},
|
|
+
|
|
+ {0x2d,0x40,0x0},
|
|
+ {0x3e,0x10,0x0},
|
|
+ {0x34,0x0a,0x0},
|
|
+ {0x39,0x04,0x0},
|
|
+ {0x3a,0x02,0x0},
|
|
+ {0x31,0x05,0x0},
|
|
+
|
|
+ {0x40,0x1d,0x0},
|
|
+ {0x41,0x50,0x0},
|
|
+ {0x42,0x24,0x0},
|
|
+ {0x43,0x3f,0x0},
|
|
+ {0x44,0x30,0x0},
|
|
+ {0x45,0x31,0x0},
|
|
+
|
|
+ {0x48,0xa0,0x0},
|
|
+ {0x49,0xc0,0x0},
|
|
+ {0x4a,0x58,0x0},
|
|
+ {0x4b,0x50,0x0},
|
|
+ {0x4c,0xb0,0x0},
|
|
+ {0x4d,0xc0,0x0},
|
|
+ {0x4e,0x30,0x0},
|
|
+ {0x4f,0x20,0x0},
|
|
+
|
|
+ {0x50,0xa0,0x0},
|
|
+ {0x51,0xc0,0x0},
|
|
+ {0x52,0x50,0x0},
|
|
+ {0x53,0x60,0x0},
|
|
+ {0x54,0xb0,0x0},
|
|
+ {0x55,0xc0,0x0},
|
|
+ {0x56,0x20,0x0},
|
|
+ {0x57,0x08,0x0},
|
|
+// {0x72,0x50,0x0}, // Clock 16
|
|
+ {0x72,0x78,0x0}, // Clock 24Mhz
|
|
+// {0x72,0xf0,0x0}, // Clock 48Mhz
|
|
+ // page 1
|
|
+ {0xec,0x01,0x1},
|
|
+ {0x10,0x17,0x1}, // ITU-R601
|
|
+ /*
|
|
+ [3:2] : out_sel
|
|
+ 00 : 656
|
|
+ 01 : 601
|
|
+ 10 : RGB
|
|
+ 11 : CIS
|
|
+ [1] : YC_SEL
|
|
+ [0] : CBCR_SEL
|
|
+ */
|
|
+
|
|
+ {0x0b,0x06,0x1}, // 6
|
|
+ {0x20,0xa8,0x1}, //b0); // Highlight C Supp 040215
|
|
+ {0x22,0x26,0x1}, //2f); 040225
|
|
+
|
|
+ {0x24,0x08,0x1}, //00); //1F); 040226
|
|
+ {0x25,0x10,0x1}, //10); //34);
|
|
+ {0x26,0x40,0x1}, //56);
|
|
+ {0x27,0x80,0x1}, //8D);
|
|
+ {0x28,0x2c,0x1}, //E7);
|
|
+ {0x29,0xd6,0x1}, //7C);
|
|
+ {0x2A,0x0c,0x1}, //70);
|
|
+ {0x2B,0xFF,0x1}, //FF);
|
|
+ {0x2C,0x00,0x1}, //00);
|
|
+ {0x2D,0x5f,0x1}, //1B);
|
|
+ //
|
|
+ {0xB0,0x08,0x1}, //00); //1F); 040226
|
|
+ {0xB1,0x10,0x1}, //10); //34);50
|
|
+ {0xB2,0x40,0x1}, //36);
|
|
+ {0xB3,0x80,0x1}, //6D);
|
|
+ {0xB4,0x2c,0x1}, //b7);
|
|
+ {0xB5,0xd6,0x1}, //7C);
|
|
+ {0xB6,0x0c,0x1}, //70);
|
|
+ {0xB7,0xFF,0x1}, //FF);
|
|
+ {0xB8,0x00,0x1}, //00);
|
|
+ {0xB9,0x5f,0x1}, //1B);
|
|
+
|
|
+
|
|
+ {0xc2,0x01,0x1}, // shading On
|
|
+ {0xc3,0x80,0x1},
|
|
+ {0xc4,0x02,0x1},
|
|
+ {0xc5,0x00,0x1},
|
|
+ {0xc6,0x01,0x1},
|
|
+ {0xc7,0x00,0x1},
|
|
+ {0xc8,0x05,0x1},
|
|
+ {0xc9,0x00,0x1},
|
|
+ {0xca,0x04,0x1},
|
|
+
|
|
+ // shading 5
|
|
+ {0xd0,0xb5,0x1},
|
|
+ {0xd1,0x9c,0x1},
|
|
+ {0xd2,0x8d,0x1},
|
|
+ {0xd3,0x84,0x1},
|
|
+ {0xd4,0x84,0x1},
|
|
+ {0xd5,0x91,0x1},
|
|
+ {0xd6,0xa0,0x1},
|
|
+ {0xd7,0xb5,0x1},
|
|
+
|
|
+ {0xd8,0xc0,0x1},
|
|
+ {0xd9,0xa6,0x1},
|
|
+ {0xda,0x93,0x1},
|
|
+ {0xdb,0x85,0x1},
|
|
+ {0xdc,0x85,0x1},
|
|
+ {0xdd,0x90,0x1},
|
|
+ {0xde,0xa0,0x1},
|
|
+ {0xdf,0xb8,0x1},
|
|
+
|
|
+ // Page 2
|
|
+ {0xec,0x02,0x02},
|
|
+
|
|
+ {0x2d,0x02,0x02},
|
|
+ {0x20,0x13,0x02},
|
|
+ {0x21,0x13,0x2},
|
|
+ {0x22,0x13,0x2},
|
|
+ {0x23,0x13,0x2},
|
|
+ {0x2e,0x85,0x2},
|
|
+ {0x2f,0x34,0x2},
|
|
+ {0x30,0x00,0x2},
|
|
+ {0x28,0x94,0x2},
|
|
+
|
|
+
|
|
+ // page 3
|
|
+ {0xec,0x03,0x03},
|
|
+ {0x10,0x00,0x3},
|
|
+ {0x20,0x00,0x3},
|
|
+ {0x21,0x20,0x3},
|
|
+ {0x22,0x00,0x3},
|
|
+ {0x23,0x00,0x3},
|
|
+ {0x40,0x20,0x3},
|
|
+ {0x41,0x20,0x3},
|
|
+ {0x42,0x20,0x3},
|
|
+ {0x43,0x20,0x3},
|
|
+ {0x60,0x00,0x3},
|
|
+ {0x61,0x00,0x3},
|
|
+ {0x62,0x00,0x3},
|
|
+ {0x63,0x00,0x3},
|
|
+ {0x64,0x04,0x3},
|
|
+ {0x65,0x1C,0x3},
|
|
+ {0x66,0x05,0x3},
|
|
+ {0x67,0x1C,0x3},
|
|
+ {0x68,0x00,0x3},
|
|
+ {0x69,0x2D,0x3},
|
|
+ {0x6a,0x00,0x3},
|
|
+ {0x6b,0x72,0x3},
|
|
+ {0x6c,0x00,0x3},
|
|
+ {0x6d,0x00,0x3},
|
|
+ {0x6e,0x16,0x3}, // 2.38
|
|
+ {0x6f,0x16,0x3}, // 2.38
|
|
+ {0x70,0x00,0x3},
|
|
+ {0x71,0x00,0x3},
|
|
+ {0x72,0x45,0x3},
|
|
+ {0x73,0x00,0x3},
|
|
+ {0x74,0x1C,0x3},
|
|
+ {0x75,0x05,0x3},
|
|
+
|
|
+ {0x80,0x00,0x3}, //for 0.02 _ 44
|
|
+ {0x81,0x00,0x3},
|
|
+ {0x82,0x00,0x3},
|
|
+ {0x83,0x00,0x3},
|
|
+ {0x84,0x04,0x3},
|
|
+ {0x85,0x1c,0x3},
|
|
+ {0x86,0x05,0x3},
|
|
+ {0x87,0x1c,0x3},
|
|
+ {0x88,0x00,0x3},
|
|
+ {0x89,0x2d,0x3},
|
|
+ {0x8a,0x00,0x3},
|
|
+ {0x8b,0xcc,0x3},
|
|
+ {0x8c,0x00,0x3},
|
|
+ {0x8d,0x00,0x3},
|
|
+ {0x8e,0x08,0x3},
|
|
+ {0x8f,0x08,0x3},
|
|
+ {0x90,0x01,0x3},
|
|
+ {0x91,0x00,0x3},
|
|
+ {0x92,0x91,0x3},
|
|
+ {0x93,0x00,0x3},
|
|
+ {0x94,0x88,0x3},
|
|
+ {0x95,0x02,0x3},
|
|
+
|
|
+
|
|
+
|
|
+ // page 4
|
|
+ {0xec,0x04,0x04},
|
|
+ {0x3f,0x09,0x04}, // VGA : old board :0x08 , new board ; 0X09
|
|
+ {0x18,0x00,0x04}, // sxga
|
|
+ {0x1c,0x41,0x04},
|
|
+ {0x20,0x41,0x04}, // vga center 040215
|
|
+ {0x22,0xc1,0x04},// a1);
|
|
+ {0x23,0x02,0x04},
|
|
+ {0x28,0x41,0x04},
|
|
+ {0x2a,0xc1,0x04},// a1);
|
|
+ {0x2b,0x02,0x04},
|
|
+
|
|
+ {0x3c,0x0b,0x04}, //f); // vga
|
|
+ {0x58,0x11,0x04},
|
|
+ {0x5c,0x14,0x04},
|
|
+ {0x60,0x21,0x04},
|
|
+ {0x61,0x00,0x04},
|
|
+ {0x62,0xB1,0x04},
|
|
+ {0x63,0x02,0x04},
|
|
+ {0x64,0x01,0x04},
|
|
+ {0x65,0x00,0x04},
|
|
+ {0x66,0x01,0x04},
|
|
+ {0x67,0x02,0x04},
|
|
+ {0x68,0x21,0x04},
|
|
+ {0x69,0x00,0x04},
|
|
+ {0x6a,0xB1,0x04},
|
|
+ {0x6b,0x02,0x04},
|
|
+ {0x6c,0x01,0x04},
|
|
+ {0x6d,0x00,0x04},
|
|
+ {0x6e,0x01,0x04},
|
|
+ {0x6f,0x02,0x04},
|
|
+ {0x70,0x2D,0x04},
|
|
+ {0x71,0x00,0x04},
|
|
+ {0x72,0xd3,0x04}, // 14
|
|
+ {0x73,0x05,0x04}, // 15
|
|
+ {0x74,0x1C,0x04},
|
|
+ {0x75,0x05,0x04},
|
|
+ {0x76,0x1b,0x04}, // HendL
|
|
+ {0x77,0x0b,0x04}, // HendH
|
|
+ {0x78,0x01,0x04}, // 5.00
|
|
+ {0x79,0x80,0x04}, // 5.2a
|
|
+ {0x7a,0x33,0x04},
|
|
+ {0x7b,0x00,0x04},
|
|
+ {0x7c,0x38,0x04}, // 5.0e
|
|
+ {0x7d,0x03,0x04},
|
|
+ {0x7e,0x00,0x04},
|
|
+ {0x7f,0x0A,0x04},
|
|
+
|
|
+ {0x80,0x2e,0x04},
|
|
+ {0x81,0x00,0x04},
|
|
+ {0x82,0xae,0x04},
|
|
+ {0x83,0x02,0x04},
|
|
+ {0x84,0x00,0x04},
|
|
+ {0x85,0x00,0x04},
|
|
+ {0x86,0x01,0x04},
|
|
+ {0x87,0x02,0x04},
|
|
+ {0x88,0x2e,0x04},
|
|
+ {0x89,0x00,0x04},
|
|
+ {0x8a,0xae,0x04},
|
|
+ {0x8b,0x02,0x04},
|
|
+ {0x8c,0x1c,0x04},
|
|
+ {0x8d,0x00,0x04},
|
|
+ {0x8e,0x04,0x04},
|
|
+ {0x8f,0x02,0x04},
|
|
+ {0x90,0x2d,0x04},
|
|
+ {0x91,0x00,0x04},
|
|
+ {0x92,0xa5,0x04},
|
|
+ {0x93,0x00,0x04},
|
|
+ {0x94,0x88,0x04},
|
|
+ {0x95,0x02,0x04},
|
|
+ {0x96,0xb3,0x04},
|
|
+ {0x97,0x06,0x04},
|
|
+ {0x98,0x01,0x04},
|
|
+ {0x99,0x00,0x04},
|
|
+ {0x9a,0x33,0x04},
|
|
+ {0x9b,0x30,0x04},
|
|
+ {0x9c,0x50,0x04},
|
|
+ {0x9d,0x30,0x04},
|
|
+ {0x9e,0x01,0x04},
|
|
+ {0x9f,0x08,0x04},
|
|
+
|
|
+ // page 5
|
|
+ {0xec,0x05,0x05},
|
|
+ {0x5a,0x22,0x05},
|
|
+
|
|
+ // page 6
|
|
+ {0xec,0x06,0x06},
|
|
+ {0x14,0x1e,0x06},
|
|
+ {0x15,0xb4,0x04},
|
|
+ {0x16,0x25,0x04},
|
|
+ {0x17,0x74,0x04},
|
|
+
|
|
+ {0x10,0x48,0x04},
|
|
+ {0x11,0xa0,0x04},
|
|
+ {0x12,0x40,0x04}, // 040216 AE1 window ÁÙÀÓ
|
|
+ {0x13,0x70,0x04},
|
|
+
|
|
+ {0x1a,0x29,0x04}, // 040217 AWB window ÁÙÀÓ
|
|
+ {0x30,0x40,0x04},
|
|
+ {0x31,0xa2,0x04},
|
|
+ {0x32,0x50,0x04},
|
|
+ {0x33,0xbc,0x04},
|
|
+ {0x34,0x10,0x04},
|
|
+ {0x35,0xd2,0x04},
|
|
+ {0x36,0x18,0x04},
|
|
+ {0x37,0xf5,0x04},
|
|
+ {0x38,0x10,0x04},
|
|
+ {0x39,0xd3,0x04},
|
|
+ {0x3a,0x1a,0x04},
|
|
+ {0x3b,0xf0,0x04},
|
|
+
|
|
+ // page 7
|
|
+ {0xec,0x07,0x07},
|
|
+ {0x08,0xff,0x7},
|
|
+ {0x38,0x01,0x7}, //07); 040315
|
|
+ {0x39,0x01,0x7}, //02); //4); 040223 040315
|
|
+ {0x11,0xfe,0x7}, //fe); // green -2 040303
|
|
+ {0x2a,0x20,0x7},
|
|
+ {0x2b,0x20,0x7},
|
|
+ {0x2c,0x10,0x7},
|
|
+ {0x2d,0x00,0x7},
|
|
+ {0x2e,0xf0,0x7},
|
|
+ {0x2f,0xd0,0x7},
|
|
+ {0x3a,0xf0,0x7},
|
|
+ {0x23,0x07,0x7}, // for ESD
|
|
+
|
|
+ // page 0
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x8a,0x04,0x00},
|
|
+
|
|
+ // page 1
|
|
+ {0xec,0x01,0x01},
|
|
+ {0xe5,0xb0,0x01},
|
|
+ {0xe5,0xb0,0x01},
|
|
+ {0xc2,0x01,0x01},
|
|
+
|
|
+ {0x61,0x7b,0x01},
|
|
+ {0x62,0x7b,0x01},
|
|
+ {0x63,0x1b,0x01},
|
|
+ {0x64,0x1b,0x01},
|
|
+
|
|
+ // page 0
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x7e,0x04,0x00},
|
|
+
|
|
+ // page 4
|
|
+ {0xec,0x04,0x04},
|
|
+ {0x04,0x02,0x04},
|
|
+ {0x06,0x02,0x04},
|
|
+
|
|
+ // page 1
|
|
+ {0xec,0x01,0x01},
|
|
+ {0x10,0x05,0x01},
|
|
+ {0x54,0x02,0x01},
|
|
+ {0x56,0x02,0x01},
|
|
+
|
|
+ // page 3
|
|
+ {0xec,0x03,0x03},
|
|
+ {0x0e,0x08,0x03},
|
|
+ {0x0f,0x08,0x03},
|
|
+
|
|
+ // page 4
|
|
+ {0xec,0x04,0x04},
|
|
+ {0x00,0x30,0x04},
|
|
+ {0x0a,0x30,0x04},
|
|
+
|
|
+ // page 5
|
|
+ {0xec,0x05,0x05},
|
|
+ {0x08,0x33,0x05},
|
|
+
|
|
+ // page 0
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x02,0x00,0x00},
|
|
+
|
|
+ // page 4
|
|
+//scale out
|
|
+ {0xec,0x04,0x04},
|
|
+ {0x02,0x20,0x04},
|
|
+ {0x1c,0x4f,0x04},
|
|
+
|
|
+ // page 1
|
|
+ {0xec,0x01,0x01},
|
|
+ {0x52,0x20,0x01},
|
|
+
|
|
+ // page 5
|
|
+ {0xec,0x05,0x05},
|
|
+ {0x0e,0x4f,0x05},
|
|
+
|
|
+//ae speed
|
|
+ // page 0
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x92,0x80,0x00},
|
|
+ {0x93,0x02,0x00},
|
|
+ {0x94,0x04,0x00},
|
|
+ {0x95,0x04,0x00},
|
|
+ {0x96,0x04,0x00},
|
|
+ {0x97,0x04,0x00},
|
|
+ {0x9b,0x47,0x00},
|
|
+
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x40,0x17,0x00},
|
|
+ {0x41,0x4c,0x00},
|
|
+ {0x42,0x1d,0x00},
|
|
+ {0x43,0x3e,0x00},
|
|
+ {0x44,0x2a,0x00},
|
|
+ {0x45,0x2d,0x00},
|
|
+
|
|
+ {0xec,0x01,0x01},
|
|
+ {0x20,0xd0,0x01}, //high light color reference
|
|
+
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x7e,0x00,0x00},
|
|
+ {0x73,0x11,0x00}, // 41
|
|
+ {0x78,0x78,0x00},
|
|
+
|
|
+ {0xec,0x07,0x07},
|
|
+ {0x1b,0x3e,0x07},
|
|
+
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x48,0xA0,0x00}, //s48C0
|
|
+ {0x49,0xB0,0x00}, //s49B0
|
|
+ {0x4a,0x30,0x00}, //s4a20
|
|
+ {0x4b,0x70,0x00}, //s4b70
|
|
+ {0x4c,0xD0,0x00}, //s4cA0
|
|
+ {0x4d,0xB0,0x00}, //s4dB0
|
|
+ {0x4e,0x30,0x00}, //s4e30
|
|
+ {0x4f,0xF0,0x00}, //s4fF0
|
|
+ {0x50,0xA0,0x00}, //s50D0
|
|
+ {0x51,0xB0,0x00}, //s51B0
|
|
+ {0x52,0x25,0x00}, //s5210
|
|
+ {0x53,0x70,0x00}, //s5370
|
|
+ {0x54,0xD0,0x00}, //s5490
|
|
+ {0x55,0xD0,0x00}, //s55B0
|
|
+ {0x56,0x3A,0x00}, //s5640
|
|
+ {0x57,0xD0,0x00}, //s57D0
|
|
+ {0x58,0xA0,0x00}, //s58D0
|
|
+ {0x59,0xA0,0x00}, //s59B0
|
|
+ {0x5a,0x32,0x00}, //s5a0A
|
|
+ {0x5b,0x7A,0x00}, //s5b7A
|
|
+ {0x5c,0xB0,0x00}, //s5c90
|
|
+ {0x5d,0xC0,0x00}, //s5dC0
|
|
+ {0x5e,0x3E,0x00}, //s5e4A
|
|
+ {0x5f,0xfa,0x00}, //s5fD0
|
|
+
|
|
+ // gamma
|
|
+ {0xec,0x01,0x01},
|
|
+ {0x24,0x31,0x01},
|
|
+ {0x25,0x4C,0x01},
|
|
+ {0x26,0x75,0x01},
|
|
+ {0x27,0xB5,0x01},
|
|
+ {0x28,0x17,0x01},
|
|
+ {0x29,0xAE,0x01},
|
|
+ {0x2A,0x97,0x01},
|
|
+ {0x2B,0xFF,0x01},
|
|
+ {0x2C,0x00,0x01},
|
|
+ {0x2D,0x5B,0x01},
|
|
+
|
|
+ {0xB0,0x31,0x01},
|
|
+ {0xB1,0x4C,0x01},
|
|
+ {0xB2,0x75,0x01},
|
|
+ {0xB3,0xB5,0x01},
|
|
+ {0xB4,0x17,0x01},
|
|
+ {0xB5,0xAE,0x01},
|
|
+ {0xB6,0x97,0x01},
|
|
+ {0xB7,0xFF,0x01},
|
|
+ {0xB8,0x00,0x01},
|
|
+ {0xB9,0x5B,0x01},
|
|
+
|
|
+ {0xec,0x00,0x00},
|
|
+ {0x77,0xb0,0x00},
|
|
+ {0x39,0x06,0x00},
|
|
+ {0x3a,0x08,0x00},
|
|
+
|
|
+};
|
|
+
|
|
+
|
|
+#define S5X532_INIT_REGS (sizeof(s5x532_reg)/sizeof(s5x532_reg[0]))
|
|
+#define S5X532_RISC_REGS 0xEB
|
|
+#define S5X532_ISP_REGS 0xFB /* S5C7323X */
|
|
+#define S5X532_CIS_REGS 0x2F /* S5K437LA03 */
|
|
+
|
|
+
|
|
+#define PAGE_ADDRESS 0xEC
|
|
+
|
|
+//#define S5X532_REGS (S5X532_RISC_REGS+S5X532_ISP_REGS+S5X532_CIS_REGS)
|
|
+#define S5X532_REGS (0x1000)
|
|
+
|
|
+
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
diff --git a/arch/arm/mach-s3c2440/camera/userapp.h b/arch/arm/mach-s3c2440/camera/userapp.h
|
|
new file mode 100644
|
|
index 0000000..9203378
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/userapp.h
|
|
@@ -0,0 +1,44 @@
|
|
+/*
|
|
+ Character Driver API Interface
|
|
+
|
|
+ Copyright (C) 2003 Samsung Electronics (SW.LEE: hitchcar@samsung.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.
|
|
+
|
|
+*/
|
|
+
|
|
+#ifndef __FIMC20_CAMIF_USR_APP_H_
|
|
+#define __FIMC20_CAMIF_USR_APP_H_
|
|
+
|
|
+
|
|
+/*
|
|
+ * IOCTL Command for Character Driver
|
|
+ */
|
|
+
|
|
+#define CMD_CAMERA_INIT 0x23
|
|
+/* Test Application Usage */
|
|
+typedef struct {
|
|
+ int src_x;
|
|
+ int src_y;
|
|
+ int dst_x;
|
|
+ int dst_y;
|
|
+ int bpp;
|
|
+ int flip;
|
|
+} camif_param_t;
|
|
+
|
|
+
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * tab-width: 8
|
|
+ * c-indent-level: 8
|
|
+ * c-basic-offset: 8
|
|
+ * c-set-style: "K&R"
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/v4l2_api.c b/arch/arm/mach-s3c2440/camera/v4l2_api.c
|
|
new file mode 100644
|
|
index 0000000..13aed36
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/v4l2_api.c
|
|
@@ -0,0 +1,311 @@
|
|
+/*
|
|
+ * . 2004-01-03: SW.LEE <hitchcar@sec.samsung.com>
|
|
+ *
|
|
+ * This file is subject to the terms and conditions of the GNU General Public
|
|
+ * License 2. See the file COPYING in the main directory of this archive
|
|
+ * for more details.
|
|
+ */
|
|
+
|
|
+#include <linux/config.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/irq.h>
|
|
+#include <linux/tqueue.h>
|
|
+#include <linux/locks.h>
|
|
+#include <linux/completion.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/vmalloc.h>
|
|
+#include <linux/miscdevice.h>
|
|
+#include <linux/wait.h>
|
|
+
|
|
+#include <asm/io.h>
|
|
+#include <asm/semaphore.h>
|
|
+#include <asm/hardware.h>
|
|
+#include <asm/uaccess.h>
|
|
+
|
|
+#include <asm/arch/cpu_s3c2440.h>
|
|
+#include <asm/arch/S3C2440.h>
|
|
+
|
|
+#include "camif.h"
|
|
+#include "videodev.h"
|
|
+
|
|
+/*
|
|
+ Codec_formats/Preview_format[0] must be same to initial value of
|
|
+ preview_init_param/codec_init_param
|
|
+*/
|
|
+
|
|
+const struct v4l2_fmtdesc codec_formats[] = {
|
|
+ {
|
|
+ .index = 0,
|
|
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
|
+// .flags = FORMAT_FLAGS_PLANAR,
|
|
+ .description = "4:2:2, planar, Y-Cb-Cr",
|
|
+ .pixelformat = V4L2_PIX_FMT_YUV422P,
|
|
+
|
|
+ },{
|
|
+ .index = 1,
|
|
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
|
+// .flags = FORMAT_FLAGS_PLANAR,
|
|
+ .name = "4:2:0, planar, Y-Cb-Cr",
|
|
+ .fourcc = V4L2_PIX_FMT_YUV420,
|
|
+ }
|
|
+};
|
|
+
|
|
+
|
|
+/* Todo
|
|
+ FIMC V4L2_PIX_FMT_RGB565 is not same to that of V4L2spec
|
|
+ and so we need image convert to FIMC V4l2_PIX_FMT_RGB565.
|
|
+*/
|
|
+const struct v4l2_fmtdesc preview_formats[] = {
|
|
+ {
|
|
+ .index = 1,
|
|
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
|
+ .description = "16 bpp RGB, le",
|
|
+ .fourcc = V4L2_PIX_FMT_RGB565,
|
|
+// .flags = FORMAT_FLAGS_PACKED,
|
|
+ },
|
|
+ {
|
|
+ .index = 0,
|
|
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
|
+// .flags = FORMAT_FLAGS_PACKED,
|
|
+ .description = "32 bpp RGB, le",
|
|
+ .fourcc = V4L2_PIX_FMT_BGR32,
|
|
+ }
|
|
+}
|
|
+
|
|
+#define NUM_F ARRARY_SIZE(preview_formats)
|
|
+
|
|
+
|
|
+/*
|
|
+ * This function and v4l2 structure made for V4L2 API functions
|
|
+ * App <--> v4l2 <--> logical param <--> hardware
|
|
+ */
|
|
+static int camif_get_v4l2(camif_cfg_t *cfg)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
|
|
+*/
|
|
+static int pixfmt2depth(int pixfmt,int *fmtptr)
|
|
+{
|
|
+ int fmt, depth;
|
|
+
|
|
+ switch (pixfmt) {
|
|
+ case V4L2_PIX_FMT_RGB565:
|
|
+ case V4L2_PIX_FMT_RGB565X:
|
|
+ fmt = CAMIF_RGB_16;
|
|
+ depth = 16;
|
|
+ break;
|
|
+ case V4L2_PIX_FMT_BGR24: /* Not tested */
|
|
+ case V4L2_PIX_FMT_RGB24:
|
|
+ fmt = CAMIF_RGB_24;
|
|
+ depth = 24;
|
|
+ break;
|
|
+ case V4L2_PIX_FMT_BGR32:
|
|
+ case V4L2_PIX_FMT_RGB32:
|
|
+ fmt = CAMIF_RGB_24;
|
|
+ depth 32;
|
|
+ break;
|
|
+ case V4L2_PIX_FMT_GREY: /* Not tested */
|
|
+ fmt = CAMIF_OUT_YCBCR420;
|
|
+ depth = 8;
|
|
+ break;
|
|
+ case V4L2_PIX_FMT_YUYV:
|
|
+ case V4L2_PIX_FMT_UYVY:
|
|
+ case V4L2_PIX_FMT_YUV422P:
|
|
+ fmt = CAMIF_OUT_YCBCR422;
|
|
+ depth = 16;
|
|
+ break;
|
|
+ case V4L2_PIX_FMT_YUV420:
|
|
+ fmt = CAMIF_OUT_YCBCR420;
|
|
+ depth = 12;
|
|
+ break;
|
|
+ }
|
|
+ if (fmtptr) *fmtptr = fmt;
|
|
+ return depth;
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+static int camif_s_v4l2(camif_cfg_t *cfg)
|
|
+{
|
|
+ int num = cfg->v2.used_fmt;
|
|
+
|
|
+ if ( !(cfg->v2.status&CAMIF_V4L2_INIT)) {
|
|
+ int depth;
|
|
+ int fourcc = v2.fmtdesc[num].pixelformat;
|
|
+
|
|
+ /* To define v4l2_fmtsdesc */
|
|
+ if (cfg->dma_type == CAMIF_CODEC)
|
|
+ cfg->v2->fmtdesc = codec_formats;
|
|
+ else
|
|
+ cfg->v2->fmtdesc = preview_formats;
|
|
+
|
|
+ /* To define v4l2_format used currently */
|
|
+ cfg->v2.fmt.width = cfg->target_x;
|
|
+ cfg->v2.fmt.height = cfg->target_y;
|
|
+ cfg->v2.fmt.field = V4L2_FIELD_NONE;
|
|
+ cfg->v2.fmt.pixelformat = fourcc;
|
|
+ depth = pixfmt2depth(fourcc,NULL);
|
|
+ cfg->v2.fmt.bytesperline= cfg->v2.fmt.width*depth >> 3;
|
|
+ cfg->v2.fmt.sizeimage =
|
|
+ cfg->v2.fmt.height * cfg->v2.fmt.bytesperline;
|
|
+
|
|
+ /* To define v4l2_input */
|
|
+ cfg->v2.input.index = 0;
|
|
+ if (cfg->dma_type == CAMIF_CODEC)
|
|
+ snprintf(cfg->v2.input.name, 31, "CAMIF CODEC");
|
|
+ else
|
|
+ snprintf(cfg->v2.input.name, 31, "CAMIF PREVIEW");
|
|
+ cfg->v2.input.type = V4L2_INPUT_TYPE_CAMERA;
|
|
+
|
|
+ /* Write the Status of v4l2 machine */
|
|
+ cfg->v2.status |= CAMIF_V4L2_INIT;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static int camif_g_fmt(camif_cfg_t *cfg, struct v4l2_format *f)
|
|
+{
|
|
+ int size = sizeof(struct v4l2_pix_format);
|
|
+
|
|
+ switch (f->type) {
|
|
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
|
+ memset(&f->fmt.pix,0,size);
|
|
+ memcpy(&f->fmt.pix,&cfg->v2.fmt,size);
|
|
+ return 0;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+/* Copy v4l2 parameter into other element of camif_cfg_t */
|
|
+static int camif_s_try(camif_cfg_t *cfg, int f)
|
|
+{
|
|
+ int fmt;
|
|
+ cfg->target_x = cfg->v2.fmt.width;
|
|
+ cfg->target_y = cfg->v2.fmt.height;
|
|
+ pixfmt2depth(cfg->v2.fmt.pixelformat,&fmt);
|
|
+ cfg->fmt = fmt;
|
|
+ camif_dynamic_conf(cfg);
|
|
+}
|
|
+
|
|
+
|
|
+static int camif_s_fmt(camif_cfg_t *cfg, struct v4l2_format *f)
|
|
+{
|
|
+ int retval;
|
|
+
|
|
+ switch (f->type) {
|
|
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
|
+ {
|
|
+ /* update our state informations */
|
|
+// down(&fh->cap.lock);
|
|
+ cfg->v2.fmt = f->pix;
|
|
+ cfg->v2.status |= CAMIF_v4L2_DIRTY;
|
|
+ camif_dynamic_conf(cfg);
|
|
+ cfg->v2.status &= ~CAMIF_v4L2_DIRTY; /* dummy ? */
|
|
+// up(&fh->cap.lock);
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+/* Refer ioctl of videodeX.c and bttv-driver.c */
|
|
+int camif_do_ioctl
|
|
+(struct inode *inode, struct file *file,unsigned int cmd, void * arg)
|
|
+{
|
|
+ camif_cfg_t *cfg = file->private_data;
|
|
+ int ret = 0;
|
|
+
|
|
+ switch (cmd) {
|
|
+ case VIDIOC_QUERYCAP:
|
|
+ {
|
|
+ struct v4l2_capability *cap = arg;
|
|
+
|
|
+ strcpy(cap->driver,"Fimc Camera");
|
|
+ strlcpy(cap->card,cfg->v->name,sizeof(cap->card));
|
|
+ sprintf(cap->bus_info,"FIMC 2.0 AHB Bus");
|
|
+ cap->version = 0;
|
|
+ cap->capabilities =
|
|
+ V4L2_CAP_VIDEO_CAPTURE |V4L2_CAP_READWRITE;
|
|
+ return 0;
|
|
+ }
|
|
+ case VIDIOC_G_FMT:
|
|
+ {
|
|
+ struct v4l2_format *f = arg;
|
|
+ return camif_g_fmt(cfg,f);
|
|
+ }
|
|
+ case VIDIOC_S_FMT:
|
|
+ {
|
|
+ struct v4l2_format *f = arg;
|
|
+ return camif_s_fmt(cfg,f);
|
|
+ }
|
|
+
|
|
+ case VIDIOC_ENUM_FMT:
|
|
+ {
|
|
+ struct v4l2_fmtdesc *f = arg;
|
|
+ enum v4l2_buf_type type = f->type;
|
|
+ int index = f->index;
|
|
+
|
|
+ if (index >= NUM_F)
|
|
+ return -EINVAL;
|
|
+ switch (f->type) {
|
|
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
|
+ break;
|
|
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
|
|
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ memset(f,0,sizeof(*f));
|
|
+ memcpy(f,cfg->v2.fmtdesc+index,sizeof(*f));
|
|
+ return 0;
|
|
+ }
|
|
+ case VIDIOC_G_INPUT:
|
|
+ {
|
|
+ u32 *i = arg;
|
|
+ *i = cfg->v2.input;
|
|
+ return 0;
|
|
+ }
|
|
+ case VIDIOC_S_INPUT:
|
|
+ {
|
|
+ int index = *((int *)arg);
|
|
+ if (index != 0)
|
|
+ return -EINVAL;
|
|
+ cfg->v2.input.index = index;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ default:
|
|
+ return -ENOIOCTLCMD; /* errno.h */
|
|
+ } /* End of Switch */
|
|
+
|
|
+
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * tab-width: 8
|
|
+ * c-indent-level: 8
|
|
+ * c-basic-offset: 8
|
|
+ * c-set-style: "K&R"
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/video-driver.c b/arch/arm/mach-s3c2440/camera/video-driver.c
|
|
new file mode 100644
|
|
index 0000000..fe9130c
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/video-driver.c
|
|
@@ -0,0 +1,591 @@
|
|
+/*
|
|
+ Copyright (C) 2004 Samsung Electronics
|
|
+ SW.LEE <hitchcar@sec.samsung.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.
|
|
+*/
|
|
+
|
|
+#include <linux/version.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/delay.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/fs.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/major.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/poll.h>
|
|
+#include <linux/signal.h>
|
|
+#include <linux/ioport.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/interrupt.h>
|
|
+#include <linux/kmod.h>
|
|
+#include <linux/vmalloc.h>
|
|
+#include <linux/init.h>
|
|
+#include <asm/io.h>
|
|
+#include <asm/page.h>
|
|
+#include <asm/irq.h>
|
|
+#include <asm/semaphore.h>
|
|
+#include <linux/miscdevice.h>
|
|
+
|
|
+//#define SW_DEBUG
|
|
+
|
|
+#include "camif.h"
|
|
+#include "videodev.h"
|
|
+#include "miscdevice.h"
|
|
+#include "cam_reg.h"
|
|
+#include "sensor.h"
|
|
+#include "userapp.h"
|
|
+
|
|
+#ifdef Z_API
|
|
+#include "qt.h"
|
|
+#endif
|
|
+
|
|
+/* Codec and Preview */
|
|
+#define CAMIF_NUM 2
|
|
+static camif_cfg_t fimc[CAMIF_NUM];
|
|
+
|
|
+static const char *driver_version =
|
|
+ "$Id: video-driver.c,v 1.9 2004/06/02 03:10:36 swlee Exp $";
|
|
+extern const char *fimc_version;
|
|
+extern const char *fsm_version;
|
|
+
|
|
+
|
|
+camif_cfg_t * get_camif(int nr)
|
|
+{
|
|
+ camif_cfg_t *ret = NULL;
|
|
+ switch(nr) {
|
|
+ case CODEC_MINOR:
|
|
+ ret = &fimc[0];
|
|
+ break;
|
|
+ case PREVIEW_MINOR:
|
|
+ ret = &fimc[1];
|
|
+ break;
|
|
+ default:
|
|
+ panic("Unknow Minor Number \n");
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+static int camif_codec_start(camif_cfg_t *cfg)
|
|
+{
|
|
+ int ret = 0;
|
|
+ ret =camif_check_preview(cfg);
|
|
+ switch(ret) {
|
|
+ case 0: /* Play alone */
|
|
+ DPRINTK("Start Alone \n");
|
|
+ camif_4fsm_start(cfg);
|
|
+ cfg->gc->status |= C_WORKING;
|
|
+ break;
|
|
+ case -ERESTARTSYS: /* Busy , retry */
|
|
+ //DPRINTK("Error \n");
|
|
+ printk("Error \n");
|
|
+ break;
|
|
+ case 1:
|
|
+ DPRINTK("need callback \n");
|
|
+ ret = camif_callback_start(cfg);
|
|
+ if(ret < 0 ) {
|
|
+ printk(KERN_INFO "Busy RESTART \n");
|
|
+ return ret; /* Busy, retry */
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+ssize_t camif_write (struct file *f, const char *b, size_t c,loff_t *offset)
|
|
+{
|
|
+ camif_cfg_t *cfg;
|
|
+
|
|
+ c = 0; /* return value */
|
|
+ DPRINTK("\n");
|
|
+ cfg = get_camif(MINOR(f->f_dentry->d_inode->i_rdev));
|
|
+ switch (*b) {
|
|
+ case 'O':
|
|
+ if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ if (cfg->gc->status & C_WORKING) {
|
|
+ camif_start_c_with_p(cfg,get_camif(CODEC_MINOR));
|
|
+ }
|
|
+ else {
|
|
+ camif_4fsm_start(cfg);
|
|
+ }
|
|
+ }
|
|
+ else{
|
|
+ c = camif_codec_start(cfg);
|
|
+ if(c < 0) c = 1; /* Error and neet to retry */
|
|
+ }
|
|
+
|
|
+ break;
|
|
+ case 'X':
|
|
+ camif_p_stop(cfg);
|
|
+ break;
|
|
+ default:
|
|
+ panic("CAMERA:camif_write: Unexpected Param\n");
|
|
+ }
|
|
+ DPRINTK("end\n");
|
|
+
|
|
+ return c;
|
|
+}
|
|
+
|
|
+
|
|
+ssize_t camif_p_read(struct file *file, char *buf, size_t count, loff_t *pos)
|
|
+{
|
|
+ camif_cfg_t *cfg = NULL;
|
|
+ size_t end;
|
|
+
|
|
+ cfg = get_camif(MINOR(file->f_dentry->d_inode->i_rdev));
|
|
+ cfg->status = CAMIF_STARTED;
|
|
+
|
|
+ if (wait_event_interruptible(cfg->waitq,cfg->status == CAMIF_INT_HAPPEN))
|
|
+ return -ERESTARTSYS;
|
|
+
|
|
+ cfg->status = CAMIF_STOPPED;
|
|
+ end = min_t(size_t, cfg->pp_totalsize /cfg->pp_num, count);
|
|
+ if (copy_to_user(buf, camif_g_frame(cfg), end))
|
|
+ return -EFAULT;
|
|
+
|
|
+ return end;
|
|
+}
|
|
+
|
|
+
|
|
+static ssize_t
|
|
+camif_c_read(struct file *file, char *buf, size_t count, loff_t *pos)
|
|
+{
|
|
+ camif_cfg_t *cfg = NULL;
|
|
+ size_t end;
|
|
+
|
|
+ /* cfg = file->private_data; */
|
|
+ cfg = get_camif(MINOR(file->f_dentry->d_inode->i_rdev));
|
|
+#if 0
|
|
+ if(file->f_flags & O_NONBLOCK) {
|
|
+ printk(KERN_ERR"Don't Support NON_BLOCK \n");
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ /* Change the below wait_event_interruptible func */
|
|
+ if (wait_event_interruptible(cfg->waitq,cfg->status == CAMIF_INT_HAPPEN))
|
|
+ return -ERESTARTSYS;
|
|
+ cfg->status = CAMIF_STOPPED;
|
|
+ end = min_t(size_t, cfg->pp_totalsize /cfg->pp_num, count);
|
|
+ if (copy_to_user(buf, camif_g_frame(cfg), end))
|
|
+ return -EFAULT;
|
|
+ return end;
|
|
+}
|
|
+
|
|
+
|
|
+static void camif_c_irq(int irq, void *dev_id, struct pt_regs *regs)
|
|
+{
|
|
+ camif_cfg_t *cfg = (camif_cfg_t *)dev_id;
|
|
+ DPRINTK("\n");
|
|
+ camif_g_fifo_status(cfg);
|
|
+ camif_g_frame_num(cfg);
|
|
+ if(camif_enter_c_4fsm(cfg) == INSTANT_SKIP) return;
|
|
+ wake_up_interruptible(&cfg->waitq);
|
|
+}
|
|
+
|
|
+static void camif_p_irq(int irq, void *dev_id, struct pt_regs * regs)
|
|
+{
|
|
+ camif_cfg_t *cfg = (camif_cfg_t *)dev_id;
|
|
+ DPRINTK("\n");
|
|
+ camif_g_fifo_status(cfg);
|
|
+ camif_g_frame_num(cfg);
|
|
+ if(camif_enter_p_4fsm(cfg) == INSTANT_SKIP) return;
|
|
+ wake_up_interruptible(&cfg->waitq);
|
|
+#if 0
|
|
+ if( (cfg->perf.frames % 5) == 0)
|
|
+ DPRINTK("5\n");
|
|
+#endif
|
|
+}
|
|
+
|
|
+static void camif_release_irq(camif_cfg_t *cfg)
|
|
+{
|
|
+ disable_irq(cfg->irq);
|
|
+ free_irq(cfg->irq, cfg);
|
|
+}
|
|
+
|
|
+static int camif_irq_request(camif_cfg_t *cfg)
|
|
+{
|
|
+ int ret = 0;
|
|
+
|
|
+ if (cfg->dma_type & CAMIF_CODEC) {
|
|
+ if ((ret = request_irq(cfg->irq, camif_c_irq,
|
|
+ SA_INTERRUPT,cfg->shortname, cfg))) {
|
|
+ printk("request_irq(CAM_C) failed.\n");
|
|
+ }
|
|
+ }
|
|
+ if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ if ((ret = request_irq(cfg->irq, camif_p_irq,
|
|
+ SA_INTERRUPT,cfg->shortname, cfg))) {
|
|
+ printk("request_irq(CAM_P) failed.\n");
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void camif_init_sensor(camif_cfg_t *cfg)
|
|
+{
|
|
+ camif_gc_t *gc = cfg->gc;
|
|
+ if (!gc->sensor)
|
|
+ panic("CAMERA:I2C Client(Img Sensor)Not registered\n");
|
|
+ if(!gc->init_sensor) {
|
|
+ camif_reset(gc->reset_type, gc->reset_udelay);
|
|
+ gc->sensor->driver->command(gc->sensor,SENSOR_INIT,NULL);
|
|
+ gc->init_sensor = 1; /*sensor init done */
|
|
+ }
|
|
+ gc->sensor->driver->command(gc->sensor, USER_ADD, NULL);
|
|
+}
|
|
+
|
|
+static int camif_open(struct inode *inode, struct file *file)
|
|
+{
|
|
+ int err;
|
|
+ camif_cfg_t * cfg = get_camif(MINOR(inode->i_rdev));
|
|
+
|
|
+ if(cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ if(down_interruptible(&cfg->gc->lock))
|
|
+ return -ERESTARTSYS;
|
|
+ if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ cfg->gc->status &= ~PNOTWORKING;
|
|
+ }
|
|
+ up(&cfg->gc->lock);
|
|
+ }
|
|
+ err = video_exclusive_open(inode,file);
|
|
+ cfg->gc->user++;
|
|
+ cfg->status = CAMIF_STOPPED;
|
|
+ if (err < 0) return err;
|
|
+ if (file->f_flags & O_NONCAP ) {
|
|
+ printk("Don't Support Non-capturing open \n");
|
|
+ return 0;
|
|
+ }
|
|
+ file->private_data = cfg;
|
|
+ camif_irq_request(cfg);
|
|
+ camif_init_sensor(cfg);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#if 0
|
|
+static void print_pregs(void)
|
|
+{
|
|
+ printk(" CISRCFMT 0x%08X \n", CISRCFMT);
|
|
+ printk(" CIWDOFST 0x%08X \n", CIWDOFST);
|
|
+ printk(" CIGCTRL 0x%08X \n", CIGCTRL);
|
|
+ printk(" CIPRTRGFMT 0x%08X \n", CIPRTRGFMT);
|
|
+ printk(" CIPRCTRL 0x%08X \n", CIPRCTRL);
|
|
+ printk(" CIPRSCPRERATIO 0x%08X \n", CIPRSCPRERATIO);
|
|
+ printk(" CIPRSCPREDST 0x%08X \n", CIPRSCPREDST);
|
|
+ printk(" CIPRSCCTRL 0x%08X \n", CIPRSCCTRL);
|
|
+ printk(" CIPRTAREA 0x%08X \n", CIPRTAREA);
|
|
+ printk(" CIPRSTATUS 0x%08X \n", CIPRSTATUS);
|
|
+ printk(" CIIMGCPT 0x%08X \n", CIIMGCPT);
|
|
+}
|
|
+
|
|
+static void print_cregs(void)
|
|
+{
|
|
+ printk(" CISRCFMT 0x%08X \n", CISRCFMT);
|
|
+ printk(" CIWDOFST 0x%08X \n", CIWDOFST);
|
|
+ printk(" CIGCTRL 0x%08X \n", CIGCTRL);
|
|
+ printk(" CICOCTRL 0x%8X \n", CICOCTRL);
|
|
+ printk(" CICOSCPRERATIO 0x%08X \n", CICOSCPRERATIO);
|
|
+ printk(" CICOSCPREDST 0x%08X \n", CICOSCPREDST);
|
|
+ printk(" CICOSCCTRL 0x%08X \n", CICOSCCTRL);
|
|
+ printk(" CICOTAREA 0x%08X \n", CICOTAREA);
|
|
+ printk(" CICOSTATUS 0x%8X \n", CICOSTATUS);
|
|
+ printk(" CIIMGCPT 0x%08X \n", CIIMGCPT);
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
+static int camif_release(struct inode *inode, struct file *file)
|
|
+{
|
|
+ camif_cfg_t * cfg = get_camif(MINOR(inode->i_rdev));
|
|
+
|
|
+ //DPRINTK(" cfg->status 0x%0X cfg->gc->status 0x%0X \n", cfg->status,cfg->gc->status );
|
|
+ if (cfg->dma_type & CAMIF_PREVIEW) {
|
|
+ if(down_interruptible(&cfg->gc->lock))
|
|
+ return -ERESTARTSYS;
|
|
+ cfg->gc->status &= ~PWANT2START;
|
|
+ cfg->gc->status |= PNOTWORKING;
|
|
+ up(&cfg->gc->lock);
|
|
+ }
|
|
+ else {
|
|
+ cfg->gc->status &= ~CWANT2START; /* No need semaphore */
|
|
+ }
|
|
+ camif_dynamic_close(cfg);
|
|
+ camif_release_irq(cfg);
|
|
+ video_exclusive_release(inode,file);
|
|
+ camif_p_stop(cfg);
|
|
+ cfg->gc->sensor->driver->command(cfg->gc->sensor, USER_EXIT, NULL);
|
|
+ cfg->gc->user--;
|
|
+ cfg->status = CAMIF_STOPPED;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void fimc_config(camif_cfg_t *cfg,u32 x, u32 y, int bpp)
|
|
+{
|
|
+ cfg->target_x = x;
|
|
+ cfg->target_y = y;
|
|
+
|
|
+ switch (bpp) {
|
|
+ case 16:
|
|
+ cfg->fmt = CAMIF_RGB16;
|
|
+ break;
|
|
+ case 24:
|
|
+ cfg->fmt = CAMIF_RGB24;
|
|
+ break;
|
|
+ case 420:
|
|
+ cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR420;
|
|
+ break;
|
|
+ case 422:
|
|
+ cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR422;
|
|
+ break;
|
|
+ default:
|
|
+ panic("Wrong BPP \n");
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+static int
|
|
+camif_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
|
|
+{
|
|
+ int ret = 0;
|
|
+ camif_cfg_t *cfg = file->private_data;
|
|
+ camif_param_t par;
|
|
+
|
|
+ switch (cmd) {
|
|
+ case CMD_CAMERA_INIT:
|
|
+ if (copy_from_user(&par,(camif_param_t *)arg,
|
|
+ sizeof(camif_param_t)))
|
|
+ return -EFAULT;
|
|
+ fimc_config(cfg,par.dst_x, par.dst_y, par.bpp);
|
|
+ if (camif_dynamic_open(cfg)) {
|
|
+ printk(" Eror Happens \n");
|
|
+ ret = -1;
|
|
+ }
|
|
+
|
|
+ switch (par.flip) {
|
|
+ case 3 :
|
|
+ cfg->flip = CAMIF_FLIP_MIRROR;
|
|
+ break;
|
|
+ case 1 :
|
|
+ cfg->flip = CAMIF_FLIP_X;
|
|
+ break;
|
|
+ case 2 :
|
|
+ cfg->flip = CAMIF_FLIP_Y;
|
|
+ break;
|
|
+ case 0 :
|
|
+ default:
|
|
+ cfg->flip = CAMIF_FLIP;
|
|
+ }
|
|
+ break;
|
|
+ /* Todo
|
|
+ case CMD_SENSOR_BRIGHTNESS:
|
|
+ cfg->gc->sensor->driver->command(cfg->gc->sensor, SENSOR_BRIGHTNESS, NULL);
|
|
+ break;
|
|
+ */
|
|
+ default:
|
|
+ ret = -EINVAL;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+#if 0
|
|
+static int camif_ioctl(struct inode *inode, struct file *file,
|
|
+ unsigned int cmd, unsigned long arg)
|
|
+{
|
|
+// camif_cfg_t *cfg = file->private_data;
|
|
+
|
|
+
|
|
+ switch (cmd) {
|
|
+/* case Some_other_action */
|
|
+ default:
|
|
+ return video_usercopy(inode, file, cmd, arg, camif_do_ioctl);
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+static struct file_operations camif_c_fops =
|
|
+{
|
|
+ .owner = THIS_MODULE,
|
|
+ .open = camif_open,
|
|
+ .release = camif_release,
|
|
+ .ioctl = camif_ioctl,
|
|
+ .read = camif_c_read,
|
|
+ .write = camif_write,
|
|
+};
|
|
+
|
|
+static struct file_operations camif_p_fops =
|
|
+{
|
|
+ .owner = THIS_MODULE,
|
|
+ .open = camif_open,
|
|
+ .release = camif_release,
|
|
+ .ioctl = camif_ioctl,
|
|
+#ifdef Z_API
|
|
+ .read = z_read,
|
|
+ .write = z_write,
|
|
+#else
|
|
+ .read = camif_p_read,
|
|
+ .write = camif_write,
|
|
+#endif
|
|
+};
|
|
+
|
|
+static struct video_device codec_template =
|
|
+{
|
|
+ .name = "CODEC_IF",
|
|
+ .type = VID_TYPE_CAPTURE|VID_TYPE_CLIPPING|VID_TYPE_SCALES,
|
|
+ .hardware = VID_HARDWARE_SAMSUNG_FIMC20,
|
|
+ .fops = &camif_c_fops,
|
|
+// .release = camif_release
|
|
+ .minor = -1,
|
|
+};
|
|
+
|
|
+static struct video_device preview_template =
|
|
+{
|
|
+ .name = "PREVIEW_IF",
|
|
+ .type = VID_TYPE_CAPTURE|VID_TYPE_CLIPPING|VID_TYPE_SCALES,
|
|
+ .hardware = VID_HARDWARE_SAMSUNG_FIMC20,
|
|
+ .fops = &camif_p_fops,
|
|
+ .minor = -1,
|
|
+};
|
|
+
|
|
+static int preview_init(camif_cfg_t *cfg)
|
|
+{
|
|
+ char name[16]="CAM_PREVIEW";
|
|
+
|
|
+ memset(cfg, 0, sizeof(camif_cfg_t));
|
|
+ cfg->target_x = 640;
|
|
+ cfg->target_y = 480;
|
|
+ cfg->pp_num = 4;
|
|
+ cfg->dma_type = CAMIF_PREVIEW;
|
|
+ cfg->fmt = CAMIF_RGB16;
|
|
+ cfg->flip = CAMIF_FLIP_Y;
|
|
+ cfg->v = &preview_template;
|
|
+ init_MUTEX(&cfg->v->lock);
|
|
+ cfg->irq = IRQ_CAM_P;
|
|
+
|
|
+ strcpy(cfg->shortname,name);
|
|
+ init_waitqueue_head(&cfg->waitq);
|
|
+ cfg->status = CAMIF_STOPPED;
|
|
+ return cfg->status;
|
|
+}
|
|
+
|
|
+static int codec_init(camif_cfg_t *cfg)
|
|
+{
|
|
+ char name[16]="CAM_CODEC";
|
|
+
|
|
+ memset(cfg, 0, sizeof(camif_cfg_t));
|
|
+ cfg->target_x = 176;
|
|
+ cfg->target_y = 144;
|
|
+ cfg->pp_num = 4;
|
|
+ cfg->dma_type = CAMIF_CODEC;
|
|
+ cfg->fmt = CAMIF_IN_YCBCR422|CAMIF_OUT_YCBCR420;
|
|
+ cfg->flip = CAMIF_FLIP_X;
|
|
+ cfg->v = &codec_template;
|
|
+ init_MUTEX(&cfg->v->lock);
|
|
+ cfg->irq = IRQ_CAM_C;
|
|
+ strcpy(cfg->shortname,name);
|
|
+ init_waitqueue_head(&cfg->waitq);
|
|
+ cfg->status = CAMIF_STOPPED;
|
|
+ return cfg->status;
|
|
+}
|
|
+
|
|
+static void camif_init(void)
|
|
+{
|
|
+ camif_setup_sensor();
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+static void print_version(void)
|
|
+{
|
|
+ printk(KERN_INFO"FIMC built:"__DATE__ " "__TIME__"\n%s\n%s\n%s\n",
|
|
+ fimc_version, driver_version,fsm_version);
|
|
+}
|
|
+
|
|
+
|
|
+static int camif_m_in(void)
|
|
+{
|
|
+ int ret = 0;
|
|
+ camif_cfg_t * cfg;
|
|
+
|
|
+ camif_init();
|
|
+ cfg = get_camif(CODEC_MINOR);
|
|
+ codec_init(cfg);
|
|
+
|
|
+ if (video_register_device(cfg->v,0,CODEC_MINOR)!=0) {
|
|
+ DPRINTK("Couldn't register codec driver.\n");
|
|
+ return 0;
|
|
+ }
|
|
+ cfg = get_camif(PREVIEW_MINOR);
|
|
+ preview_init(cfg);
|
|
+ if (video_register_device(cfg->v,0,PREVIEW_MINOR)!=0) {
|
|
+ DPRINTK("Couldn't register preview driver.\n");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ print_version();
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static void unconfig_device(camif_cfg_t *cfg)
|
|
+{
|
|
+ video_unregister_device(cfg->v);
|
|
+ camif_hw_close(cfg);
|
|
+ //memset(cfg, 0, sizeof(camif_cfg_t));
|
|
+}
|
|
+
|
|
+static void camif_m_out(void) /* module out */
|
|
+{
|
|
+ camif_cfg_t *cfg;
|
|
+
|
|
+ cfg = get_camif(CODEC_MINOR);
|
|
+ unconfig_device(cfg);
|
|
+ cfg = get_camif(PREVIEW_MINOR);
|
|
+ unconfig_device(cfg);
|
|
+ return;
|
|
+}
|
|
+
|
|
+void camif_register_decoder(struct i2c_client *ptr)
|
|
+{
|
|
+ camif_cfg_t *cfg;
|
|
+
|
|
+ cfg =get_camif(CODEC_MINOR);
|
|
+ cfg->gc = (camif_gc_t *)(ptr->data);
|
|
+
|
|
+ cfg =get_camif(PREVIEW_MINOR);
|
|
+ cfg->gc = (camif_gc_t *)(ptr->data);
|
|
+
|
|
+ sema_init(&cfg->gc->lock,1); /* global lock for both Codec and Preview */
|
|
+ cfg->gc->status |= PNOTWORKING; /* Default Value */
|
|
+ camif_hw_open(cfg->gc);
|
|
+}
|
|
+
|
|
+void camif_unregister_decoder(struct i2c_client *ptr)
|
|
+{
|
|
+ camif_gc_t *gc;
|
|
+
|
|
+ gc = (camif_gc_t *)(ptr->data);
|
|
+ gc->init_sensor = 0; /* need to modify */
|
|
+}
|
|
+
|
|
+module_init(camif_m_in);
|
|
+module_exit(camif_m_out);
|
|
+
|
|
+EXPORT_SYMBOL(camif_register_decoder);
|
|
+EXPORT_SYMBOL(camif_unregister_decoder);
|
|
+
|
|
+MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
|
|
+MODULE_DESCRIPTION("Video-Driver For Fimc2.0 MISC Drivers");
|
|
+MODULE_LICENSE("GPL");
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * c-basic-offset: 8
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/videodev.c b/arch/arm/mach-s3c2440/camera/videodev.c
|
|
new file mode 100644
|
|
index 0000000..0b3498f
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/videodev.c
|
|
@@ -0,0 +1,342 @@
|
|
+/*
|
|
+ * Video capture interface for Linux Character Device Driver.
|
|
+ * based on
|
|
+ * Alan Cox, <alan@redhat.com> video4linux
|
|
+ *
|
|
+ * Author: SW.LEE <hitchcar@samsung.com>
|
|
+ * 2004 (C) Samsung Electronics
|
|
+ * Modified for S3C2440/S3C24A0 Interface
|
|
+ *
|
|
+ * This file is released under the GPLv2
|
|
+ */
|
|
+
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/smp_lock.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/errno.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/kmod.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/devfs_fs_kernel.h>
|
|
+#include <linux/miscdevice.h>
|
|
+#include <asm/uaccess.h>
|
|
+#include <asm/system.h>
|
|
+#include <asm/semaphore.h>
|
|
+
|
|
+
|
|
+
|
|
+#include "camif.h"
|
|
+#include "videodev.h"
|
|
+#include "miscdevice.h"
|
|
+
|
|
+
|
|
+static DECLARE_MUTEX(videodev_lock);
|
|
+
|
|
+const char *fimc_version = "$Id: videodev.c,v 1.1.1.1 2004/04/27 03:52:50 swlee Exp $";
|
|
+
|
|
+#define VIDEO_NAME "video4linux"
|
|
+
|
|
+
|
|
+static inline unsigned iminor(struct inode *inode)
|
|
+{
|
|
+ return MINOR(inode->i_rdev);
|
|
+}
|
|
+
|
|
+static inline unsigned imajor(struct inode *inode)
|
|
+{
|
|
+ return MAJOR(inode->i_rdev);
|
|
+}
|
|
+
|
|
+
|
|
+#define VIDEO_NUM_DEVICES 2
|
|
+static struct video_device *video_device[VIDEO_NUM_DEVICES];
|
|
+
|
|
+static inline struct video_device * get_vd(int nr)
|
|
+{
|
|
+ if ( nr == CODEC_MINOR)
|
|
+ return video_device[0];
|
|
+ else {
|
|
+ assert ( nr & PREVIEW_MINOR);
|
|
+ return video_device[1];
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline void set_vd ( struct video_device * vd, int nr)
|
|
+{
|
|
+ if ( nr == CODEC_MINOR)
|
|
+ video_device[0] = vd;
|
|
+ else {
|
|
+ assert ( nr & PREVIEW_MINOR);
|
|
+ video_device[1] = vd;
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline int video_release(struct inode *inode, struct file *f)
|
|
+{
|
|
+ int minor = MINOR(inode->i_rdev);
|
|
+ struct video_device *vfd;
|
|
+
|
|
+ vfd = get_vd(minor);
|
|
+#if 1 /* needed until all drivers are fixed */
|
|
+ if (!vfd->release)
|
|
+ return 0;
|
|
+#endif
|
|
+ vfd->release(vfd);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+struct video_device* video_devdata(struct file *file)
|
|
+{
|
|
+ return video_device[iminor(file->f_dentry->d_inode)];
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * Open a video device.
|
|
+ */
|
|
+static int video_open(struct inode *inode, struct file *file)
|
|
+{
|
|
+ int minor = MINOR(inode->i_rdev);
|
|
+ int err = 0;
|
|
+ struct video_device *vfl;
|
|
+ struct file_operations *old_fops;
|
|
+
|
|
+ down(&videodev_lock);
|
|
+
|
|
+ vfl = get_vd(minor);
|
|
+
|
|
+ old_fops = file->f_op;
|
|
+ file->f_op = fops_get(vfl->fops);
|
|
+ if(file->f_op->open)
|
|
+ err = file->f_op->open(inode,file);
|
|
+ if (err) {
|
|
+ fops_put(file->f_op);
|
|
+ file->f_op = fops_get(old_fops);
|
|
+ }
|
|
+ fops_put(old_fops);
|
|
+ up(&videodev_lock);
|
|
+ return err;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * open/release helper functions -- handle exclusive opens
|
|
+ */
|
|
+extern int video_exclusive_open(struct inode *inode, struct file *file)
|
|
+{
|
|
+ struct video_device *vfl = get_vd(MINOR(inode->i_rdev));
|
|
+ int retval = 0;
|
|
+
|
|
+ down(&vfl->lock);
|
|
+ if (vfl->users) {
|
|
+ retval = -EBUSY;
|
|
+ } else {
|
|
+ vfl->users++;
|
|
+ }
|
|
+ up(&vfl->lock);
|
|
+ return retval;
|
|
+}
|
|
+
|
|
+extern int video_exclusive_release(struct inode *inode, struct file *file)
|
|
+{
|
|
+ struct video_device *vfl = get_vd(MINOR(inode->i_rdev));
|
|
+ vfl->users--;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+video_usercopy(struct inode *inode, struct file *file,
|
|
+ unsigned int cmd, unsigned long arg,
|
|
+ int (*func)(struct inode *inode, struct file *file,
|
|
+ unsigned int cmd, void *arg))
|
|
+{
|
|
+ char sbuf[128];
|
|
+ void *mbuf = NULL;
|
|
+ void *parg = NULL;
|
|
+ int err = -EINVAL;
|
|
+
|
|
+ // cmd = video_fix_command(cmd);
|
|
+
|
|
+ /* Copy arguments into temp kernel buffer */
|
|
+ switch (_IOC_DIR(cmd)) {
|
|
+ case _IOC_NONE:
|
|
+ parg = (void *)arg;
|
|
+ break;
|
|
+ case _IOC_READ:
|
|
+ case _IOC_WRITE:
|
|
+ case (_IOC_WRITE | _IOC_READ):
|
|
+ if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
|
|
+ parg = sbuf;
|
|
+ } else {
|
|
+ /* too big to allocate from stack */
|
|
+ mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
|
|
+ if (NULL == mbuf)
|
|
+ return -ENOMEM;
|
|
+ parg = mbuf;
|
|
+ }
|
|
+
|
|
+ err = -EFAULT;
|
|
+ if (_IOC_DIR(cmd) & _IOC_WRITE)
|
|
+ if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd)))
|
|
+ goto out;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* call driver */
|
|
+ err = func(inode, file, cmd, parg);
|
|
+ if (err == -ENOIOCTLCMD)
|
|
+ err = -EINVAL;
|
|
+ if (err < 0)
|
|
+ goto out;
|
|
+
|
|
+ /* Copy results into user buffer */
|
|
+ switch (_IOC_DIR(cmd))
|
|
+ {
|
|
+ case _IOC_READ:
|
|
+ case (_IOC_WRITE | _IOC_READ):
|
|
+ if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd)))
|
|
+ err = -EFAULT;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+out:
|
|
+ if (mbuf)
|
|
+ kfree(mbuf);
|
|
+ return err;
|
|
+}
|
|
+
|
|
+
|
|
+static struct file_operations video_fops=
|
|
+{
|
|
+ .owner = THIS_MODULE,
|
|
+ .llseek = no_llseek,
|
|
+ .open = video_open,
|
|
+ .release = video_release,
|
|
+};
|
|
+
|
|
+static struct miscdevice codec_dev = {
|
|
+ minor: CODEC_MINOR,
|
|
+ name : "codec",
|
|
+ fops : &video_fops
|
|
+};
|
|
+
|
|
+static struct miscdevice preview_dev = {
|
|
+ minor: PREVIEW_MINOR,
|
|
+ name : "preview",
|
|
+ fops : &video_fops
|
|
+};
|
|
+
|
|
+
|
|
+/**
|
|
+ * video_register_device - register video4linux devices
|
|
+ * @vfd: video device structure we want to register
|
|
+ * @type: type of device to register
|
|
+ * @nr: minor number
|
|
+ *
|
|
+ * Zero is returned on success.
|
|
+ * type : ignored.
|
|
+ * nr :
|
|
+ * 0 Codec index
|
|
+ * 1 Preview index
|
|
+ */
|
|
+int video_register_device(struct video_device *vfd, int type, int nr)
|
|
+{
|
|
+ int ret=0;
|
|
+
|
|
+ /* pick a minor number */
|
|
+ down(&videodev_lock);
|
|
+ set_vd (vfd, nr);
|
|
+ vfd->minor=nr;
|
|
+ up(&videodev_lock);
|
|
+
|
|
+ switch (vfd->minor) {
|
|
+ case CODEC_MINOR:
|
|
+ ret = misc_register(&codec_dev);
|
|
+ if (ret) {
|
|
+ printk(KERN_ERR
|
|
+ "can't misc_register : codec on minor=%d\n", CODEC_MINOR);
|
|
+ panic(" Give me misc codec \n");
|
|
+ }
|
|
+ break;
|
|
+ case PREVIEW_MINOR:
|
|
+ ret = misc_register(&preview_dev);
|
|
+ if (ret) {
|
|
+ printk(KERN_ERR
|
|
+ "can't misc_register (preview) on minor=%d\n", PREVIEW_MINOR);
|
|
+ panic(" Give me misc codec \n");
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+#if 0 /* needed until all drivers are fixed */
|
|
+ if (!vfd->release)
|
|
+ printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
|
|
+ "Please fix your driver for proper sysfs support, see "
|
|
+ "http://lwn.net/Articles/36850/\n", vfd->name);
|
|
+#endif
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * video_unregister_device - unregister a video4linux device
|
|
+ * @vfd: the device to unregister
|
|
+ *
|
|
+ * This unregisters the passed device and deassigns the minor
|
|
+ * number. Future open calls will be met with errors.
|
|
+ */
|
|
+
|
|
+void video_unregister_device(struct video_device *vfd)
|
|
+{
|
|
+ down(&videodev_lock);
|
|
+
|
|
+ if(get_vd(vfd->minor)!=vfd)
|
|
+ panic("videodev: bad unregister");
|
|
+
|
|
+ if (vfd->minor== CODEC_MINOR)
|
|
+ misc_deregister(&codec_dev);
|
|
+ else
|
|
+ misc_deregister(&preview_dev);
|
|
+ set_vd (NULL, vfd->minor);
|
|
+ up(&videodev_lock);
|
|
+}
|
|
+
|
|
+
|
|
+/*
|
|
+ * Initialise video for linux
|
|
+ */
|
|
+
|
|
+static int __init videodev_init(void)
|
|
+{
|
|
+// printk(KERN_INFO "FIMC2.0 Built:"__DATE__" "__TIME__"\n%s\n",fimc_version);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void __exit videodev_exit(void)
|
|
+{
|
|
+}
|
|
+
|
|
+module_init(videodev_init)
|
|
+module_exit(videodev_exit)
|
|
+
|
|
+EXPORT_SYMBOL(video_register_device);
|
|
+EXPORT_SYMBOL(fimc_version);
|
|
+EXPORT_SYMBOL(video_unregister_device);
|
|
+EXPORT_SYMBOL(video_usercopy);
|
|
+EXPORT_SYMBOL(video_exclusive_open);
|
|
+EXPORT_SYMBOL(video_exclusive_release);
|
|
+
|
|
+
|
|
+MODULE_AUTHOR("SW.LEE <hitchcar@sec.samsung.com>");
|
|
+MODULE_DESCRIPTION("VideoDev For FIMC2.0 MISC Drivers");
|
|
+MODULE_LICENSE("GPL");
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * c-basic-offset: 8
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/videodev.h b/arch/arm/mach-s3c2440/camera/videodev.h
|
|
new file mode 100644
|
|
index 0000000..f12db43
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/videodev.h
|
|
@@ -0,0 +1,110 @@
|
|
+#ifndef __LINUX_S3C_VIDEODEV_H
|
|
+#define __LINUX_S3C_VIDEODEV_H
|
|
+
|
|
+#include <linux/types.h>
|
|
+#include <linux/version.h>
|
|
+#include "videodev2.h"
|
|
+
|
|
+
|
|
+struct video_device
|
|
+{
|
|
+ /* device info */
|
|
+ // struct device *dev;
|
|
+ char name[32];
|
|
+ int type; /* v4l1 */
|
|
+ int type2; /* v4l2 */
|
|
+ int hardware;
|
|
+ int minor;
|
|
+
|
|
+ /* device ops + callbacks */
|
|
+ struct file_operations *fops;
|
|
+ void (*release)(struct video_device *vfd);
|
|
+
|
|
+
|
|
+#if 1 /* to be removed in 2.7.x */
|
|
+ /* obsolete -- fops->owner is used instead */
|
|
+ struct module *owner;
|
|
+ /* dev->driver_data will be used instead some day.
|
|
+ * Use the video_{get|set}_drvdata() helper functions,
|
|
+ * so the switch over will be transparent for you.
|
|
+ * Or use {pci|usb}_{get|set}_drvdata() directly. */
|
|
+ void *priv;
|
|
+#endif
|
|
+
|
|
+ /* for videodev.c intenal usage -- please don't touch */
|
|
+ int users; /* video_exclusive_{open|close} ... */
|
|
+ struct semaphore lock; /* ... helper function uses these */
|
|
+ char devfs_name[64]; /* devfs */
|
|
+ // struct class_device class_dev; /* sysfs */
|
|
+};
|
|
+
|
|
+#define VIDEO_MAJOR 81
|
|
+
|
|
+#define VFL_TYPE_GRABBER 0
|
|
+
|
|
+
|
|
+extern int video_register_device(struct video_device *, int type, int nr);
|
|
+extern void video_unregister_device(struct video_device *);
|
|
+extern struct video_device* video_devdata(struct file*);
|
|
+
|
|
+
|
|
+
|
|
+struct video_picture
|
|
+{
|
|
+ __u16 brightness;
|
|
+ __u16 hue;
|
|
+ __u16 colour;
|
|
+ __u16 contrast;
|
|
+ __u16 whiteness; /* Black and white only */
|
|
+ __u16 depth; /* Capture depth */
|
|
+ __u16 palette; /* Palette in use */
|
|
+#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
|
|
+#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
|
|
+#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
|
|
+#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
|
|
+#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
|
|
+#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
|
|
+#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
|
|
+#define VIDEO_PALETTE_YUYV 8
|
|
+#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
|
|
+#define VIDEO_PALETTE_YUV420 10
|
|
+#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
|
|
+#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
|
|
+#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
|
|
+#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
|
|
+#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
|
|
+#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
|
|
+#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
|
|
+#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
|
|
+};
|
|
+
|
|
+extern int video_exclusive_open(struct inode *inode, struct file *file);
|
|
+extern int video_exclusive_release(struct inode *inode, struct file *file);
|
|
+extern int video_usercopy(struct inode *inode, struct file *file,
|
|
+ unsigned int cmd, unsigned long arg,
|
|
+ int (*func)(struct inode *inode, struct file *file,
|
|
+ unsigned int cmd, void *arg));
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+#define VID_TYPE_CAPTURE 1 /* Can capture */
|
|
+#define VID_TYPE_CLIPPING 32 /* Can clip */
|
|
+#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
|
|
+#define VID_TYPE_SCALES 128 /* Scalable */
|
|
+#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
|
|
+
|
|
+
|
|
+
|
|
+#define VID_HARDWARE_SAMSUNG_FIMC 255
|
|
+
|
|
+
|
|
+
|
|
+#endif
|
|
+
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * c-basic-offset: 8
|
|
+ * End:
|
|
+ */
|
|
diff --git a/arch/arm/mach-s3c2440/camera/videodev2.h b/arch/arm/mach-s3c2440/camera/videodev2.h
|
|
new file mode 100644
|
|
index 0000000..1bfc45a
|
|
--- /dev/null
|
|
+++ b/arch/arm/mach-s3c2440/camera/videodev2.h
|
|
@@ -0,0 +1,938 @@
|
|
+#ifndef __LINUX_VIDEODEV2_H
|
|
+#define __LINUX_VIDEODEV2_H
|
|
+/*
|
|
+ * Video for Linux Two
|
|
+ *
|
|
+ * Header file for v4l or V4L2 drivers and applications, for
|
|
+ * Linux kernels 2.2.x or 2.4.x.
|
|
+ *
|
|
+ * See http://bytesex.org/v4l/ for API specs and other
|
|
+ * v4l2 documentation.
|
|
+ *
|
|
+ * Author: Bill Dirks <bdirks@pacbell.net>
|
|
+ * Justin Schoeman
|
|
+ * et al.
|
|
+ */
|
|
+#ifdef __KERNEL__
|
|
+#include <linux/time.h> /* need struct timeval */
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * M I S C E L L A N E O U S
|
|
+ */
|
|
+
|
|
+/* Four-character-code (FOURCC) */
|
|
+#define v4l2_fourcc(a,b,c,d)\
|
|
+ (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
|
|
+
|
|
+/*
|
|
+ * E N U M S
|
|
+ */
|
|
+enum v4l2_field {
|
|
+ V4L2_FIELD_ANY = 0, /* driver can choose from none,
|
|
+ top, bottom, interlaced
|
|
+ depending on whatever it thinks
|
|
+ is approximate ... */
|
|
+ V4L2_FIELD_NONE = 1, /* this device has no fields ... */
|
|
+ V4L2_FIELD_TOP = 2, /* top field only */
|
|
+ V4L2_FIELD_BOTTOM = 3, /* bottom field only */
|
|
+ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
|
|
+ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one
|
|
+ buffer, top-bottom order */
|
|
+ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
|
|
+ V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into
|
|
+ separate buffers */
|
|
+};
|
|
+#define V4L2_FIELD_HAS_TOP(field) \
|
|
+ ((field) == V4L2_FIELD_TOP ||\
|
|
+ (field) == V4L2_FIELD_INTERLACED ||\
|
|
+ (field) == V4L2_FIELD_SEQ_TB ||\
|
|
+ (field) == V4L2_FIELD_SEQ_BT)
|
|
+#define V4L2_FIELD_HAS_BOTTOM(field) \
|
|
+ ((field) == V4L2_FIELD_BOTTOM ||\
|
|
+ (field) == V4L2_FIELD_INTERLACED ||\
|
|
+ (field) == V4L2_FIELD_SEQ_TB ||\
|
|
+ (field) == V4L2_FIELD_SEQ_BT)
|
|
+#define V4L2_FIELD_HAS_BOTH(field) \
|
|
+ ((field) == V4L2_FIELD_INTERLACED ||\
|
|
+ (field) == V4L2_FIELD_SEQ_TB ||\
|
|
+ (field) == V4L2_FIELD_SEQ_BT)
|
|
+
|
|
+enum v4l2_buf_type {
|
|
+ V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
|
|
+ V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
|
|
+ V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
|
|
+ V4L2_BUF_TYPE_VBI_CAPTURE = 4,
|
|
+ V4L2_BUF_TYPE_VBI_OUTPUT = 5,
|
|
+ V4L2_BUF_TYPE_PRIVATE = 0x80,
|
|
+};
|
|
+
|
|
+enum v4l2_ctrl_type {
|
|
+ V4L2_CTRL_TYPE_INTEGER = 1,
|
|
+ V4L2_CTRL_TYPE_BOOLEAN = 2,
|
|
+ V4L2_CTRL_TYPE_MENU = 3,
|
|
+ V4L2_CTRL_TYPE_BUTTON = 4,
|
|
+};
|
|
+
|
|
+enum v4l2_tuner_type {
|
|
+ V4L2_TUNER_RADIO = 1,
|
|
+ V4L2_TUNER_ANALOG_TV = 2,
|
|
+};
|
|
+
|
|
+enum v4l2_memory {
|
|
+ V4L2_MEMORY_MMAP = 1,
|
|
+ V4L2_MEMORY_USERPTR = 2,
|
|
+ V4L2_MEMORY_OVERLAY = 3,
|
|
+};
|
|
+
|
|
+/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
|
|
+enum v4l2_colorspace {
|
|
+ /* ITU-R 601 -- broadcast NTSC/PAL */
|
|
+ V4L2_COLORSPACE_SMPTE170M = 1,
|
|
+
|
|
+ /* 1125-Line (US) HDTV */
|
|
+ V4L2_COLORSPACE_SMPTE240M = 2,
|
|
+
|
|
+ /* HD and modern captures. */
|
|
+ V4L2_COLORSPACE_REC709 = 3,
|
|
+
|
|
+ /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
|
|
+ V4L2_COLORSPACE_BT878 = 4,
|
|
+
|
|
+ /* These should be useful. Assume 601 extents. */
|
|
+ V4L2_COLORSPACE_470_SYSTEM_M = 5,
|
|
+ V4L2_COLORSPACE_470_SYSTEM_BG = 6,
|
|
+
|
|
+ /* I know there will be cameras that send this. So, this is
|
|
+ * unspecified chromaticities and full 0-255 on each of the
|
|
+ * Y'CbCr components
|
|
+ */
|
|
+ V4L2_COLORSPACE_JPEG = 7,
|
|
+
|
|
+ /* For RGB colourspaces, this is probably a good start. */
|
|
+ V4L2_COLORSPACE_SRGB = 8,
|
|
+};
|
|
+
|
|
+enum v4l2_priority {
|
|
+ V4L2_PRIORITY_UNSET = 0, /* not initialized */
|
|
+ V4L2_PRIORITY_BACKGROUND = 1,
|
|
+ V4L2_PRIORITY_INTERACTIVE = 2,
|
|
+ V4L2_PRIORITY_RECORD = 3,
|
|
+ V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
|
|
+};
|
|
+
|
|
+struct v4l2_rect {
|
|
+ __s32 left;
|
|
+ __s32 top;
|
|
+ __s32 width;
|
|
+ __s32 height;
|
|
+};
|
|
+
|
|
+struct v4l2_fract {
|
|
+ __u32 numerator;
|
|
+ __u32 denominator;
|
|
+};
|
|
+
|
|
+/*
|
|
+ * D R I V E R C A P A B I L I T I E S
|
|
+ */
|
|
+struct v4l2_capability
|
|
+{
|
|
+ __u8 driver[16]; /* i.e. "bttv" */
|
|
+ __u8 card[32]; /* i.e. "Hauppauge WinTV" */
|
|
+ __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
|
|
+ __u32 version; /* should use KERNEL_VERSION() */
|
|
+ __u32 capabilities; /* Device capabilities */
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+
|
|
+/* Values for 'capabilities' field */
|
|
+#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
|
|
+#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
|
|
+#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
|
|
+#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */
|
|
+#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */
|
|
+#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
|
|
+
|
|
+#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
|
|
+#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
|
|
+#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
|
|
+
|
|
+#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
|
|
+#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
|
|
+#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
|
|
+
|
|
+/*
|
|
+ * V I D E O I M A G E F O R M A T
|
|
+ */
|
|
+
|
|
+struct v4l2_pix_format
|
|
+{
|
|
+ __u32 width;
|
|
+ __u32 height;
|
|
+ __u32 pixelformat;
|
|
+ enum v4l2_field field;
|
|
+ __u32 bytesperline; /* for padding, zero if unused */
|
|
+ __u32 sizeimage;
|
|
+ enum v4l2_colorspace colorspace;
|
|
+ __u32 priv; /* private data, depends on pixelformat */
|
|
+};
|
|
+
|
|
+/* Pixel format FOURCC depth Description */
|
|
+#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */
|
|
+#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */
|
|
+#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */
|
|
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */
|
|
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */
|
|
+#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */
|
|
+#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */
|
|
+#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */
|
|
+#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */
|
|
+#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */
|
|
+#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */
|
|
+#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */
|
|
+#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */
|
|
+#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */
|
|
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */
|
|
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */
|
|
+#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */
|
|
+
|
|
+/* two planes -- one Y, one Cr + Cb interleaved */
|
|
+#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */
|
|
+#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */
|
|
+
|
|
+/* The following formats are not defined in the V4L2 specification */
|
|
+#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */
|
|
+#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */
|
|
+#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */
|
|
+#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */
|
|
+
|
|
+/* compressed formats */
|
|
+#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */
|
|
+#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */
|
|
+#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */
|
|
+#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG */
|
|
+
|
|
+/* Vendor-specific formats */
|
|
+#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
|
|
+
|
|
+/*
|
|
+ * F O R M A T E N U M E R A T I O N
|
|
+ */
|
|
+struct v4l2_fmtdesc
|
|
+{
|
|
+ __u32 index; /* Format number */
|
|
+ enum v4l2_buf_type type; /* buffer type */
|
|
+ __u32 flags;
|
|
+ __u8 description[32]; /* Description string */
|
|
+ __u32 pixelformat; /* Format fourcc */
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+
|
|
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
|
|
+
|
|
+
|
|
+/*
|
|
+ * T I M E C O D E
|
|
+ */
|
|
+struct v4l2_timecode
|
|
+{
|
|
+ __u32 type;
|
|
+ __u32 flags;
|
|
+ __u8 frames;
|
|
+ __u8 seconds;
|
|
+ __u8 minutes;
|
|
+ __u8 hours;
|
|
+ __u8 userbits[4];
|
|
+};
|
|
+
|
|
+/* Type */
|
|
+#define V4L2_TC_TYPE_24FPS 1
|
|
+#define V4L2_TC_TYPE_25FPS 2
|
|
+#define V4L2_TC_TYPE_30FPS 3
|
|
+#define V4L2_TC_TYPE_50FPS 4
|
|
+#define V4L2_TC_TYPE_60FPS 5
|
|
+
|
|
+/* Flags */
|
|
+#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */
|
|
+#define V4L2_TC_FLAG_COLORFRAME 0x0002
|
|
+#define V4L2_TC_USERBITS_field 0x000C
|
|
+#define V4L2_TC_USERBITS_USERDEFINED 0x0000
|
|
+#define V4L2_TC_USERBITS_8BITCHARS 0x0008
|
|
+/* The above is based on SMPTE timecodes */
|
|
+
|
|
+
|
|
+/*
|
|
+ * C O M P R E S S I O N P A R A M E T E R S
|
|
+ */
|
|
+#if 0
|
|
+/* ### generic compression settings don't work, there is too much
|
|
+ * ### codec-specific stuff. Maybe reuse that for MPEG codec settings
|
|
+ * ### later ... */
|
|
+struct v4l2_compression
|
|
+{
|
|
+ __u32 quality;
|
|
+ __u32 keyframerate;
|
|
+ __u32 pframerate;
|
|
+ __u32 reserved[5];
|
|
+
|
|
+/* what we'll need for MPEG, extracted from some postings on
|
|
+ the v4l list (Gert Vervoort, PlasmaJohn).
|
|
+
|
|
+system stream:
|
|
+ - type: elementary stream(ES), packatised elementary stream(s) (PES)
|
|
+ program stream(PS), transport stream(TS)
|
|
+ - system bitrate
|
|
+ - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes)
|
|
+ - TS video PID
|
|
+ - TS audio PID
|
|
+ - TS PCR PID
|
|
+ - TS system information tables (PAT, PMT, CAT, NIT and SIT)
|
|
+ - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported
|
|
+ by MPEG-1 systems)
|
|
+
|
|
+audio:
|
|
+ - type: MPEG (+Layer I,II,III), AC-3, LPCM
|
|
+ - bitrate
|
|
+ - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz)
|
|
+ - Trick Modes? (ff, rew)
|
|
+ - Copyright
|
|
+ - Inverse Telecine
|
|
+
|
|
+video:
|
|
+ - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set
|
|
+ through excisting V4L2 controls
|
|
+ - noise reduction, parameters encoder specific?
|
|
+ - MPEG video version: MPEG-1, MPEG-2
|
|
+ - GOP (Group Of Pictures) definition:
|
|
+ - N: number of frames per GOP
|
|
+ - M: distance between reference (I,P) frames
|
|
+ - open/closed GOP
|
|
+ - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes)
|
|
+ - quantiser scale: linear or logarithmic
|
|
+ - scanning: alternate or zigzag
|
|
+ - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate).
|
|
+ - target video bitrate for CBR
|
|
+ - target video bitrate for VBR
|
|
+ - maximum video bitrate for VBR - min. quantiser value for VBR
|
|
+ - max. quantiser value for VBR
|
|
+ - adaptive quantisation value
|
|
+ - return the number of bytes per GOP or bitrate for bitrate monitoring
|
|
+
|
|
+*/
|
|
+};
|
|
+#endif
|
|
+
|
|
+struct v4l2_jpegcompression
|
|
+{
|
|
+ int quality;
|
|
+
|
|
+ int APPn; /* Number of APP segment to be written,
|
|
+ * must be 0..15 */
|
|
+ int APP_len; /* Length of data in JPEG APPn segment */
|
|
+ char APP_data[60]; /* Data in the JPEG APPn segment. */
|
|
+
|
|
+ int COM_len; /* Length of data in JPEG COM segment */
|
|
+ char COM_data[60]; /* Data in JPEG COM segment */
|
|
+
|
|
+ __u32 jpeg_markers; /* Which markers should go into the JPEG
|
|
+ * output. Unless you exactly know what
|
|
+ * you do, leave them untouched.
|
|
+ * Inluding less markers will make the
|
|
+ * resulting code smaller, but there will
|
|
+ * be fewer aplications which can read it.
|
|
+ * The presence of the APP and COM marker
|
|
+ * is influenced by APP_len and COM_len
|
|
+ * ONLY, not by this property! */
|
|
+
|
|
+#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
|
|
+#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
|
|
+#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
|
|
+#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */
|
|
+#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will
|
|
+ * allways use APP0 */
|
|
+};
|
|
+
|
|
+
|
|
+/*
|
|
+ * M E M O R Y - M A P P I N G B U F F E R S
|
|
+ */
|
|
+struct v4l2_requestbuffers
|
|
+{
|
|
+ __u32 count;
|
|
+ enum v4l2_buf_type type;
|
|
+ enum v4l2_memory memory;
|
|
+ __u32 reserved[2];
|
|
+};
|
|
+
|
|
+struct v4l2_buffer
|
|
+{
|
|
+ __u32 index;
|
|
+ enum v4l2_buf_type type;
|
|
+ __u32 bytesused;
|
|
+ __u32 flags;
|
|
+ enum v4l2_field field;
|
|
+ struct timeval timestamp;
|
|
+ struct v4l2_timecode timecode;
|
|
+ __u32 sequence;
|
|
+
|
|
+ /* memory location */
|
|
+ enum v4l2_memory memory;
|
|
+ union {
|
|
+ __u32 offset;
|
|
+ unsigned long userptr;
|
|
+ } m;
|
|
+ __u32 length;
|
|
+
|
|
+ __u32 reserved[2];
|
|
+};
|
|
+
|
|
+/* Flags for 'flags' field */
|
|
+#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */
|
|
+#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */
|
|
+#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */
|
|
+#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
|
|
+#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
|
|
+#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
|
|
+#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
|
|
+
|
|
+/*
|
|
+ * O V E R L A Y P R E V I E W
|
|
+ */
|
|
+struct v4l2_framebuffer
|
|
+{
|
|
+ __u32 capability;
|
|
+ __u32 flags;
|
|
+/* FIXME: in theory we should pass something like PCI device + memory
|
|
+ * region + offset instead of some physical address */
|
|
+ void* base;
|
|
+ struct v4l2_pix_format fmt;
|
|
+};
|
|
+/* Flags for the 'capability' field. Read only */
|
|
+#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
|
|
+#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
|
|
+#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
|
|
+#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
|
|
+/* Flags for the 'flags' field. */
|
|
+#define V4L2_FBUF_FLAG_PRIMARY 0x0001
|
|
+#define V4L2_FBUF_FLAG_OVERLAY 0x0002
|
|
+#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
|
|
+
|
|
+struct v4l2_clip
|
|
+{
|
|
+ struct v4l2_rect c;
|
|
+ struct v4l2_clip *next;
|
|
+};
|
|
+
|
|
+struct v4l2_window
|
|
+{
|
|
+ struct v4l2_rect w;
|
|
+ enum v4l2_field field;
|
|
+ __u32 chromakey;
|
|
+ struct v4l2_clip *clips;
|
|
+ __u32 clipcount;
|
|
+ void *bitmap;
|
|
+};
|
|
+
|
|
+
|
|
+/*
|
|
+ * C A P T U R E P A R A M E T E R S
|
|
+ */
|
|
+struct v4l2_captureparm
|
|
+{
|
|
+ __u32 capability; /* Supported modes */
|
|
+ __u32 capturemode; /* Current mode */
|
|
+ struct v4l2_fract timeperframe; /* Time per frame in .1us units */
|
|
+ __u32 extendedmode; /* Driver-specific extensions */
|
|
+ __u32 readbuffers; /* # of buffers for read */
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+/* Flags for 'capability' and 'capturemode' fields */
|
|
+#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
|
|
+#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
|
|
+
|
|
+struct v4l2_outputparm
|
|
+{
|
|
+ __u32 capability; /* Supported modes */
|
|
+ __u32 outputmode; /* Current mode */
|
|
+ struct v4l2_fract timeperframe; /* Time per frame in seconds */
|
|
+ __u32 extendedmode; /* Driver-specific extensions */
|
|
+ __u32 writebuffers; /* # of buffers for write */
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+
|
|
+/*
|
|
+ * I N P U T I M A G E C R O P P I N G
|
|
+ */
|
|
+
|
|
+struct v4l2_cropcap {
|
|
+ enum v4l2_buf_type type;
|
|
+ struct v4l2_rect bounds;
|
|
+ struct v4l2_rect defrect;
|
|
+ struct v4l2_fract pixelaspect;
|
|
+};
|
|
+
|
|
+struct v4l2_crop {
|
|
+ enum v4l2_buf_type type;
|
|
+ struct v4l2_rect c;
|
|
+};
|
|
+
|
|
+/*
|
|
+ * A N A L O G V I D E O S T A N D A R D
|
|
+ */
|
|
+
|
|
+typedef __u64 v4l2_std_id;
|
|
+
|
|
+/* one bit for each */
|
|
+#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
|
|
+#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
|
|
+#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
|
|
+#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
|
|
+#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
|
|
+#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
|
|
+#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
|
|
+#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
|
|
+
|
|
+#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
|
|
+#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
|
|
+#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
|
|
+#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
|
|
+
|
|
+#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
|
|
+#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
|
|
+
|
|
+#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
|
|
+#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
|
|
+#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
|
|
+#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
|
|
+#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
|
|
+#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
|
|
+#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
|
|
+
|
|
+/* ATSC/HDTV */
|
|
+#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
|
|
+#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
|
|
+
|
|
+/* some common needed stuff */
|
|
+#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
|
|
+ V4L2_STD_PAL_B1 |\
|
|
+ V4L2_STD_PAL_G)
|
|
+#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
|
|
+ V4L2_STD_PAL_D1 |\
|
|
+ V4L2_STD_PAL_K)
|
|
+#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
|
|
+ V4L2_STD_PAL_DK |\
|
|
+ V4L2_STD_PAL_H |\
|
|
+ V4L2_STD_PAL_I)
|
|
+#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
|
|
+ V4L2_STD_NTSC_M_JP)
|
|
+#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
|
|
+ V4L2_STD_SECAM_D |\
|
|
+ V4L2_STD_SECAM_G |\
|
|
+ V4L2_STD_SECAM_H |\
|
|
+ V4L2_STD_SECAM_K |\
|
|
+ V4L2_STD_SECAM_K1 |\
|
|
+ V4L2_STD_SECAM_L)
|
|
+
|
|
+#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
|
|
+ V4L2_STD_PAL_60 |\
|
|
+ V4L2_STD_NTSC)
|
|
+#define V4L2_STD_625_50 (V4L2_STD_PAL |\
|
|
+ V4L2_STD_PAL_N |\
|
|
+ V4L2_STD_PAL_Nc |\
|
|
+ V4L2_STD_SECAM)
|
|
+
|
|
+#define V4L2_STD_UNKNOWN 0
|
|
+#define V4L2_STD_ALL (V4L2_STD_525_60 |\
|
|
+ V4L2_STD_625_50)
|
|
+
|
|
+struct v4l2_standard
|
|
+{
|
|
+ __u32 index;
|
|
+ v4l2_std_id id;
|
|
+ __u8 name[24];
|
|
+ struct v4l2_fract frameperiod; /* Frames, not fields */
|
|
+ __u32 framelines;
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+
|
|
+
|
|
+/*
|
|
+ * V I D E O I N P U T S
|
|
+ */
|
|
+struct v4l2_input
|
|
+{
|
|
+ __u32 index; /* Which input */
|
|
+ __u8 name[32]; /* Label */
|
|
+ __u32 type; /* Type of input */
|
|
+ __u32 audioset; /* Associated audios (bitfield) */
|
|
+ __u32 tuner; /* Associated tuner */
|
|
+ v4l2_std_id std;
|
|
+ __u32 status;
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+/* Values for the 'type' field */
|
|
+#define V4L2_INPUT_TYPE_TUNER 1
|
|
+#define V4L2_INPUT_TYPE_CAMERA 2
|
|
+
|
|
+/* field 'status' - general */
|
|
+#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */
|
|
+#define V4L2_IN_ST_NO_SIGNAL 0x00000002
|
|
+#define V4L2_IN_ST_NO_COLOR 0x00000004
|
|
+
|
|
+/* field 'status' - analog */
|
|
+#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
|
|
+#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
|
|
+
|
|
+/* field 'status' - digital */
|
|
+#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */
|
|
+#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */
|
|
+#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */
|
|
+
|
|
+/* field 'status' - VCR and set-top box */
|
|
+#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */
|
|
+#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
|
|
+#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
|
|
+
|
|
+/*
|
|
+ * V I D E O O U T P U T S
|
|
+ */
|
|
+struct v4l2_output
|
|
+{
|
|
+ __u32 index; /* Which output */
|
|
+ __u8 name[32]; /* Label */
|
|
+ __u32 type; /* Type of output */
|
|
+ __u32 audioset; /* Associated audios (bitfield) */
|
|
+ __u32 modulator; /* Associated modulator */
|
|
+ v4l2_std_id std;
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+/* Values for the 'type' field */
|
|
+#define V4L2_OUTPUT_TYPE_MODULATOR 1
|
|
+#define V4L2_OUTPUT_TYPE_ANALOG 2
|
|
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
|
|
+
|
|
+/*
|
|
+ * C O N T R O L S
|
|
+ */
|
|
+struct v4l2_control
|
|
+{
|
|
+ __u32 id;
|
|
+ __s32 value;
|
|
+};
|
|
+
|
|
+/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
|
|
+struct v4l2_queryctrl
|
|
+{
|
|
+ __u32 id;
|
|
+ enum v4l2_ctrl_type type;
|
|
+ __u8 name[32]; /* Whatever */
|
|
+ __s32 minimum; /* Note signedness */
|
|
+ __s32 maximum;
|
|
+ __s32 step;
|
|
+ __s32 default_value;
|
|
+ __u32 flags;
|
|
+ __u32 reserved[2];
|
|
+};
|
|
+
|
|
+/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
|
|
+struct v4l2_querymenu
|
|
+{
|
|
+ __u32 id;
|
|
+ __u32 index;
|
|
+ __u8 name[32]; /* Whatever */
|
|
+ __u32 reserved;
|
|
+};
|
|
+
|
|
+/* Control flags */
|
|
+#define V4L2_CTRL_FLAG_DISABLED 0x0001
|
|
+#define V4L2_CTRL_FLAG_GRABBED 0x0002
|
|
+
|
|
+/* Control IDs defined by V4L2 */
|
|
+#define V4L2_CID_BASE 0x00980900
|
|
+/* IDs reserved for driver specific controls */
|
|
+#define V4L2_CID_PRIVATE_BASE 0x08000000
|
|
+
|
|
+#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
|
|
+#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
|
|
+#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
|
|
+#define V4L2_CID_HUE (V4L2_CID_BASE+3)
|
|
+#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
|
|
+#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
|
|
+#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
|
|
+#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
|
|
+#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
|
|
+#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
|
|
+#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11)
|
|
+#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
|
|
+#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
|
|
+#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
|
|
+#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
|
|
+#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
|
|
+#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */
|
|
+#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
|
|
+#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
|
|
+#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
|
|
+#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
|
|
+#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
|
|
+#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
|
|
+#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
|
|
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */
|
|
+
|
|
+/*
|
|
+ * T U N I N G
|
|
+ */
|
|
+struct v4l2_tuner
|
|
+{
|
|
+ __u32 index;
|
|
+ __u8 name[32];
|
|
+ enum v4l2_tuner_type type;
|
|
+ __u32 capability;
|
|
+ __u32 rangelow;
|
|
+ __u32 rangehigh;
|
|
+ __u32 rxsubchans;
|
|
+ __u32 audmode;
|
|
+ __s32 signal;
|
|
+ __s32 afc;
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+
|
|
+struct v4l2_modulator
|
|
+{
|
|
+ __u32 index;
|
|
+ __u8 name[32];
|
|
+ __u32 capability;
|
|
+ __u32 rangelow;
|
|
+ __u32 rangehigh;
|
|
+ __u32 txsubchans;
|
|
+ __u32 reserved[4];
|
|
+};
|
|
+
|
|
+/* Flags for the 'capability' field */
|
|
+#define V4L2_TUNER_CAP_LOW 0x0001
|
|
+#define V4L2_TUNER_CAP_NORM 0x0002
|
|
+#define V4L2_TUNER_CAP_STEREO 0x0010
|
|
+#define V4L2_TUNER_CAP_LANG2 0x0020
|
|
+#define V4L2_TUNER_CAP_SAP 0x0020
|
|
+#define V4L2_TUNER_CAP_LANG1 0x0040
|
|
+
|
|
+/* Flags for the 'rxsubchans' field */
|
|
+#define V4L2_TUNER_SUB_MONO 0x0001
|
|
+#define V4L2_TUNER_SUB_STEREO 0x0002
|
|
+#define V4L2_TUNER_SUB_LANG2 0x0004
|
|
+#define V4L2_TUNER_SUB_SAP 0x0004
|
|
+#define V4L2_TUNER_SUB_LANG1 0x0008
|
|
+
|
|
+/* Values for the 'audmode' field */
|
|
+#define V4L2_TUNER_MODE_MONO 0x0000
|
|
+#define V4L2_TUNER_MODE_STEREO 0x0001
|
|
+#define V4L2_TUNER_MODE_LANG2 0x0002
|
|
+#define V4L2_TUNER_MODE_SAP 0x0002
|
|
+#define V4L2_TUNER_MODE_LANG1 0x0003
|
|
+
|
|
+struct v4l2_frequency
|
|
+{
|
|
+ __u32 tuner;
|
|
+ enum v4l2_tuner_type type;
|
|
+ __u32 frequency;
|
|
+ __u32 reserved[8];
|
|
+};
|
|
+
|
|
+/*
|
|
+ * A U D I O
|
|
+ */
|
|
+struct v4l2_audio
|
|
+{
|
|
+ __u32 index;
|
|
+ __u8 name[32];
|
|
+ __u32 capability;
|
|
+ __u32 mode;
|
|
+ __u32 reserved[2];
|
|
+};
|
|
+/* Flags for the 'capability' field */
|
|
+#define V4L2_AUDCAP_STEREO 0x00001
|
|
+#define V4L2_AUDCAP_AVL 0x00002
|
|
+
|
|
+/* Flags for the 'mode' field */
|
|
+#define V4L2_AUDMODE_AVL 0x00001
|
|
+
|
|
+struct v4l2_audioout
|
|
+{
|
|
+ __u32 index;
|
|
+ __u8 name[32];
|
|
+ __u32 capability;
|
|
+ __u32 mode;
|
|
+ __u32 reserved[2];
|
|
+};
|
|
+
|
|
+/*
|
|
+ * D A T A S E R V I C E S ( V B I )
|
|
+ *
|
|
+ * Data services API by Michael Schimek
|
|
+ */
|
|
+
|
|
+struct v4l2_vbi_format
|
|
+{
|
|
+ __u32 sampling_rate; /* in 1 Hz */
|
|
+ __u32 offset;
|
|
+ __u32 samples_per_line;
|
|
+ __u32 sample_format; /* V4L2_PIX_FMT_* */
|
|
+ __s32 start[2];
|
|
+ __u32 count[2];
|
|
+ __u32 flags; /* V4L2_VBI_* */
|
|
+ __u32 reserved[2]; /* must be zero */
|
|
+};
|
|
+
|
|
+/* VBI flags */
|
|
+#define V4L2_VBI_UNSYNC (1<< 0)
|
|
+#define V4L2_VBI_INTERLACED (1<< 1)
|
|
+
|
|
+
|
|
+/*
|
|
+ * A G G R E G A T E S T R U C T U R E S
|
|
+ */
|
|
+
|
|
+/* Stream data format
|
|
+ */
|
|
+struct v4l2_format
|
|
+{
|
|
+ enum v4l2_buf_type type;
|
|
+ union
|
|
+ {
|
|
+ struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE
|
|
+ struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY
|
|
+ struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE
|
|
+ __u8 raw_data[200]; // user-defined
|
|
+ } fmt;
|
|
+};
|
|
+
|
|
+
|
|
+/* Stream type-dependent parameters
|
|
+ */
|
|
+struct v4l2_streamparm
|
|
+{
|
|
+ enum v4l2_buf_type type;
|
|
+ union
|
|
+ {
|
|
+ struct v4l2_captureparm capture;
|
|
+ struct v4l2_outputparm output;
|
|
+ __u8 raw_data[200]; /* user-defined */
|
|
+ } parm;
|
|
+};
|
|
+
|
|
+
|
|
+
|
|
+/*
|
|
+ * I O C T L C O D E S F O R V I D E O D E V I C E S
|
|
+ *
|
|
+ */
|
|
+#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability)
|
|
+#define VIDIOC_RESERVED _IO ('V', 1)
|
|
+#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
|
|
+#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
|
|
+#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
|
|
+#if 0
|
|
+#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression)
|
|
+#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression)
|
|
+#endif
|
|
+#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
|
|
+#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
|
|
+#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
|
|
+#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer)
|
|
+#define VIDIOC_OVERLAY _IOW ('V', 14, int)
|
|
+#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer)
|
|
+#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer)
|
|
+#define VIDIOC_STREAMON _IOW ('V', 18, int)
|
|
+#define VIDIOC_STREAMOFF _IOW ('V', 19, int)
|
|
+#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm)
|
|
+#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm)
|
|
+#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id)
|
|
+#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id)
|
|
+#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard)
|
|
+#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input)
|
|
+#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control)
|
|
+#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control)
|
|
+#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner)
|
|
+#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner)
|
|
+#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio)
|
|
+#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio)
|
|
+#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl)
|
|
+#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu)
|
|
+#define VIDIOC_G_INPUT _IOR ('V', 38, int)
|
|
+#define VIDIOC_S_INPUT _IOWR ('V', 39, int)
|
|
+#define VIDIOC_G_OUTPUT _IOR ('V', 46, int)
|
|
+#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int)
|
|
+#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output)
|
|
+#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout)
|
|
+#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout)
|
|
+#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator)
|
|
+#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator)
|
|
+#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency)
|
|
+#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency)
|
|
+#define VIDIOC_CROPCAP _IOR ('V', 58, struct v4l2_cropcap)
|
|
+#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop)
|
|
+#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
|
|
+#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression)
|
|
+#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression)
|
|
+#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
|
|
+#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
|
|
+#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio)
|
|
+#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
|
|
+#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
|
|
+#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
|
|
+
|
|
+/* for compatibility, will go away some day */
|
|
+#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
|
|
+#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
|
|
+#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
|
|
+#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
|
|
+#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
|
|
+
|
|
+#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
|
|
+
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+/*
|
|
+ *
|
|
+ * V 4 L 2 D R I V E R H E L P E R A P I
|
|
+ *
|
|
+ * Some commonly needed functions for drivers (v4l2-common.o module)
|
|
+ */
|
|
+#include <linux/fs.h>
|
|
+
|
|
+/* Video standard functions */
|
|
+extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
|
|
+extern int v4l2_video_std_construct(struct v4l2_standard *vs,
|
|
+ int id, char *name);
|
|
+
|
|
+/* prority handling */
|
|
+struct v4l2_prio_state {
|
|
+ atomic_t prios[4];
|
|
+};
|
|
+int v4l2_prio_init(struct v4l2_prio_state *global);
|
|
+int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
|
|
+ enum v4l2_priority new);
|
|
+int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
|
|
+int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local);
|
|
+enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
|
|
+int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
|
|
+
|
|
+/* names for fancy debug output */
|
|
+extern char *v4l2_field_names[];
|
|
+extern char *v4l2_type_names[];
|
|
+extern char *v4l2_ioctl_names[];
|
|
+
|
|
+/* Compatibility layer interface -- v4l1-compat module */
|
|
+typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
|
|
+ unsigned int cmd, void *arg);
|
|
+int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
|
|
+ int cmd, void *arg, v4l2_kioctl driver_ioctl);
|
|
+
|
|
+#endif /* __KERNEL__ */
|
|
+#endif /* __LINUX_VIDEODEV2_H */
|
|
+
|
|
+/*
|
|
+ * Local variables:
|
|
+ * c-basic-offset: 8
|
|
+ * End:
|
|
+ */
|
|
--
|
|
1.5.6.5
|
|
|