mirror of https://gitee.com/openkylin/linux.git
Staging: HTC Dream: add camera support
This patch adds driver for HTC Dream camera. I guess driver is slightly higher quality than usual for staging/ , but it is fairly big and I don't feel like doing all the cleanups myself. Also some parts can probably be removed, as they did not end up in shipping hardware.. Signed-off-by: Pavel Machek <pavel@ucw.cz> Cc: Brian Swetland <swetland@google.com> Cc: Iliyan Malchev <ibm@android.com> Cc: San Mehat <san@android.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
caff4caead
commit
eb7b797b40
|
@ -0,0 +1,46 @@
|
|||
comment "Qualcomm MSM Camera And Video"
|
||||
|
||||
menuconfig MSM_CAMERA
|
||||
bool "Qualcomm MSM camera and video capture support"
|
||||
depends on ARCH_MSM && VIDEO_V4L2_COMMON
|
||||
help
|
||||
Say Y here to enable selecting the video adapters for
|
||||
Qualcomm msm camera and video encoding
|
||||
|
||||
config MSM_CAMERA_DEBUG
|
||||
bool "Qualcomm MSM camera debugging with printk"
|
||||
depends on MSM_CAMERA
|
||||
help
|
||||
Enable printk() debug for msm camera
|
||||
|
||||
config MSM_CAMERA_FLASH
|
||||
bool "Qualcomm MSM camera flash support"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
Enable support for LED flash for msm camera
|
||||
|
||||
|
||||
comment "Camera Sensor Selection"
|
||||
config MT9T013
|
||||
bool "Sensor mt9t013 (BAYER 3M)"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
MICRON 3M Bayer Sensor with AutoFocus
|
||||
|
||||
config MT9D112
|
||||
bool "Sensor mt9d112 (YUV 2M)"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
MICRON 2M YUV Sensor
|
||||
|
||||
config MT9P012
|
||||
bool "Sensor mt9p012 (BAYER 5M)"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
MICRON 5M Bayer Sensor with Autofocus
|
||||
|
||||
config S5K3E2FX
|
||||
bool "Sensor s5k3e2fx (Samsung 5M)"
|
||||
depends on MSM_CAMERA
|
||||
---help---
|
||||
Samsung 5M with Autofocus
|
|
@ -0,0 +1,7 @@
|
|||
obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
|
||||
obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
|
||||
obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o
|
||||
obj-$(CONFIG_MSM_CAMERA) += msm_camera.o msm_v4l2.o
|
||||
obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o
|
||||
obj-$(CONFIG_ARCH_MSM) += msm_vfe7x.o msm_io7x.o
|
||||
obj-$(CONFIG_ARCH_QSD) += msm_vfe8x.o msm_vfe8x_proc.o msm_io8x.o
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2009 QUALCOMM Incorporated
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/camera.h>
|
||||
|
||||
#define CAMIF_CFG_RMSK 0x1fffff
|
||||
#define CAM_SEL_BMSK 0x2
|
||||
#define CAM_PCLK_SRC_SEL_BMSK 0x60000
|
||||
#define CAM_PCLK_INVERT_BMSK 0x80000
|
||||
#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
|
||||
|
||||
#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
|
||||
#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
|
||||
#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80
|
||||
|
||||
#define CAM_SEL_SHFT 0x1
|
||||
#define CAM_PCLK_SRC_SEL_SHFT 0x11
|
||||
#define CAM_PCLK_INVERT_SHFT 0x13
|
||||
#define CAM_PAD_REG_SW_RESET_SHFT 0x14
|
||||
|
||||
#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
|
||||
#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
|
||||
#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7
|
||||
#define APPS_RESET_OFFSET 0x00000210
|
||||
|
||||
static struct clk *camio_vfe_mdc_clk;
|
||||
static struct clk *camio_mdc_clk;
|
||||
static struct clk *camio_vfe_clk;
|
||||
|
||||
static struct msm_camera_io_ext camio_ext;
|
||||
static struct resource *appio, *mdcio;
|
||||
void __iomem *appbase, *mdcbase;
|
||||
|
||||
static struct msm_camera_io_ext camio_ext;
|
||||
static struct resource *appio, *mdcio;
|
||||
void __iomem *appbase, *mdcbase;
|
||||
|
||||
extern int clk_set_flags(struct clk *clk, unsigned long flags);
|
||||
|
||||
int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
|
||||
{
|
||||
int rc = -1;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
switch (clktype) {
|
||||
case CAMIO_VFE_MDC_CLK:
|
||||
clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_MDC_CLK:
|
||||
clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_CLK:
|
||||
clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_enable(clk);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
|
||||
{
|
||||
int rc = -1;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
switch (clktype) {
|
||||
case CAMIO_VFE_MDC_CLK:
|
||||
clk = camio_vfe_mdc_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_MDC_CLK:
|
||||
clk = camio_mdc_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_CLK:
|
||||
clk = camio_vfe_clk;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_disable(clk);
|
||||
clk_put(clk);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camio_clk_rate_set(int rate)
|
||||
{
|
||||
struct clk *clk = camio_vfe_clk;
|
||||
|
||||
if (clk != ERR_PTR(-ENOENT))
|
||||
clk_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
int msm_camio_enable(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
camio_ext = camdev->ioext;
|
||||
|
||||
appio = request_mem_region(camio_ext.appphy,
|
||||
camio_ext.appsz, pdev->name);
|
||||
if (!appio) {
|
||||
rc = -EBUSY;
|
||||
goto enable_fail;
|
||||
}
|
||||
|
||||
appbase = ioremap(camio_ext.appphy,
|
||||
camio_ext.appsz);
|
||||
if (!appbase) {
|
||||
rc = -ENOMEM;
|
||||
goto apps_no_mem;
|
||||
}
|
||||
|
||||
mdcio = request_mem_region(camio_ext.mdcphy,
|
||||
camio_ext.mdcsz, pdev->name);
|
||||
if (!mdcio) {
|
||||
rc = -EBUSY;
|
||||
goto mdc_busy;
|
||||
}
|
||||
|
||||
mdcbase = ioremap(camio_ext.mdcphy,
|
||||
camio_ext.mdcsz);
|
||||
if (!mdcbase) {
|
||||
rc = -ENOMEM;
|
||||
goto mdc_no_mem;
|
||||
}
|
||||
|
||||
camdev->camera_gpio_on();
|
||||
|
||||
msm_camio_clk_enable(CAMIO_VFE_CLK);
|
||||
msm_camio_clk_enable(CAMIO_MDC_CLK);
|
||||
msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
|
||||
return 0;
|
||||
|
||||
mdc_no_mem:
|
||||
release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
|
||||
mdc_busy:
|
||||
iounmap(appbase);
|
||||
apps_no_mem:
|
||||
release_mem_region(camio_ext.appphy, camio_ext.appsz);
|
||||
enable_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camio_disable(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
iounmap(mdcbase);
|
||||
release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
|
||||
iounmap(appbase);
|
||||
release_mem_region(camio_ext.appphy, camio_ext.appsz);
|
||||
|
||||
camdev->camera_gpio_off();
|
||||
|
||||
msm_camio_clk_disable(CAMIO_VFE_CLK);
|
||||
msm_camio_clk_disable(CAMIO_MDC_CLK);
|
||||
msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
|
||||
}
|
||||
|
||||
void msm_camio_camif_pad_reg_reset(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t mask, value;
|
||||
|
||||
/* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */
|
||||
msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
|
||||
mask = CAM_SEL_BMSK |
|
||||
CAM_PCLK_SRC_SEL_BMSK |
|
||||
CAM_PCLK_INVERT_BMSK;
|
||||
|
||||
value = 1 << CAM_SEL_SHFT |
|
||||
3 << CAM_PCLK_SRC_SEL_SHFT |
|
||||
0 << CAM_PCLK_INVERT_SHFT;
|
||||
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_vfe_blk_reset(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = readl(appbase + 0x00000210);
|
||||
val |= 0x1;
|
||||
writel(val, appbase + 0x00000210);
|
||||
mdelay(10);
|
||||
|
||||
val = readl(appbase + 0x00000210);
|
||||
val &= ~0x1;
|
||||
writel(val, appbase + 0x00000210);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_camif_pad_reg_reset_2(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t mask, value;
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
|
||||
{
|
||||
struct clk *clk = NULL;
|
||||
|
||||
clk = camio_vfe_clk;
|
||||
|
||||
if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
|
||||
switch (srctype) {
|
||||
case MSM_CAMIO_CLK_SRC_INTERNAL:
|
||||
clk_set_flags(clk, 0x00000100 << 1);
|
||||
break;
|
||||
|
||||
case MSM_CAMIO_CLK_SRC_EXTERNAL:
|
||||
clk_set_flags(clk, 0x00000100);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int msm_camio_probe_on(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
camdev->camera_gpio_on();
|
||||
return msm_camio_clk_enable(CAMIO_VFE_CLK);
|
||||
}
|
||||
|
||||
int msm_camio_probe_off(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
camdev->camera_gpio_off();
|
||||
return msm_camio_clk_disable(CAMIO_VFE_CLK);
|
||||
}
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2009 QUALCOMM Incorporated
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/board.h>
|
||||
#include <mach/camera.h>
|
||||
|
||||
#define CAMIF_CFG_RMSK 0x1fffff
|
||||
#define CAM_SEL_BMSK 0x2
|
||||
#define CAM_PCLK_SRC_SEL_BMSK 0x60000
|
||||
#define CAM_PCLK_INVERT_BMSK 0x80000
|
||||
#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
|
||||
|
||||
#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
|
||||
#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
|
||||
#define MDDI_CLK_CHICKEN_BIT_BMSK 0x80
|
||||
|
||||
#define CAM_SEL_SHFT 0x1
|
||||
#define CAM_PCLK_SRC_SEL_SHFT 0x11
|
||||
#define CAM_PCLK_INVERT_SHFT 0x13
|
||||
#define CAM_PAD_REG_SW_RESET_SHFT 0x14
|
||||
|
||||
#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
|
||||
#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
|
||||
#define MDDI_CLK_CHICKEN_BIT_SHFT 0x7
|
||||
#define APPS_RESET_OFFSET 0x00000210
|
||||
|
||||
static struct clk *camio_vfe_mdc_clk;
|
||||
static struct clk *camio_mdc_clk;
|
||||
static struct clk *camio_vfe_clk;
|
||||
static struct clk *camio_vfe_axi_clk;
|
||||
static struct msm_camera_io_ext camio_ext;
|
||||
static struct resource *appio, *mdcio;
|
||||
void __iomem *appbase, *mdcbase;
|
||||
|
||||
extern int clk_set_flags(struct clk *clk, unsigned long flags);
|
||||
|
||||
int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
|
||||
{
|
||||
int rc = 0;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
switch (clktype) {
|
||||
case CAMIO_VFE_MDC_CLK:
|
||||
camio_vfe_mdc_clk =
|
||||
clk = clk_get(NULL, "vfe_mdc_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_MDC_CLK:
|
||||
camio_mdc_clk =
|
||||
clk = clk_get(NULL, "mdc_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_CLK:
|
||||
camio_vfe_clk =
|
||||
clk = clk_get(NULL, "vfe_clk");
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_AXI_CLK:
|
||||
camio_vfe_axi_clk =
|
||||
clk = clk_get(NULL, "vfe_axi_clk");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk))
|
||||
clk_enable(clk);
|
||||
else
|
||||
rc = -1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
|
||||
{
|
||||
int rc = 0;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
switch (clktype) {
|
||||
case CAMIO_VFE_MDC_CLK:
|
||||
clk = camio_vfe_mdc_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_MDC_CLK:
|
||||
clk = camio_mdc_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_CLK:
|
||||
clk = camio_vfe_clk;
|
||||
break;
|
||||
|
||||
case CAMIO_VFE_AXI_CLK:
|
||||
clk = camio_vfe_axi_clk;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
clk_disable(clk);
|
||||
clk_put(clk);
|
||||
} else
|
||||
rc = -1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camio_clk_rate_set(int rate)
|
||||
{
|
||||
struct clk *clk = camio_vfe_mdc_clk;
|
||||
|
||||
/* TODO: check return */
|
||||
clk_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
int msm_camio_enable(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
camio_ext = camdev->ioext;
|
||||
|
||||
appio = request_mem_region(camio_ext.appphy,
|
||||
camio_ext.appsz, pdev->name);
|
||||
if (!appio) {
|
||||
rc = -EBUSY;
|
||||
goto enable_fail;
|
||||
}
|
||||
|
||||
appbase = ioremap(camio_ext.appphy,
|
||||
camio_ext.appsz);
|
||||
if (!appbase) {
|
||||
rc = -ENOMEM;
|
||||
goto apps_no_mem;
|
||||
}
|
||||
|
||||
mdcio = request_mem_region(camio_ext.mdcphy,
|
||||
camio_ext.mdcsz, pdev->name);
|
||||
if (!mdcio) {
|
||||
rc = -EBUSY;
|
||||
goto mdc_busy;
|
||||
}
|
||||
|
||||
mdcbase = ioremap(camio_ext.mdcphy,
|
||||
camio_ext.mdcsz);
|
||||
if (!mdcbase) {
|
||||
rc = -ENOMEM;
|
||||
goto mdc_no_mem;
|
||||
}
|
||||
|
||||
camdev->camera_gpio_on();
|
||||
|
||||
msm_camio_clk_enable(CAMIO_VFE_CLK);
|
||||
msm_camio_clk_enable(CAMIO_MDC_CLK);
|
||||
msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
|
||||
msm_camio_clk_enable(CAMIO_VFE_AXI_CLK);
|
||||
return 0;
|
||||
|
||||
mdc_no_mem:
|
||||
release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
|
||||
mdc_busy:
|
||||
iounmap(appbase);
|
||||
apps_no_mem:
|
||||
release_mem_region(camio_ext.appphy, camio_ext.appsz);
|
||||
enable_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camio_disable(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
iounmap(mdcbase);
|
||||
release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
|
||||
iounmap(appbase);
|
||||
release_mem_region(camio_ext.appphy, camio_ext.appsz);
|
||||
|
||||
camdev->camera_gpio_off();
|
||||
|
||||
msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
|
||||
msm_camio_clk_disable(CAMIO_MDC_CLK);
|
||||
msm_camio_clk_disable(CAMIO_VFE_CLK);
|
||||
msm_camio_clk_disable(CAMIO_VFE_AXI_CLK);
|
||||
}
|
||||
|
||||
void msm_camio_camif_pad_reg_reset(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t mask, value;
|
||||
|
||||
/* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */
|
||||
msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
|
||||
mask = CAM_SEL_BMSK |
|
||||
CAM_PCLK_SRC_SEL_BMSK |
|
||||
CAM_PCLK_INVERT_BMSK |
|
||||
EXT_CAM_HSYNC_POL_SEL_BMSK |
|
||||
EXT_CAM_VSYNC_POL_SEL_BMSK |
|
||||
MDDI_CLK_CHICKEN_BIT_BMSK;
|
||||
|
||||
value = 1 << CAM_SEL_SHFT |
|
||||
3 << CAM_PCLK_SRC_SEL_SHFT |
|
||||
0 << CAM_PCLK_INVERT_SHFT |
|
||||
0 << EXT_CAM_HSYNC_POL_SEL_SHFT |
|
||||
0 << EXT_CAM_VSYNC_POL_SEL_SHFT |
|
||||
0 << MDDI_CLK_CHICKEN_BIT_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
|
||||
|
||||
mdelay(10);
|
||||
|
||||
/* todo: check return */
|
||||
if (camio_vfe_clk)
|
||||
clk_set_rate(camio_vfe_clk, 96000000);
|
||||
}
|
||||
|
||||
void msm_camio_vfe_blk_reset(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = readl(appbase + 0x00000210);
|
||||
val |= 0x1;
|
||||
writel(val, appbase + 0x00000210);
|
||||
mdelay(10);
|
||||
|
||||
val = readl(appbase + 0x00000210);
|
||||
val &= ~0x1;
|
||||
writel(val, appbase + 0x00000210);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_camif_pad_reg_reset_2(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t mask, value;
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
|
||||
reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
|
||||
mask = CAM_PAD_REG_SW_RESET_BMSK;
|
||||
value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
|
||||
writel((reg & (~mask)) | (value & mask), mdcbase);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
|
||||
{
|
||||
struct clk *clk = NULL;
|
||||
|
||||
clk = camio_vfe_clk;
|
||||
|
||||
if (clk != NULL) {
|
||||
switch (srctype) {
|
||||
case MSM_CAMIO_CLK_SRC_INTERNAL:
|
||||
clk_set_flags(clk, 0x00000100 << 1);
|
||||
break;
|
||||
|
||||
case MSM_CAMIO_CLK_SRC_EXTERNAL:
|
||||
clk_set_flags(clk, 0x00000100);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msm_camio_clk_axi_rate_set(int rate)
|
||||
{
|
||||
struct clk *clk = camio_vfe_axi_clk;
|
||||
/* todo: check return */
|
||||
clk_set_rate(clk, rate);
|
||||
}
|
||||
|
||||
int msm_camio_probe_on(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
camdev->camera_gpio_on();
|
||||
return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
|
||||
}
|
||||
|
||||
int msm_camio_probe_off(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
|
||||
struct msm_camera_device_platform_data *camdev = sinfo->pdata;
|
||||
|
||||
camdev->camera_gpio_off();
|
||||
return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
|
||||
}
|
|
@ -0,0 +1,793 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <media/v4l2-dev.h>
|
||||
#include <media/msm_camera.h>
|
||||
#include <mach/camera.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
/*#include <linux/platform_device.h>*/
|
||||
|
||||
#define MSM_V4L2_START_SNAPSHOT _IOWR('V', BASE_VIDIOC_PRIVATE+1, \
|
||||
struct v4l2_buffer)
|
||||
|
||||
#define MSM_V4L2_GET_PICTURE _IOWR('V', BASE_VIDIOC_PRIVATE+2, \
|
||||
struct v4l2_buffer)
|
||||
|
||||
#define MSM_V4L2_DEVICE_NAME "msm_v4l2"
|
||||
|
||||
#define MSM_V4L2_PROC_NAME "msm_v4l2"
|
||||
|
||||
#define MSM_V4L2_DEVNUM_MPEG2 0
|
||||
#define MSM_V4L2_DEVNUM_YUV 20
|
||||
|
||||
/* HVGA-P (portrait) and HVGA-L (landscape) */
|
||||
#define MSM_V4L2_WIDTH 480
|
||||
#define MSM_V4L2_HEIGHT 320
|
||||
|
||||
#if 1
|
||||
#define D(fmt, args...) printk(KERN_INFO "msm_v4l2: " fmt, ##args)
|
||||
#else
|
||||
#define D(fmt, args...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define PREVIEW_FRAMES_NUM 4
|
||||
|
||||
struct msm_v4l2_device {
|
||||
struct list_head read_queue;
|
||||
struct v4l2_format current_cap_format;
|
||||
struct v4l2_format current_pix_format;
|
||||
struct video_device *pvdev;
|
||||
struct msm_v4l2_driver *drv;
|
||||
uint8_t opencnt;
|
||||
|
||||
spinlock_t read_queue_lock;
|
||||
};
|
||||
|
||||
static struct msm_v4l2_device *g_pmsm_v4l2_dev;
|
||||
|
||||
|
||||
static DEFINE_MUTEX(msm_v4l2_opencnt_lock);
|
||||
|
||||
static int msm_v4l2_open(struct file *f)
|
||||
{
|
||||
int rc = 0;
|
||||
D("%s\n", __func__);
|
||||
mutex_lock(&msm_v4l2_opencnt_lock);
|
||||
if (!g_pmsm_v4l2_dev->opencnt) {
|
||||
rc = g_pmsm_v4l2_dev->drv->open(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
MSM_APPS_ID_V4L2);
|
||||
}
|
||||
g_pmsm_v4l2_dev->opencnt++;
|
||||
mutex_unlock(&msm_v4l2_opencnt_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_v4l2_release(struct file *f)
|
||||
{
|
||||
int rc = 0;
|
||||
D("%s\n", __func__);
|
||||
mutex_lock(&msm_v4l2_opencnt_lock);
|
||||
if (!g_pmsm_v4l2_dev->opencnt) {
|
||||
g_pmsm_v4l2_dev->opencnt--;
|
||||
if (!g_pmsm_v4l2_dev->opencnt) {
|
||||
rc = g_pmsm_v4l2_dev->drv->release(
|
||||
g_pmsm_v4l2_dev->drv->sync);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&msm_v4l2_opencnt_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static unsigned int msm_v4l2_poll(struct file *f, struct poll_table_struct *w)
|
||||
{
|
||||
return g_pmsm_v4l2_dev->drv->drv_poll(g_pmsm_v4l2_dev->drv->sync, f, w);
|
||||
}
|
||||
|
||||
static long msm_v4l2_ioctl(struct file *filep,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
D("msm_v4l2_ioctl, cmd = %d, %d\n", cmd, __LINE__);
|
||||
|
||||
switch (cmd) {
|
||||
case MSM_V4L2_START_SNAPSHOT:
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_ioctl: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->length = 0;
|
||||
ctrlcmd->value = NULL;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
D("msm_v4l2_ioctl, MSM_V4L2_START_SNAPSHOT v4l2 ioctl %d\n",
|
||||
cmd);
|
||||
ctrlcmd->type = MSM_V4L2_SNAPSHOT;
|
||||
return g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync,
|
||||
ctrlcmd);
|
||||
|
||||
case MSM_V4L2_GET_PICTURE:
|
||||
D("msm_v4l2_ioctl, MSM_V4L2_GET_PICTURE v4l2 ioctl %d\n", cmd);
|
||||
ctrlcmd = (struct msm_ctrl_cmd *)arg;
|
||||
return g_pmsm_v4l2_dev->drv->get_pict(
|
||||
g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
|
||||
default:
|
||||
D("msm_v4l2_ioctl, standard v4l2 ioctl %d\n", cmd);
|
||||
return video_ioctl2(filep, cmd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static void msm_v4l2_release_dev(struct video_device *d)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
}
|
||||
|
||||
static int msm_v4l2_querycap(struct file *f,
|
||||
void *pctx, struct v4l2_capability *pcaps)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
strncpy(pcaps->driver, MSM_APPS_ID_V4L2, sizeof(pcaps->driver));
|
||||
strncpy(pcaps->card,
|
||||
MSM_V4L2_DEVICE_NAME, sizeof(pcaps->card));
|
||||
pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_std(struct file *f, void *pctx, v4l2_std_id *pnorm)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_queryctrl(struct file *f,
|
||||
void *pctx, struct v4l2_queryctrl *pqctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_queryctrl: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_QUERY_CTRL;
|
||||
ctrlcmd->length = sizeof(struct v4l2_queryctrl);
|
||||
ctrlcmd->value = pqctrl;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
return ctrlcmd->status;
|
||||
}
|
||||
|
||||
static int msm_v4l2_g_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_g_ctrl: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_GET_CTRL;
|
||||
ctrlcmd->length = sizeof(struct v4l2_control);
|
||||
ctrlcmd->value = c;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
return ctrlcmd->status;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_s_ctrl: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_SET_CTRL;
|
||||
ctrlcmd->length = sizeof(struct v4l2_control);
|
||||
ctrlcmd->value = c;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
return ctrlcmd->status;
|
||||
}
|
||||
|
||||
static int msm_v4l2_reqbufs(struct file *f,
|
||||
void *pctx, struct v4l2_requestbuffers *b)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_querybuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
|
||||
{
|
||||
struct msm_pmem_info pmem_buf;
|
||||
#if 0
|
||||
__u32 width = 0;
|
||||
__u32 height = 0;
|
||||
__u32 y_size = 0;
|
||||
__u32 y_pad = 0;
|
||||
|
||||
/* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.width; */
|
||||
width = 640;
|
||||
/* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.height; */
|
||||
height = 480;
|
||||
|
||||
D("%s: width = %d, height = %d\n", __func__, width, height);
|
||||
|
||||
y_size = width * height;
|
||||
y_pad = y_size % 4;
|
||||
#endif
|
||||
|
||||
__u32 y_pad = pb->bytesused % 4;
|
||||
|
||||
/* V4L2 videodev will do the copy_from_user. */
|
||||
|
||||
memset(&pmem_buf, 0, sizeof(struct msm_pmem_info));
|
||||
pmem_buf.type = MSM_PMEM_OUTPUT2;
|
||||
pmem_buf.vaddr = (void *)pb->m.userptr;
|
||||
pmem_buf.y_off = 0;
|
||||
pmem_buf.fd = (int)pb->reserved;
|
||||
/* pmem_buf.cbcr_off = (y_size + y_pad); */
|
||||
pmem_buf.cbcr_off = (pb->bytesused + y_pad);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync, &pmem_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_qbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
|
||||
{
|
||||
/*
|
||||
__u32 y_size = 0;
|
||||
__u32 y_pad = 0;
|
||||
__u32 width = 0;
|
||||
__u32 height = 0;
|
||||
*/
|
||||
|
||||
__u32 y_pad = 0;
|
||||
|
||||
struct msm_pmem_info meminfo;
|
||||
struct msm_frame frame;
|
||||
static int cnt;
|
||||
|
||||
if ((pb->flags >> 16) & 0x0001) {
|
||||
/* this is for previwe */
|
||||
#if 0
|
||||
width = 640;
|
||||
height = 480;
|
||||
|
||||
/* V4L2 videodev will do the copy_from_user. */
|
||||
D("%s: width = %d, height = %d\n", __func__, width, height);
|
||||
y_size = width * height;
|
||||
y_pad = y_size % 4;
|
||||
#endif
|
||||
|
||||
y_pad = pb->bytesused % 4;
|
||||
|
||||
if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
|
||||
/* this qbuf is actually for releasing */
|
||||
|
||||
frame.buffer = pb->m.userptr;
|
||||
frame.y_off = 0;
|
||||
/* frame.cbcr_off = (y_size + y_pad); */
|
||||
frame.cbcr_off = (pb->bytesused + y_pad);
|
||||
frame.fd = pb->reserved;
|
||||
|
||||
D("V4L2_BUF_TYPE_PRIVATE: pb->bytesused = %d \n",
|
||||
pb->bytesused);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->put_frame(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
&frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
D("V4L2_BUF_TYPE_VIDEO_CAPTURE: pb->bytesused = %d \n",
|
||||
pb->bytesused);
|
||||
|
||||
meminfo.type = MSM_PMEM_OUTPUT2;
|
||||
meminfo.fd = (int)pb->reserved;
|
||||
meminfo.vaddr = (void *)pb->m.userptr;
|
||||
meminfo.y_off = 0;
|
||||
/* meminfo.cbcr_off = (y_size + y_pad); */
|
||||
meminfo.cbcr_off = (pb->bytesused + y_pad);
|
||||
if (cnt == PREVIEW_FRAMES_NUM - 1)
|
||||
meminfo.active = 0;
|
||||
else
|
||||
meminfo.active = 1;
|
||||
cnt++;
|
||||
g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
|
||||
&meminfo);
|
||||
} else if ((pb->flags) & 0x0001) {
|
||||
/* this is for snapshot */
|
||||
|
||||
__u32 y_size = 0;
|
||||
|
||||
if ((pb->flags >> 8) & 0x01) {
|
||||
|
||||
y_size = pb->bytesused;
|
||||
|
||||
meminfo.type = MSM_PMEM_THUMBAIL;
|
||||
} else if ((pb->flags >> 9) & 0x01) {
|
||||
|
||||
y_size = pb->bytesused;
|
||||
|
||||
meminfo.type = MSM_PMEM_MAINIMG;
|
||||
}
|
||||
|
||||
y_pad = y_size % 4;
|
||||
|
||||
meminfo.fd = (int)pb->reserved;
|
||||
meminfo.vaddr = (void *)pb->m.userptr;
|
||||
meminfo.y_off = 0;
|
||||
/* meminfo.cbcr_off = (y_size + y_pad); */
|
||||
meminfo.cbcr_off = (y_size + y_pad);
|
||||
meminfo.active = 1;
|
||||
g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
|
||||
&meminfo);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_dqbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
|
||||
{
|
||||
struct msm_frame frame;
|
||||
D("%s\n", __func__);
|
||||
|
||||
/* V4L2 videodev will do the copy_to_user. */
|
||||
if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
|
||||
D("%s, %d\n", __func__, __LINE__);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->get_frame(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
&frame);
|
||||
|
||||
pb->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
pb->m.userptr = (unsigned long)frame.buffer; /* FIXME */
|
||||
pb->reserved = (int)frame.fd;
|
||||
/* pb->length = (int)frame.cbcr_off; */
|
||||
|
||||
pb->bytesused = frame.cbcr_off;
|
||||
|
||||
} else if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
|
||||
__u32 y_pad = pb->bytesused % 4;
|
||||
|
||||
frame.buffer = pb->m.userptr;
|
||||
frame.y_off = 0;
|
||||
/* frame.cbcr_off = (y_size + y_pad); */
|
||||
frame.cbcr_off = (pb->bytesused + y_pad);
|
||||
frame.fd = pb->reserved;
|
||||
|
||||
g_pmsm_v4l2_dev->drv->put_frame(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
&frame);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_streamon(struct file *f, void *pctx, enum v4l2_buf_type i)
|
||||
{
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_STREAM_ON;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
ctrlcmd->length = 0;
|
||||
ctrlcmd->value = NULL;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->ctrl(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
ctrlcmd);
|
||||
|
||||
D("%s after drv->ctrl \n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_streamoff(struct file *f, void *pctx, enum v4l2_buf_type i)
|
||||
{
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_STREAM_OFF;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
ctrlcmd->length = 0;
|
||||
ctrlcmd->value = NULL;
|
||||
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
g_pmsm_v4l2_dev->drv->ctrl(
|
||||
g_pmsm_v4l2_dev->drv->sync,
|
||||
ctrlcmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_enum_fmt_overlay(struct file *f,
|
||||
void *pctx, struct v4l2_fmtdesc *pfmtdesc)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_enum_fmt_cap(struct file *f,
|
||||
void *pctx, struct v4l2_fmtdesc *pfmtdesc)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
|
||||
switch (pfmtdesc->index) {
|
||||
case 0:
|
||||
pfmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
pfmtdesc->flags = 0;
|
||||
strncpy(pfmtdesc->description, "YUV 4:2:0",
|
||||
sizeof(pfmtdesc->description));
|
||||
pfmtdesc->pixelformat = V4L2_PIX_FMT_YVU420;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_g_fmt_cap(struct file *f,
|
||||
void *pctx, struct v4l2_format *pfmt)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
pfmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
|
||||
pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
|
||||
pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
|
||||
pfmt->fmt.pix.field = V4L2_FIELD_ANY;
|
||||
pfmt->fmt.pix.bytesperline = 0;
|
||||
pfmt->fmt.pix.sizeimage = 0;
|
||||
pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
|
||||
pfmt->fmt.pix.priv = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_fmt_cap(struct file *f,
|
||||
void *pctx, struct v4l2_format *pfmt)
|
||||
{
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
|
||||
D("%s\n", __func__);
|
||||
|
||||
ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
|
||||
if (!ctrlcmd) {
|
||||
CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrlcmd->type = MSM_V4L2_VID_CAP_TYPE;
|
||||
ctrlcmd->length = sizeof(struct v4l2_format);
|
||||
ctrlcmd->value = pfmt;
|
||||
ctrlcmd->timeout_ms = 10000;
|
||||
|
||||
if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -1;
|
||||
|
||||
#if 0
|
||||
/* FIXEME */
|
||||
if (pfmt->fmt.pix.pixelformat != V4L2_PIX_FMT_YVU420)
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
/* Ok, but check other params, too. */
|
||||
|
||||
#if 0
|
||||
memcpy(&g_pmsm_v4l2_dev->current_pix_format.fmt.pix, pfmt,
|
||||
sizeof(struct v4l2_format));
|
||||
#endif
|
||||
|
||||
g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_g_fmt_overlay(struct file *f,
|
||||
void *pctx, struct v4l2_format *pfmt)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
pfmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
|
||||
pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
|
||||
pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
|
||||
pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
|
||||
pfmt->fmt.pix.field = V4L2_FIELD_ANY;
|
||||
pfmt->fmt.pix.bytesperline = 0;
|
||||
pfmt->fmt.pix.sizeimage = 0;
|
||||
pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
|
||||
pfmt->fmt.pix.priv = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_fmt_overlay(struct file *f,
|
||||
void *pctx, struct v4l2_format *pfmt)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_overlay(struct file *f, void *pctx, unsigned int i)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_g_jpegcomp(struct file *f,
|
||||
void *pctx, struct v4l2_jpegcompression *pcomp)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_s_jpegcomp(struct file *f,
|
||||
void *pctx, struct v4l2_jpegcompression *pcomp)
|
||||
{
|
||||
D("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
int msm_v4l2_read_proc(char *pbuf, char **start, off_t offset,
|
||||
int count, int *eof, void *data)
|
||||
{
|
||||
int len = 0;
|
||||
len += snprintf(pbuf, strlen("stats\n") + 1, "stats\n");
|
||||
|
||||
if (g_pmsm_v4l2_dev) {
|
||||
len += snprintf(pbuf, strlen("mode: ") + 1, "mode: ");
|
||||
|
||||
if (g_pmsm_v4l2_dev->current_cap_format.type
|
||||
== V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
len += snprintf(pbuf, strlen("capture\n") + 1,
|
||||
"capture\n");
|
||||
else
|
||||
len += snprintf(pbuf, strlen("unknown\n") + 1,
|
||||
"unknown\n");
|
||||
|
||||
len += snprintf(pbuf, 21, "resolution: %dx%d\n",
|
||||
g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
|
||||
width,
|
||||
g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
|
||||
height);
|
||||
|
||||
len += snprintf(pbuf,
|
||||
strlen("pixel format: ") + 1, "pixel format: ");
|
||||
if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.pixelformat
|
||||
== V4L2_PIX_FMT_YVU420)
|
||||
len += snprintf(pbuf, strlen("yvu420\n") + 1,
|
||||
"yvu420\n");
|
||||
else
|
||||
len += snprintf(pbuf, strlen("unknown\n") + 1,
|
||||
"unknown\n");
|
||||
|
||||
len += snprintf(pbuf, strlen("colorspace: ") + 1,
|
||||
"colorspace: ");
|
||||
if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.colorspace
|
||||
== V4L2_COLORSPACE_JPEG)
|
||||
len += snprintf(pbuf, strlen("jpeg\n") + 1, "jpeg\n");
|
||||
else
|
||||
len += snprintf(pbuf, strlen("unknown\n") + 1,
|
||||
"unknown\n");
|
||||
}
|
||||
|
||||
*eof = 1;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct v4l2_file_operations msm_v4l2_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = msm_v4l2_open,
|
||||
.poll = msm_v4l2_poll,
|
||||
.release = msm_v4l2_release,
|
||||
.ioctl = msm_v4l2_ioctl,
|
||||
};
|
||||
|
||||
static void msm_v4l2_dev_init(struct msm_v4l2_device *pmsm_v4l2_dev)
|
||||
{
|
||||
pmsm_v4l2_dev->read_queue_lock =
|
||||
__SPIN_LOCK_UNLOCKED(pmsm_v4l2_dev->read_queue_lock);
|
||||
INIT_LIST_HEAD(&pmsm_v4l2_dev->read_queue);
|
||||
}
|
||||
|
||||
static int msm_v4l2_try_fmt_cap(struct file *file,
|
||||
void *fh, struct v4l2_format *f)
|
||||
{
|
||||
/* FIXME */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mm_v4l2_try_fmt_type_private(struct file *file,
|
||||
void *fh, struct v4l2_format *f)
|
||||
{
|
||||
/* FIXME */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* should the following structure be used instead of the code in the function?
|
||||
* static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
|
||||
* .vidioc_querycap = ....
|
||||
* }
|
||||
*/
|
||||
static const struct v4l2_ioctl_ops msm_ioctl_ops = {
|
||||
.vidioc_querycap = msm_v4l2_querycap,
|
||||
.vidioc_s_std = msm_v4l2_s_std,
|
||||
|
||||
.vidioc_queryctrl = msm_v4l2_queryctrl,
|
||||
.vidioc_g_ctrl = msm_v4l2_g_ctrl,
|
||||
.vidioc_s_ctrl = msm_v4l2_s_ctrl,
|
||||
|
||||
.vidioc_reqbufs = msm_v4l2_reqbufs,
|
||||
.vidioc_querybuf = msm_v4l2_querybuf,
|
||||
.vidioc_qbuf = msm_v4l2_qbuf,
|
||||
.vidioc_dqbuf = msm_v4l2_dqbuf,
|
||||
|
||||
.vidioc_streamon = msm_v4l2_streamon,
|
||||
.vidioc_streamoff = msm_v4l2_streamoff,
|
||||
|
||||
.vidioc_enum_fmt_vid_overlay = msm_v4l2_enum_fmt_overlay,
|
||||
.vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt_cap,
|
||||
|
||||
.vidioc_try_fmt_vid_cap = msm_v4l2_try_fmt_cap,
|
||||
.vidioc_try_fmt_type_private = mm_v4l2_try_fmt_type_private,
|
||||
|
||||
.vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt_cap,
|
||||
.vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt_cap,
|
||||
.vidioc_g_fmt_vid_overlay = msm_v4l2_g_fmt_overlay,
|
||||
.vidioc_s_fmt_vid_overlay = msm_v4l2_s_fmt_overlay,
|
||||
.vidioc_overlay = msm_v4l2_overlay,
|
||||
|
||||
.vidioc_g_jpegcomp = msm_v4l2_g_jpegcomp,
|
||||
.vidioc_s_jpegcomp = msm_v4l2_s_jpegcomp,
|
||||
};
|
||||
|
||||
static int msm_v4l2_video_dev_init(struct video_device *pvd)
|
||||
{
|
||||
strncpy(pvd->name, MSM_APPS_ID_V4L2, sizeof(pvd->name));
|
||||
pvd->vfl_type = 1;
|
||||
pvd->fops = &msm_v4l2_fops;
|
||||
pvd->release = msm_v4l2_release_dev;
|
||||
pvd->minor = -1;
|
||||
pvd->ioctl_ops = &msm_ioctl_ops;
|
||||
return msm_v4l2_register(g_pmsm_v4l2_dev->drv);
|
||||
}
|
||||
|
||||
static int __init msm_v4l2_init(void)
|
||||
{
|
||||
int rc = -ENOMEM;
|
||||
struct video_device *pvdev = NULL;
|
||||
struct msm_v4l2_device *pmsm_v4l2_dev = NULL;
|
||||
D("%s\n", __func__);
|
||||
|
||||
pvdev = video_device_alloc();
|
||||
if (pvdev == NULL)
|
||||
return rc;
|
||||
|
||||
pmsm_v4l2_dev =
|
||||
kzalloc(sizeof(struct msm_v4l2_device), GFP_KERNEL);
|
||||
if (pmsm_v4l2_dev == NULL) {
|
||||
video_device_release(pvdev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
msm_v4l2_dev_init(pmsm_v4l2_dev);
|
||||
|
||||
g_pmsm_v4l2_dev = pmsm_v4l2_dev;
|
||||
g_pmsm_v4l2_dev->pvdev = pvdev;
|
||||
|
||||
g_pmsm_v4l2_dev->drv =
|
||||
kzalloc(sizeof(struct msm_v4l2_driver), GFP_KERNEL);
|
||||
if (!g_pmsm_v4l2_dev->drv) {
|
||||
video_device_release(pvdev);
|
||||
kfree(pmsm_v4l2_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = msm_v4l2_video_dev_init(pvdev);
|
||||
if (rc < 0) {
|
||||
video_device_release(pvdev);
|
||||
kfree(g_pmsm_v4l2_dev->drv);
|
||||
kfree(pmsm_v4l2_dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (video_register_device(pvdev, VFL_TYPE_GRABBER,
|
||||
MSM_V4L2_DEVNUM_YUV)) {
|
||||
D("failed to register device\n");
|
||||
video_device_release(pvdev);
|
||||
kfree(g_pmsm_v4l2_dev);
|
||||
g_pmsm_v4l2_dev = NULL;
|
||||
return -ENOENT;
|
||||
}
|
||||
#ifdef CONFIG_PROC_FS
|
||||
create_proc_read_entry(MSM_V4L2_PROC_NAME,
|
||||
0, NULL, msm_v4l2_read_proc, NULL);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit msm_v4l2_exit(void)
|
||||
{
|
||||
struct video_device *pvdev = g_pmsm_v4l2_dev->pvdev;
|
||||
D("%s\n", __func__);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
remove_proc_entry(MSM_V4L2_PROC_NAME, NULL);
|
||||
#endif
|
||||
video_unregister_device(pvdev);
|
||||
video_device_release(pvdev);
|
||||
|
||||
msm_v4l2_unregister(g_pmsm_v4l2_dev->drv);
|
||||
|
||||
kfree(g_pmsm_v4l2_dev->drv);
|
||||
g_pmsm_v4l2_dev->drv = NULL;
|
||||
|
||||
kfree(g_pmsm_v4l2_dev);
|
||||
g_pmsm_v4l2_dev = NULL;
|
||||
}
|
||||
|
||||
module_init(msm_v4l2_init);
|
||||
module_exit(msm_v4l2_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MSM V4L2 driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -0,0 +1,701 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include <linux/msm_adsp.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/android_pmem.h>
|
||||
#include <mach/msm_adsp.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/wait.h>
|
||||
#include "msm_vfe7x.h"
|
||||
|
||||
#define QDSP_CMDQUEUE QDSP_vfeCommandQueue
|
||||
|
||||
#define VFE_RESET_CMD 0
|
||||
#define VFE_START_CMD 1
|
||||
#define VFE_STOP_CMD 2
|
||||
#define VFE_FRAME_ACK 20
|
||||
#define STATS_AF_ACK 21
|
||||
#define STATS_WE_ACK 22
|
||||
|
||||
#define MSG_STOP_ACK 1
|
||||
#define MSG_SNAPSHOT 2
|
||||
#define MSG_OUTPUT1 6
|
||||
#define MSG_OUTPUT2 7
|
||||
#define MSG_STATS_AF 8
|
||||
#define MSG_STATS_WE 9
|
||||
|
||||
static struct msm_adsp_module *qcam_mod;
|
||||
static struct msm_adsp_module *vfe_mod;
|
||||
static struct msm_vfe_callback *resp;
|
||||
static void *extdata;
|
||||
static uint32_t extlen;
|
||||
|
||||
struct mutex vfe_lock;
|
||||
static void *vfe_syncdata;
|
||||
static uint8_t vfestopped;
|
||||
|
||||
static struct stop_event stopevent;
|
||||
|
||||
static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
|
||||
enum vfe_resp_msg type,
|
||||
void *data, void **ext, int32_t *elen)
|
||||
{
|
||||
switch (type) {
|
||||
case VFE_MSG_OUTPUT1:
|
||||
case VFE_MSG_OUTPUT2: {
|
||||
pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
|
||||
pinfo->cbcr_phy =
|
||||
((struct vfe_endframe *)data)->cbcr_address;
|
||||
|
||||
CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
|
||||
pinfo->y_phy, pinfo->cbcr_phy);
|
||||
|
||||
((struct vfe_frame_extra *)extdata)->bl_evencol =
|
||||
((struct vfe_endframe *)data)->blacklevelevencolumn;
|
||||
|
||||
((struct vfe_frame_extra *)extdata)->bl_oddcol =
|
||||
((struct vfe_endframe *)data)->blackleveloddcolumn;
|
||||
|
||||
((struct vfe_frame_extra *)extdata)->g_def_p_cnt =
|
||||
((struct vfe_endframe *)data)->greendefectpixelcount;
|
||||
|
||||
((struct vfe_frame_extra *)extdata)->r_b_def_p_cnt =
|
||||
((struct vfe_endframe *)data)->redbluedefectpixelcount;
|
||||
|
||||
*ext = extdata;
|
||||
*elen = extlen;
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_MSG_STATS_AF:
|
||||
case VFE_MSG_STATS_WE:
|
||||
pinfo->sbuf_phy = *(uint32_t *)data;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
|
||||
void (*getevent)(void *ptr, size_t len))
|
||||
{
|
||||
uint32_t evt_buf[3];
|
||||
struct msm_vfe_resp *rp;
|
||||
void *data;
|
||||
|
||||
len = (id == (uint16_t)-1) ? 0 : len;
|
||||
data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len, vfe_syncdata);
|
||||
|
||||
if (!data) {
|
||||
pr_err("rp: cannot allocate buffer\n");
|
||||
return;
|
||||
}
|
||||
rp = (struct msm_vfe_resp *)data;
|
||||
rp->evt_msg.len = len;
|
||||
|
||||
if (id == ((uint16_t)-1)) {
|
||||
/* event */
|
||||
rp->type = VFE_EVENT;
|
||||
rp->evt_msg.type = MSM_CAMERA_EVT;
|
||||
getevent(evt_buf, sizeof(evt_buf));
|
||||
rp->evt_msg.msg_id = evt_buf[0];
|
||||
resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata);
|
||||
} else {
|
||||
/* messages */
|
||||
rp->evt_msg.type = MSM_CAMERA_MSG;
|
||||
rp->evt_msg.msg_id = id;
|
||||
rp->evt_msg.data = rp + 1;
|
||||
getevent(rp->evt_msg.data, len);
|
||||
|
||||
switch (rp->evt_msg.msg_id) {
|
||||
case MSG_SNAPSHOT:
|
||||
rp->type = VFE_MSG_SNAPSHOT;
|
||||
break;
|
||||
|
||||
case MSG_OUTPUT1:
|
||||
rp->type = VFE_MSG_OUTPUT1;
|
||||
vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT1,
|
||||
rp->evt_msg.data, &(rp->extdata),
|
||||
&(rp->extlen));
|
||||
break;
|
||||
|
||||
case MSG_OUTPUT2:
|
||||
rp->type = VFE_MSG_OUTPUT2;
|
||||
vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT2,
|
||||
rp->evt_msg.data, &(rp->extdata),
|
||||
&(rp->extlen));
|
||||
break;
|
||||
|
||||
case MSG_STATS_AF:
|
||||
rp->type = VFE_MSG_STATS_AF;
|
||||
vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
|
||||
rp->evt_msg.data, NULL, NULL);
|
||||
break;
|
||||
|
||||
case MSG_STATS_WE:
|
||||
rp->type = VFE_MSG_STATS_WE;
|
||||
vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
|
||||
rp->evt_msg.data, NULL, NULL);
|
||||
|
||||
CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
|
||||
break;
|
||||
|
||||
case MSG_STOP_ACK:
|
||||
rp->type = VFE_MSG_GENERAL;
|
||||
stopevent.state = 1;
|
||||
wake_up(&stopevent.wait);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
rp->type = VFE_MSG_GENERAL;
|
||||
break;
|
||||
}
|
||||
resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe_syncdata);
|
||||
}
|
||||
}
|
||||
|
||||
static struct msm_adsp_ops vfe_7x_sync = {
|
||||
.event = vfe_7x_ops,
|
||||
};
|
||||
|
||||
static int vfe_7x_enable(struct camera_enable_cmd *enable)
|
||||
{
|
||||
int rc = -EFAULT;
|
||||
|
||||
if (!strcmp(enable->name, "QCAMTASK"))
|
||||
rc = msm_adsp_enable(qcam_mod);
|
||||
else if (!strcmp(enable->name, "VFETASK"))
|
||||
rc = msm_adsp_enable(vfe_mod);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_7x_disable(struct camera_enable_cmd *enable,
|
||||
struct platform_device *dev __attribute__((unused)))
|
||||
{
|
||||
int rc = -EFAULT;
|
||||
|
||||
if (!strcmp(enable->name, "QCAMTASK"))
|
||||
rc = msm_adsp_disable(qcam_mod);
|
||||
else if (!strcmp(enable->name, "VFETASK"))
|
||||
rc = msm_adsp_disable(vfe_mod);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_7x_stop(void)
|
||||
{
|
||||
int rc = 0;
|
||||
uint32_t stopcmd = VFE_STOP_CMD;
|
||||
rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
|
||||
&stopcmd, sizeof(uint32_t));
|
||||
if (rc < 0) {
|
||||
CDBG("%s:%d: failed rc = %d \n", __func__, __LINE__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
stopevent.state = 0;
|
||||
rc = wait_event_timeout(stopevent.wait,
|
||||
stopevent.state != 0,
|
||||
msecs_to_jiffies(stopevent.timeout));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void vfe_7x_release(struct platform_device *pdev)
|
||||
{
|
||||
mutex_lock(&vfe_lock);
|
||||
vfe_syncdata = NULL;
|
||||
mutex_unlock(&vfe_lock);
|
||||
|
||||
if (!vfestopped) {
|
||||
CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
|
||||
vfe_7x_stop();
|
||||
} else
|
||||
vfestopped = 0;
|
||||
|
||||
msm_adsp_disable(qcam_mod);
|
||||
msm_adsp_disable(vfe_mod);
|
||||
|
||||
msm_adsp_put(qcam_mod);
|
||||
msm_adsp_put(vfe_mod);
|
||||
|
||||
msm_camio_disable(pdev);
|
||||
|
||||
kfree(extdata);
|
||||
extlen = 0;
|
||||
}
|
||||
|
||||
static int vfe_7x_init(struct msm_vfe_callback *presp,
|
||||
struct platform_device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
init_waitqueue_head(&stopevent.wait);
|
||||
stopevent.timeout = 200;
|
||||
stopevent.state = 0;
|
||||
|
||||
if (presp && presp->vfe_resp)
|
||||
resp = presp;
|
||||
else
|
||||
return -EFAULT;
|
||||
|
||||
/* Bring up all the required GPIOs and Clocks */
|
||||
rc = msm_camio_enable(dev);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
msm_camio_camif_pad_reg_reset();
|
||||
|
||||
extlen = sizeof(struct vfe_frame_extra);
|
||||
|
||||
extdata =
|
||||
kmalloc(sizeof(extlen), GFP_ATOMIC);
|
||||
if (!extdata) {
|
||||
rc = -ENOMEM;
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
|
||||
if (rc) {
|
||||
rc = -EBUSY;
|
||||
goto get_qcam_fail;
|
||||
}
|
||||
|
||||
rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
|
||||
if (rc) {
|
||||
rc = -EBUSY;
|
||||
goto get_vfe_fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
get_vfe_fail:
|
||||
msm_adsp_put(qcam_mod);
|
||||
get_qcam_fail:
|
||||
kfree(extdata);
|
||||
init_fail:
|
||||
extlen = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_7x_config_axi(int mode,
|
||||
struct axidata *ad, struct axiout *ao)
|
||||
{
|
||||
struct msm_pmem_region *regptr;
|
||||
unsigned long *bptr;
|
||||
int cnt;
|
||||
|
||||
int rc = 0;
|
||||
|
||||
if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
|
||||
regptr = ad->region;
|
||||
|
||||
CDBG("bufnum1 = %d\n", ad->bufnum1);
|
||||
CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
|
||||
regptr->paddr, regptr->y_off, regptr->cbcr_off);
|
||||
|
||||
bptr = &ao->output1buffer1_y_phy;
|
||||
for (cnt = 0; cnt < ad->bufnum1; cnt++) {
|
||||
*bptr = regptr->paddr + regptr->y_off;
|
||||
bptr++;
|
||||
*bptr = regptr->paddr + regptr->cbcr_off;
|
||||
|
||||
bptr++;
|
||||
regptr++;
|
||||
}
|
||||
|
||||
regptr--;
|
||||
for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
|
||||
*bptr = regptr->paddr + regptr->y_off;
|
||||
bptr++;
|
||||
*bptr = regptr->paddr + regptr->cbcr_off;
|
||||
bptr++;
|
||||
}
|
||||
} /* if OUTPUT1 or Both */
|
||||
|
||||
if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
|
||||
regptr = &(ad->region[ad->bufnum1]);
|
||||
|
||||
CDBG("bufnum2 = %d\n", ad->bufnum2);
|
||||
CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
|
||||
regptr->paddr, regptr->y_off, regptr->cbcr_off);
|
||||
|
||||
bptr = &ao->output2buffer1_y_phy;
|
||||
for (cnt = 0; cnt < ad->bufnum2; cnt++) {
|
||||
*bptr = regptr->paddr + regptr->y_off;
|
||||
bptr++;
|
||||
*bptr = regptr->paddr + regptr->cbcr_off;
|
||||
|
||||
bptr++;
|
||||
regptr++;
|
||||
}
|
||||
|
||||
regptr--;
|
||||
for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
|
||||
*bptr = regptr->paddr + regptr->y_off;
|
||||
bptr++;
|
||||
*bptr = regptr->paddr + regptr->cbcr_off;
|
||||
bptr++;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
|
||||
{
|
||||
struct msm_pmem_region *regptr;
|
||||
unsigned char buf[256];
|
||||
|
||||
struct vfe_stats_ack sack;
|
||||
struct axidata *axid;
|
||||
uint32_t i;
|
||||
|
||||
struct vfe_stats_we_cfg *scfg = NULL;
|
||||
struct vfe_stats_af_cfg *sfcfg = NULL;
|
||||
|
||||
struct axiout *axio = NULL;
|
||||
void *cmd_data = NULL;
|
||||
void *cmd_data_alloc = NULL;
|
||||
long rc = 0;
|
||||
struct msm_vfe_command_7k *vfecmd;
|
||||
|
||||
vfecmd =
|
||||
kmalloc(sizeof(struct msm_vfe_command_7k),
|
||||
GFP_ATOMIC);
|
||||
if (!vfecmd) {
|
||||
pr_err("vfecmd alloc failed!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
|
||||
cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
|
||||
cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
|
||||
if (copy_from_user(vfecmd,
|
||||
(void __user *)(cmd->value),
|
||||
sizeof(struct msm_vfe_command_7k))) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cmd->cmd_type) {
|
||||
case CMD_STATS_ENABLE:
|
||||
case CMD_STATS_AXI_CFG: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
scfg =
|
||||
kmalloc(sizeof(struct vfe_stats_we_cfg),
|
||||
GFP_ATOMIC);
|
||||
if (!scfg) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(scfg,
|
||||
(void __user *)(vfecmd->value),
|
||||
vfecmd->length)) {
|
||||
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
|
||||
axid->bufnum1, scfg->wb_expstatsenable);
|
||||
|
||||
if (axid->bufnum1 > 0) {
|
||||
regptr = axid->region;
|
||||
|
||||
for (i = 0; i < axid->bufnum1; i++) {
|
||||
|
||||
CDBG("STATS_ENABLE, phy = 0x%lx\n",
|
||||
regptr->paddr);
|
||||
|
||||
scfg->wb_expstatoutputbuffer[i] =
|
||||
(void *)regptr->paddr;
|
||||
regptr++;
|
||||
}
|
||||
|
||||
cmd_data = scfg;
|
||||
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
goto config_done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STATS_AF_ENABLE:
|
||||
case CMD_STATS_AF_AXI_CFG: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
sfcfg =
|
||||
kmalloc(sizeof(struct vfe_stats_af_cfg),
|
||||
GFP_ATOMIC);
|
||||
|
||||
if (!sfcfg) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(sfcfg,
|
||||
(void __user *)(vfecmd->value),
|
||||
vfecmd->length)) {
|
||||
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
|
||||
axid->bufnum1, sfcfg->af_enable);
|
||||
|
||||
if (axid->bufnum1 > 0) {
|
||||
regptr = axid->region;
|
||||
|
||||
for (i = 0; i < axid->bufnum1; i++) {
|
||||
|
||||
CDBG("STATS_ENABLE, phy = 0x%lx\n",
|
||||
regptr->paddr);
|
||||
|
||||
sfcfg->af_outbuf[i] =
|
||||
(void *)regptr->paddr;
|
||||
|
||||
regptr++;
|
||||
}
|
||||
|
||||
cmd_data = sfcfg;
|
||||
|
||||
} else {
|
||||
rc = -EINVAL;
|
||||
goto config_done;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_FRAME_BUF_RELEASE: {
|
||||
struct msm_frame *b;
|
||||
unsigned long p;
|
||||
struct vfe_outputack fack;
|
||||
if (!data) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
b = (struct msm_frame *)(cmd->value);
|
||||
p = *(unsigned long *)data;
|
||||
|
||||
fack.header = VFE_FRAME_ACK;
|
||||
|
||||
fack.output2newybufferaddress =
|
||||
(void *)(p + b->y_off);
|
||||
|
||||
fack.output2newcbcrbufferaddress =
|
||||
(void *)(p + b->cbcr_off);
|
||||
|
||||
vfecmd->queue = QDSP_CMDQUEUE;
|
||||
vfecmd->length = sizeof(struct vfe_outputack);
|
||||
cmd_data = &fack;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SNAP_BUF_RELEASE:
|
||||
break;
|
||||
|
||||
case CMD_STATS_BUF_RELEASE: {
|
||||
CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
|
||||
if (!data) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
sack.header = STATS_WE_ACK;
|
||||
sack.bufaddr = (void *)*(uint32_t *)data;
|
||||
|
||||
vfecmd->queue = QDSP_CMDQUEUE;
|
||||
vfecmd->length = sizeof(struct vfe_stats_ack);
|
||||
cmd_data = &sack;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STATS_AF_BUF_RELEASE: {
|
||||
CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
|
||||
if (!data) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
sack.header = STATS_AF_ACK;
|
||||
sack.bufaddr = (void *)*(uint32_t *)data;
|
||||
|
||||
vfecmd->queue = QDSP_CMDQUEUE;
|
||||
vfecmd->length = sizeof(struct vfe_stats_ack);
|
||||
cmd_data = &sack;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_GENERAL:
|
||||
case CMD_STATS_DISABLE: {
|
||||
if (vfecmd->length > 256) {
|
||||
cmd_data_alloc =
|
||||
cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
|
||||
if (!cmd_data) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
} else
|
||||
cmd_data = buf;
|
||||
|
||||
if (copy_from_user(cmd_data,
|
||||
(void __user *)(vfecmd->value),
|
||||
vfecmd->length)) {
|
||||
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
if (vfecmd->queue == QDSP_CMDQUEUE) {
|
||||
switch (*(uint32_t *)cmd_data) {
|
||||
case VFE_RESET_CMD:
|
||||
msm_camio_vfe_blk_reset();
|
||||
msm_camio_camif_pad_reg_reset_2();
|
||||
vfestopped = 0;
|
||||
break;
|
||||
|
||||
case VFE_START_CMD:
|
||||
msm_camio_camif_pad_reg_reset_2();
|
||||
vfestopped = 0;
|
||||
break;
|
||||
|
||||
case VFE_STOP_CMD:
|
||||
vfestopped = 1;
|
||||
goto config_send;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} /* QDSP_CMDQUEUE */
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_OUT1: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
|
||||
if (!axio) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(axio, (void *)(vfecmd->value),
|
||||
sizeof(struct axiout))) {
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
vfe_7x_config_axi(OUTPUT_1, axid, axio);
|
||||
|
||||
cmd_data = axio;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_OUT2:
|
||||
case CMD_RAW_PICT_AXI_CFG: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
|
||||
if (!axio) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(axio, (void __user *)(vfecmd->value),
|
||||
sizeof(struct axiout))) {
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
vfe_7x_config_axi(OUTPUT_2, axid, axio);
|
||||
cmd_data = axio;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_SNAP_O1_AND_O2: {
|
||||
axid = data;
|
||||
if (!axid) {
|
||||
rc = -EFAULT;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
|
||||
if (!axio) {
|
||||
rc = -ENOMEM;
|
||||
goto config_failure;
|
||||
}
|
||||
|
||||
if (copy_from_user(axio, (void __user *)(vfecmd->value),
|
||||
sizeof(struct axiout))) {
|
||||
rc = -EFAULT;
|
||||
goto config_done;
|
||||
}
|
||||
|
||||
vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
|
||||
|
||||
cmd_data = axio;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
if (vfestopped)
|
||||
goto config_done;
|
||||
|
||||
config_send:
|
||||
CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
|
||||
rc = msm_adsp_write(vfe_mod, vfecmd->queue,
|
||||
cmd_data, vfecmd->length);
|
||||
|
||||
config_done:
|
||||
if (cmd_data_alloc != NULL)
|
||||
kfree(cmd_data_alloc);
|
||||
|
||||
config_failure:
|
||||
kfree(scfg);
|
||||
kfree(axio);
|
||||
kfree(vfecmd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
|
||||
{
|
||||
mutex_init(&vfe_lock);
|
||||
fptr->vfe_init = vfe_7x_init;
|
||||
fptr->vfe_enable = vfe_7x_enable;
|
||||
fptr->vfe_config = vfe_7x_config;
|
||||
fptr->vfe_disable = vfe_7x_disable;
|
||||
fptr->vfe_release = vfe_7x_release;
|
||||
vfe_syncdata = data;
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
#ifndef __MSM_VFE7X_H__
|
||||
#define __MSM_VFE7X_H__
|
||||
#include <media/msm_camera.h>
|
||||
#include <mach/camera.h>
|
||||
|
||||
struct vfe_frame_extra {
|
||||
uint32_t bl_evencol;
|
||||
uint32_t bl_oddcol;
|
||||
uint16_t g_def_p_cnt;
|
||||
uint16_t r_b_def_p_cnt;
|
||||
};
|
||||
|
||||
struct vfe_endframe {
|
||||
uint32_t y_address;
|
||||
uint32_t cbcr_address;
|
||||
|
||||
unsigned int blacklevelevencolumn:23;
|
||||
uint16_t reserved1:9;
|
||||
unsigned int blackleveloddcolumn:23;
|
||||
uint16_t reserved2:9;
|
||||
|
||||
uint16_t greendefectpixelcount:8;
|
||||
uint16_t reserved3:8;
|
||||
uint16_t redbluedefectpixelcount:8;
|
||||
uint16_t reserved4:8;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
struct vfe_outputack {
|
||||
uint32_t header;
|
||||
void *output2newybufferaddress;
|
||||
void *output2newcbcrbufferaddress;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
struct vfe_stats_ack {
|
||||
uint32_t header;
|
||||
/* MUST BE 64 bit ALIGNED */
|
||||
void *bufaddr;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
/* AXI Output Config Command sent to DSP */
|
||||
struct axiout {
|
||||
uint32_t cmdheader:32;
|
||||
int outputmode:3;
|
||||
uint8_t format:2;
|
||||
uint32_t /* reserved */ : 27;
|
||||
|
||||
/* AXI Output 1 Y Configuration, Part 1 */
|
||||
uint32_t out1yimageheight:12;
|
||||
uint32_t /* reserved */ : 4;
|
||||
uint32_t out1yimagewidthin64bitwords:10;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 1 Y Configuration, Part 2 */
|
||||
uint8_t out1yburstlen:2;
|
||||
uint32_t out1ynumrows:12;
|
||||
uint32_t out1yrowincin64bitincs:12;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 1 CbCr Configuration, Part 1 */
|
||||
uint32_t out1cbcrimageheight:12;
|
||||
uint32_t /* reserved */ : 4;
|
||||
uint32_t out1cbcrimagewidthin64bitwords:10;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 1 CbCr Configuration, Part 2 */
|
||||
uint8_t out1cbcrburstlen:2;
|
||||
uint32_t out1cbcrnumrows:12;
|
||||
uint32_t out1cbcrrowincin64bitincs:12;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 2 Y Configuration, Part 1 */
|
||||
uint32_t out2yimageheight:12;
|
||||
uint32_t /* reserved */ : 4;
|
||||
uint32_t out2yimagewidthin64bitwords:10;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 2 Y Configuration, Part 2 */
|
||||
uint8_t out2yburstlen:2;
|
||||
uint32_t out2ynumrows:12;
|
||||
uint32_t out2yrowincin64bitincs:12;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 2 CbCr Configuration, Part 1 */
|
||||
uint32_t out2cbcrimageheight:12;
|
||||
uint32_t /* reserved */ : 4;
|
||||
uint32_t out2cbcrimagewidtein64bitwords:10;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* AXI Output 2 CbCr Configuration, Part 2 */
|
||||
uint8_t out2cbcrburstlen:2;
|
||||
uint32_t out2cbcrnumrows:12;
|
||||
uint32_t out2cbcrrowincin64bitincs:12;
|
||||
uint32_t /* reserved */ : 6;
|
||||
|
||||
/* Address configuration:
|
||||
* output1 phisycal address */
|
||||
unsigned long output1buffer1_y_phy;
|
||||
unsigned long output1buffer1_cbcr_phy;
|
||||
unsigned long output1buffer2_y_phy;
|
||||
unsigned long output1buffer2_cbcr_phy;
|
||||
unsigned long output1buffer3_y_phy;
|
||||
unsigned long output1buffer3_cbcr_phy;
|
||||
unsigned long output1buffer4_y_phy;
|
||||
unsigned long output1buffer4_cbcr_phy;
|
||||
unsigned long output1buffer5_y_phy;
|
||||
unsigned long output1buffer5_cbcr_phy;
|
||||
unsigned long output1buffer6_y_phy;
|
||||
unsigned long output1buffer6_cbcr_phy;
|
||||
unsigned long output1buffer7_y_phy;
|
||||
unsigned long output1buffer7_cbcr_phy;
|
||||
unsigned long output1buffer8_y_phy;
|
||||
unsigned long output1buffer8_cbcr_phy;
|
||||
|
||||
/* output2 phisycal address */
|
||||
unsigned long output2buffer1_y_phy;
|
||||
unsigned long output2buffer1_cbcr_phy;
|
||||
unsigned long output2buffer2_y_phy;
|
||||
unsigned long output2buffer2_cbcr_phy;
|
||||
unsigned long output2buffer3_y_phy;
|
||||
unsigned long output2buffer3_cbcr_phy;
|
||||
unsigned long output2buffer4_y_phy;
|
||||
unsigned long output2buffer4_cbcr_phy;
|
||||
unsigned long output2buffer5_y_phy;
|
||||
unsigned long output2buffer5_cbcr_phy;
|
||||
unsigned long output2buffer6_y_phy;
|
||||
unsigned long output2buffer6_cbcr_phy;
|
||||
unsigned long output2buffer7_y_phy;
|
||||
unsigned long output2buffer7_cbcr_phy;
|
||||
unsigned long output2buffer8_y_phy;
|
||||
unsigned long output2buffer8_cbcr_phy;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
struct vfe_stats_we_cfg {
|
||||
uint32_t header;
|
||||
|
||||
/* White Balance/Exposure Statistic Selection */
|
||||
uint8_t wb_expstatsenable:1;
|
||||
uint8_t wb_expstatbuspriorityselection:1;
|
||||
unsigned int wb_expstatbuspriorityvalue:4;
|
||||
unsigned int /* reserved */ : 26;
|
||||
|
||||
/* White Balance/Exposure Statistic Configuration, Part 1 */
|
||||
uint8_t exposurestatregions:1;
|
||||
uint8_t exposurestatsubregions:1;
|
||||
unsigned int /* reserved */ : 14;
|
||||
|
||||
unsigned int whitebalanceminimumy:8;
|
||||
unsigned int whitebalancemaximumy:8;
|
||||
|
||||
/* White Balance/Exposure Statistic Configuration, Part 2 */
|
||||
uint8_t wb_expstatslopeofneutralregionline[
|
||||
NUM_WB_EXP_NEUTRAL_REGION_LINES];
|
||||
|
||||
/* White Balance/Exposure Statistic Configuration, Part 3 */
|
||||
unsigned int wb_expstatcrinterceptofneutralregionline2:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
unsigned int wb_expstatcbinterceptofneutralreginnline1:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
|
||||
/* White Balance/Exposure Statistic Configuration, Part 4 */
|
||||
unsigned int wb_expstatcrinterceptofneutralregionline4:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
unsigned int wb_expstatcbinterceptofneutralregionline3:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
|
||||
/* White Balance/Exposure Statistic Output Buffer Header */
|
||||
unsigned int wb_expmetricheaderpattern:8;
|
||||
unsigned int /* reserved */ : 24;
|
||||
|
||||
/* White Balance/Exposure Statistic Output Buffers-MUST
|
||||
* BE 64 bit ALIGNED */
|
||||
void *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
struct vfe_stats_af_cfg {
|
||||
uint32_t header;
|
||||
|
||||
/* Autofocus Statistic Selection */
|
||||
uint8_t af_enable:1;
|
||||
uint8_t af_busprioritysel:1;
|
||||
unsigned int af_buspriorityval:4;
|
||||
unsigned int /* reserved */ : 26;
|
||||
|
||||
/* Autofocus Statistic Configuration, Part 1 */
|
||||
unsigned int af_singlewinvoffset:12;
|
||||
unsigned int /* reserved */ : 4;
|
||||
unsigned int af_singlewinhoffset:12;
|
||||
unsigned int /* reserved */ : 3;
|
||||
uint8_t af_winmode:1;
|
||||
|
||||
/* Autofocus Statistic Configuration, Part 2 */
|
||||
unsigned int af_singglewinvh:11;
|
||||
unsigned int /* reserved */ : 5;
|
||||
unsigned int af_singlewinhw:11;
|
||||
unsigned int /* reserved */ : 5;
|
||||
|
||||
/* Autofocus Statistic Configuration, Parts 3-6 */
|
||||
uint8_t af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
|
||||
|
||||
/* Autofocus Statistic Configuration, Part 7 */
|
||||
signed int af_metrichpfcoefa00:5;
|
||||
signed int af_metrichpfcoefa04:5;
|
||||
unsigned int af_metricmaxval:11;
|
||||
uint8_t af_metricsel:1;
|
||||
unsigned int /* reserved */ : 10;
|
||||
|
||||
/* Autofocus Statistic Configuration, Part 8 */
|
||||
signed int af_metrichpfcoefa20:5;
|
||||
signed int af_metrichpfcoefa21:5;
|
||||
signed int af_metrichpfcoefa22:5;
|
||||
signed int af_metrichpfcoefa23:5;
|
||||
signed int af_metrichpfcoefa24:5;
|
||||
unsigned int /* reserved */ : 7;
|
||||
|
||||
/* Autofocus Statistic Output Buffer Header */
|
||||
unsigned int af_metrichp:8;
|
||||
unsigned int /* reserved */ : 24;
|
||||
|
||||
/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
|
||||
void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
|
||||
} __attribute__((packed, aligned(4))); /* VFE_StatsAutofocusConfigCmdType */
|
||||
|
||||
struct msm_camera_frame_msg {
|
||||
unsigned long output_y_address;
|
||||
unsigned long output_cbcr_address;
|
||||
|
||||
unsigned int blacklevelevenColumn:23;
|
||||
uint16_t reserved1:9;
|
||||
unsigned int blackleveloddColumn:23;
|
||||
uint16_t reserved2:9;
|
||||
|
||||
uint16_t greendefectpixelcount:8;
|
||||
uint16_t reserved3:8;
|
||||
uint16_t redbluedefectpixelcount:8;
|
||||
uint16_t reserved4:8;
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
/* New one for 7k */
|
||||
struct msm_vfe_command_7k {
|
||||
uint16_t queue;
|
||||
uint16_t length;
|
||||
void *value;
|
||||
};
|
||||
|
||||
struct stop_event {
|
||||
wait_queue_head_t wait;
|
||||
int state;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __MSM_VFE7X_H__ */
|
|
@ -0,0 +1,756 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <mach/irqs.h>
|
||||
#include "msm_vfe8x_proc.h"
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
|
||||
struct mutex vfe_lock;
|
||||
static void *vfe_syncdata;
|
||||
|
||||
static int vfe_enable(struct camera_enable_cmd *enable)
|
||||
{
|
||||
int rc = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_disable(struct camera_enable_cmd *enable,
|
||||
struct platform_device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
vfe_stop();
|
||||
|
||||
msm_camio_disable(dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void vfe_release(struct platform_device *dev)
|
||||
{
|
||||
msm_camio_disable(dev);
|
||||
vfe_cmd_release(dev);
|
||||
|
||||
mutex_lock(&vfe_lock);
|
||||
vfe_syncdata = NULL;
|
||||
mutex_unlock(&vfe_lock);
|
||||
}
|
||||
|
||||
static void vfe_config_axi(int mode,
|
||||
struct axidata *ad, struct vfe_cmd_axi_output_config *ao)
|
||||
{
|
||||
struct msm_pmem_region *regptr;
|
||||
int i, j;
|
||||
uint32_t *p1, *p2;
|
||||
|
||||
if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
|
||||
regptr = ad->region;
|
||||
for (i = 0;
|
||||
i < ad->bufnum1; i++) {
|
||||
|
||||
p1 = &(ao->output1.outputY.outFragments[i][0]);
|
||||
p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
|
||||
|
||||
for (j = 0;
|
||||
j < ao->output1.fragmentCount; j++) {
|
||||
|
||||
*p1 = regptr->paddr + regptr->y_off;
|
||||
p1++;
|
||||
|
||||
*p2 = regptr->paddr + regptr->cbcr_off;
|
||||
p2++;
|
||||
}
|
||||
regptr++;
|
||||
}
|
||||
} /* if OUTPUT1 or Both */
|
||||
|
||||
if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
|
||||
|
||||
regptr = &(ad->region[ad->bufnum1]);
|
||||
CDBG("bufnum2 = %d\n", ad->bufnum2);
|
||||
|
||||
for (i = 0;
|
||||
i < ad->bufnum2; i++) {
|
||||
|
||||
p1 = &(ao->output2.outputY.outFragments[i][0]);
|
||||
p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
|
||||
|
||||
CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n",
|
||||
regptr->paddr, regptr->y_off, regptr->cbcr_off);
|
||||
|
||||
for (j = 0;
|
||||
j < ao->output2.fragmentCount; j++) {
|
||||
|
||||
*p1 = regptr->paddr + regptr->y_off;
|
||||
CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
|
||||
p1++;
|
||||
|
||||
*p2 = regptr->paddr + regptr->cbcr_off;
|
||||
CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
|
||||
p2++;
|
||||
}
|
||||
regptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
CDBG("vfe_proc_general: cmdID = %d\n", cmd->id);
|
||||
|
||||
switch (cmd->id) {
|
||||
case VFE_CMD_ID_RESET:
|
||||
msm_camio_vfe_blk_reset();
|
||||
msm_camio_camif_pad_reg_reset_2();
|
||||
vfe_reset();
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_START: {
|
||||
struct vfe_cmd_start start;
|
||||
if (copy_from_user(&start,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
/* msm_camio_camif_pad_reg_reset_2(); */
|
||||
msm_camio_camif_pad_reg_reset();
|
||||
vfe_start(&start);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CAMIF_CONFIG: {
|
||||
struct vfe_cmd_camif_config camif;
|
||||
if (copy_from_user(&camif,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_camif_config(&camif);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
|
||||
struct vfe_cmd_black_level_config bl;
|
||||
if (copy_from_user(&bl,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_black_level_config(&bl);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_ROLL_OFF_CONFIG: {
|
||||
struct vfe_cmd_roll_off_config rolloff;
|
||||
if (copy_from_user(&rolloff,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_roll_off_config(&rolloff);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
|
||||
struct vfe_cmd_demux_channel_gain_config demuxc;
|
||||
if (copy_from_user(&demuxc,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
/* demux is always enabled. */
|
||||
vfe_demux_channel_gain_config(&demuxc);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMOSAIC_CONFIG: {
|
||||
struct vfe_cmd_demosaic_config demosaic;
|
||||
if (copy_from_user(&demosaic,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_demosaic_config(&demosaic);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_FOV_CROP_CONFIG:
|
||||
case VFE_CMD_ID_FOV_CROP_UPDATE: {
|
||||
struct vfe_cmd_fov_crop_config fov;
|
||||
if (copy_from_user(&fov,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_fov_crop_config(&fov);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_MAIN_SCALER_CONFIG:
|
||||
case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
|
||||
struct vfe_cmd_main_scaler_config mainds;
|
||||
if (copy_from_user(&mainds,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_main_scaler_config(&mainds);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
|
||||
case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
|
||||
struct vfe_cmd_white_balance_config wb;
|
||||
if (copy_from_user(&wb,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_white_balance_config(&wb);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
|
||||
case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
|
||||
struct vfe_cmd_color_correction_config cc;
|
||||
if (copy_from_user(&cc,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_color_correction_config(&cc);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_LA_CONFIG: {
|
||||
struct vfe_cmd_la_config la;
|
||||
if (copy_from_user(&la,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_la_config(&la);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
|
||||
struct vfe_cmd_rgb_gamma_config rgb;
|
||||
if (copy_from_user(&rgb,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
rc = vfe_rgb_gamma_config(&rgb);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
|
||||
case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
|
||||
struct vfe_cmd_chroma_enhan_config chrom;
|
||||
if (copy_from_user(&chrom,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_chroma_enhan_config(&chrom);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
|
||||
case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
|
||||
struct vfe_cmd_chroma_suppression_config chromsup;
|
||||
if (copy_from_user(&chromsup,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_chroma_sup_config(&chromsup);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_ASF_CONFIG: {
|
||||
struct vfe_cmd_asf_config asf;
|
||||
if (copy_from_user(&asf,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_asf_config(&asf);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_SCALER2Y_CONFIG:
|
||||
case VFE_CMD_ID_SCALER2Y_UPDATE: {
|
||||
struct vfe_cmd_scaler2_config ds2y;
|
||||
if (copy_from_user(&ds2y,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_scaler2y_config(&ds2y);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_SCALER2CbCr_CONFIG:
|
||||
case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
|
||||
struct vfe_cmd_scaler2_config ds2cbcr;
|
||||
if (copy_from_user(&ds2cbcr,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_scaler2cbcr_config(&ds2cbcr);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
|
||||
struct vfe_cmd_chroma_subsample_config sub;
|
||||
if (copy_from_user(&sub,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_chroma_subsample_config(&sub);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
|
||||
struct vfe_cmd_frame_skip_config fskip;
|
||||
if (copy_from_user(&fskip,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_frame_skip_config(&fskip);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
|
||||
struct vfe_cmd_output_clamp_config clamp;
|
||||
if (copy_from_user(&clamp,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_output_clamp_config(&clamp);
|
||||
}
|
||||
break;
|
||||
|
||||
/* module update commands */
|
||||
case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
|
||||
struct vfe_cmd_black_level_config blk;
|
||||
if (copy_from_user(&blk,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_black_level_update(&blk);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
|
||||
struct vfe_cmd_demux_channel_gain_config dmu;
|
||||
if (copy_from_user(&dmu,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_demux_channel_gain_update(&dmu);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
|
||||
struct vfe_cmd_demosaic_bpc_update demo_bpc;
|
||||
if (copy_from_user(&demo_bpc,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_demosaic_bpc_update(&demo_bpc);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
|
||||
struct vfe_cmd_demosaic_abf_update demo_abf;
|
||||
if (copy_from_user(&demo_abf,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_demosaic_abf_update(&demo_abf);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_LA_UPDATE: {
|
||||
struct vfe_cmd_la_config la;
|
||||
if (copy_from_user(&la,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_la_update(&la);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
|
||||
struct vfe_cmd_rgb_gamma_config rgb;
|
||||
if (copy_from_user(&rgb,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
rc = vfe_rgb_gamma_update(&rgb);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_ASF_UPDATE: {
|
||||
struct vfe_cmd_asf_update asf;
|
||||
if (copy_from_user(&asf,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_asf_update(&asf);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
|
||||
struct vfe_cmd_frame_skip_update fskip;
|
||||
if (copy_from_user(&fskip,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_frame_skip_update(&fskip);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
|
||||
struct vfe_cmds_camif_frame fup;
|
||||
if (copy_from_user(&fup,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_camif_frame_update(&fup);
|
||||
}
|
||||
break;
|
||||
|
||||
/* stats update commands */
|
||||
case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
|
||||
struct vfe_cmd_stats_af_update afup;
|
||||
if (copy_from_user(&afup,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_update_af(&afup);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
|
||||
struct vfe_cmd_stats_wb_exp_update wbexp;
|
||||
if (copy_from_user(&wbexp,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_update_wb_exp(&wbexp);
|
||||
}
|
||||
break;
|
||||
|
||||
/* control of start, stop, update, etc... */
|
||||
case VFE_CMD_ID_STOP:
|
||||
vfe_stop();
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_GET_HW_VERSION:
|
||||
break;
|
||||
|
||||
/* stats */
|
||||
case VFE_CMD_ID_STATS_SETTING: {
|
||||
struct vfe_cmd_stats_setting stats;
|
||||
if (copy_from_user(&stats,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_setting(&stats);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
|
||||
struct vfe_cmd_stats_af_start af;
|
||||
if (copy_from_user(&af,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_start_af(&af);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
|
||||
vfe_stats_af_stop();
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_WB_EXP_START: {
|
||||
struct vfe_cmd_stats_wb_exp_start awexp;
|
||||
if (copy_from_user(&awexp,
|
||||
(void __user *) cmd->value, cmd->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfe_stats_start_wb_exp(&awexp);
|
||||
}
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_STATS_WB_EXP_STOP:
|
||||
vfe_stats_wb_exp_stop();
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_ASYNC_TIMER_SETTING:
|
||||
break;
|
||||
|
||||
case VFE_CMD_ID_UPDATE:
|
||||
vfe_update();
|
||||
break;
|
||||
|
||||
/* test gen */
|
||||
case VFE_CMD_ID_TEST_GEN_START:
|
||||
break;
|
||||
|
||||
/*
|
||||
acknowledge from upper layer
|
||||
these are not in general command.
|
||||
|
||||
case VFE_CMD_ID_OUTPUT1_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_OUTPUT2_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_EPOCH1_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_EPOCH2_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
|
||||
break;
|
||||
case VFE_CMD_ID_STATS_WB_EXP_ACK:
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
|
||||
{
|
||||
struct msm_pmem_region *regptr;
|
||||
struct msm_vfe_command_8k vfecmd;
|
||||
|
||||
uint32_t i;
|
||||
|
||||
void *cmd_data = NULL;
|
||||
long rc = 0;
|
||||
|
||||
struct vfe_cmd_axi_output_config *axio = NULL;
|
||||
struct vfe_cmd_stats_setting *scfg = NULL;
|
||||
|
||||
if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
|
||||
cmd->cmd_type != CMD_STATS_BUF_RELEASE) {
|
||||
|
||||
if (copy_from_user(&vfecmd,
|
||||
(void __user *)(cmd->value),
|
||||
sizeof(struct msm_vfe_command_8k)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);
|
||||
|
||||
switch (cmd->cmd_type) {
|
||||
case CMD_GENERAL:
|
||||
rc = vfe_proc_general(&vfecmd);
|
||||
break;
|
||||
|
||||
case CMD_STATS_ENABLE:
|
||||
case CMD_STATS_AXI_CFG: {
|
||||
struct axidata *axid;
|
||||
|
||||
axid = data;
|
||||
if (!axid)
|
||||
return -EFAULT;
|
||||
|
||||
scfg =
|
||||
kmalloc(sizeof(struct vfe_cmd_stats_setting),
|
||||
GFP_ATOMIC);
|
||||
if (!scfg)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(scfg,
|
||||
(void __user *)(vfecmd.value),
|
||||
vfecmd.length)) {
|
||||
|
||||
kfree(scfg);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
regptr = axid->region;
|
||||
if (axid->bufnum1 > 0) {
|
||||
for (i = 0; i < axid->bufnum1; i++) {
|
||||
scfg->awbBuffer[i] =
|
||||
(uint32_t)(regptr->paddr);
|
||||
regptr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (axid->bufnum2 > 0) {
|
||||
for (i = 0; i < axid->bufnum2; i++) {
|
||||
scfg->afBuffer[i] =
|
||||
(uint32_t)(regptr->paddr);
|
||||
regptr++;
|
||||
}
|
||||
}
|
||||
|
||||
vfe_stats_config(scfg);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STATS_AF_AXI_CFG: {
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_FRAME_BUF_RELEASE: {
|
||||
/* preview buffer release */
|
||||
struct msm_frame *b;
|
||||
unsigned long p;
|
||||
struct vfe_cmd_output_ack fack;
|
||||
|
||||
if (!data)
|
||||
return -EFAULT;
|
||||
|
||||
b = (struct msm_frame *)(cmd->value);
|
||||
p = *(unsigned long *)data;
|
||||
|
||||
b->path = MSM_FRAME_ENC;
|
||||
|
||||
fack.ybufaddr[0] =
|
||||
(uint32_t)(p + b->y_off);
|
||||
|
||||
fack.chromabufaddr[0] =
|
||||
(uint32_t)(p + b->cbcr_off);
|
||||
|
||||
if (b->path == MSM_FRAME_PREV_1)
|
||||
vfe_output1_ack(&fack);
|
||||
|
||||
if (b->path == MSM_FRAME_ENC ||
|
||||
b->path == MSM_FRAME_PREV_2)
|
||||
vfe_output2_ack(&fack);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SNAP_BUF_RELEASE: {
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_STATS_BUF_RELEASE: {
|
||||
struct vfe_cmd_stats_wb_exp_ack sack;
|
||||
|
||||
if (!data)
|
||||
return -EFAULT;
|
||||
|
||||
sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
|
||||
vfe_stats_wb_exp_ack(&sack);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_OUT1: {
|
||||
struct axidata *axid;
|
||||
|
||||
axid = data;
|
||||
if (!axid)
|
||||
return -EFAULT;
|
||||
|
||||
axio =
|
||||
kmalloc(sizeof(struct vfe_cmd_axi_output_config),
|
||||
GFP_ATOMIC);
|
||||
if (!axio)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(axio, (void __user *)(vfecmd.value),
|
||||
sizeof(struct vfe_cmd_axi_output_config))) {
|
||||
kfree(axio);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
vfe_config_axi(OUTPUT_1, axid, axio);
|
||||
vfe_axi_output_config(axio);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_OUT2:
|
||||
case CMD_RAW_PICT_AXI_CFG: {
|
||||
struct axidata *axid;
|
||||
|
||||
axid = data;
|
||||
if (!axid)
|
||||
return -EFAULT;
|
||||
|
||||
axio =
|
||||
kmalloc(sizeof(struct vfe_cmd_axi_output_config),
|
||||
GFP_ATOMIC);
|
||||
if (!axio)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(axio, (void __user *)(vfecmd.value),
|
||||
sizeof(struct vfe_cmd_axi_output_config))) {
|
||||
kfree(axio);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
vfe_config_axi(OUTPUT_2, axid, axio);
|
||||
|
||||
axio->outputDataSize = 0;
|
||||
vfe_axi_output_config(axio);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_AXI_CFG_SNAP_O1_AND_O2: {
|
||||
struct axidata *axid;
|
||||
axid = data;
|
||||
if (!axid)
|
||||
return -EFAULT;
|
||||
|
||||
axio =
|
||||
kmalloc(sizeof(struct vfe_cmd_axi_output_config),
|
||||
GFP_ATOMIC);
|
||||
if (!axio)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_from_user(axio, (void __user *)(vfecmd.value),
|
||||
sizeof(struct vfe_cmd_axi_output_config))) {
|
||||
kfree(axio);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
vfe_config_axi(OUTPUT_1_AND_2,
|
||||
axid, axio);
|
||||
vfe_axi_output_config(axio);
|
||||
cmd_data = axio;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
kfree(scfg);
|
||||
|
||||
kfree(axio);
|
||||
|
||||
/*
|
||||
if (cmd->length > 256 &&
|
||||
cmd_data &&
|
||||
(cmd->cmd_type == CMD_GENERAL ||
|
||||
cmd->cmd_type == CMD_STATS_DISABLE)) {
|
||||
kfree(cmd_data);
|
||||
}
|
||||
*/
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vfe_init(struct msm_vfe_callback *presp,
|
||||
struct platform_device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = vfe_cmd_init(presp, dev, vfe_syncdata);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Bring up all the required GPIOs and Clocks */
|
||||
return msm_camio_enable(dev);
|
||||
}
|
||||
|
||||
void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
|
||||
{
|
||||
mutex_init(&vfe_lock);
|
||||
fptr->vfe_init = vfe_init;
|
||||
fptr->vfe_enable = vfe_enable;
|
||||
fptr->vfe_config = vfe_config;
|
||||
fptr->vfe_disable = vfe_disable;
|
||||
fptr->vfe_release = vfe_release;
|
||||
vfe_syncdata = data;
|
||||
}
|
|
@ -0,0 +1,895 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
#ifndef __MSM_VFE8X_H__
|
||||
#define __MSM_VFE8X_H__
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define boolean uint8_t
|
||||
|
||||
enum VFE_STATE {
|
||||
VFE_STATE_IDLE,
|
||||
VFE_STATE_ACTIVE
|
||||
};
|
||||
|
||||
enum vfe_cmd_id {
|
||||
/*
|
||||
*Important! Command_ID are arranged in order.
|
||||
*Don't change!*/
|
||||
VFE_CMD_ID_START,
|
||||
VFE_CMD_ID_RESET,
|
||||
|
||||
/* bus and camif config */
|
||||
VFE_CMD_ID_AXI_INPUT_CONFIG,
|
||||
VFE_CMD_ID_CAMIF_CONFIG,
|
||||
VFE_CMD_ID_AXI_OUTPUT_CONFIG,
|
||||
|
||||
/* module config */
|
||||
VFE_CMD_ID_BLACK_LEVEL_CONFIG,
|
||||
VFE_CMD_ID_ROLL_OFF_CONFIG,
|
||||
VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG,
|
||||
VFE_CMD_ID_DEMOSAIC_CONFIG,
|
||||
VFE_CMD_ID_FOV_CROP_CONFIG,
|
||||
VFE_CMD_ID_MAIN_SCALER_CONFIG,
|
||||
VFE_CMD_ID_WHITE_BALANCE_CONFIG,
|
||||
VFE_CMD_ID_COLOR_CORRECTION_CONFIG,
|
||||
VFE_CMD_ID_LA_CONFIG,
|
||||
VFE_CMD_ID_RGB_GAMMA_CONFIG,
|
||||
VFE_CMD_ID_CHROMA_ENHAN_CONFIG,
|
||||
VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG,
|
||||
VFE_CMD_ID_ASF_CONFIG,
|
||||
VFE_CMD_ID_SCALER2Y_CONFIG,
|
||||
VFE_CMD_ID_SCALER2CbCr_CONFIG,
|
||||
VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG,
|
||||
VFE_CMD_ID_FRAME_SKIP_CONFIG,
|
||||
VFE_CMD_ID_OUTPUT_CLAMP_CONFIG,
|
||||
|
||||
/* test gen */
|
||||
VFE_CMD_ID_TEST_GEN_START,
|
||||
|
||||
VFE_CMD_ID_UPDATE,
|
||||
|
||||
/* ackownledge from upper layer */
|
||||
VFE_CMD_ID_OUTPUT1_ACK,
|
||||
VFE_CMD_ID_OUTPUT2_ACK,
|
||||
VFE_CMD_ID_EPOCH1_ACK,
|
||||
VFE_CMD_ID_EPOCH2_ACK,
|
||||
VFE_CMD_ID_STATS_AUTOFOCUS_ACK,
|
||||
VFE_CMD_ID_STATS_WB_EXP_ACK,
|
||||
|
||||
/* module update commands */
|
||||
VFE_CMD_ID_BLACK_LEVEL_UPDATE,
|
||||
VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE,
|
||||
VFE_CMD_ID_DEMOSAIC_BPC_UPDATE,
|
||||
VFE_CMD_ID_DEMOSAIC_ABF_UPDATE,
|
||||
VFE_CMD_ID_FOV_CROP_UPDATE,
|
||||
VFE_CMD_ID_WHITE_BALANCE_UPDATE,
|
||||
VFE_CMD_ID_COLOR_CORRECTION_UPDATE,
|
||||
VFE_CMD_ID_LA_UPDATE,
|
||||
VFE_CMD_ID_RGB_GAMMA_UPDATE,
|
||||
VFE_CMD_ID_CHROMA_ENHAN_UPDATE,
|
||||
VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE,
|
||||
VFE_CMD_ID_MAIN_SCALER_UPDATE,
|
||||
VFE_CMD_ID_SCALER2CbCr_UPDATE,
|
||||
VFE_CMD_ID_SCALER2Y_UPDATE,
|
||||
VFE_CMD_ID_ASF_UPDATE,
|
||||
VFE_CMD_ID_FRAME_SKIP_UPDATE,
|
||||
VFE_CMD_ID_CAMIF_FRAME_UPDATE,
|
||||
|
||||
/* stats update commands */
|
||||
VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE,
|
||||
VFE_CMD_ID_STATS_WB_EXP_UPDATE,
|
||||
|
||||
/* control of start, stop, update, etc... */
|
||||
VFE_CMD_ID_STOP,
|
||||
VFE_CMD_ID_GET_HW_VERSION,
|
||||
|
||||
/* stats */
|
||||
VFE_CMD_ID_STATS_SETTING,
|
||||
VFE_CMD_ID_STATS_AUTOFOCUS_START,
|
||||
VFE_CMD_ID_STATS_AUTOFOCUS_STOP,
|
||||
VFE_CMD_ID_STATS_WB_EXP_START,
|
||||
VFE_CMD_ID_STATS_WB_EXP_STOP,
|
||||
|
||||
VFE_CMD_ID_ASYNC_TIMER_SETTING,
|
||||
|
||||
/* max id */
|
||||
VFE_CMD_ID_MAX
|
||||
};
|
||||
|
||||
struct vfe_cmd_hw_version {
|
||||
uint32_t minorVersion;
|
||||
uint32_t majorVersion;
|
||||
uint32_t coreVersion;
|
||||
};
|
||||
|
||||
enum VFE_CAMIF_SYNC_EDGE {
|
||||
VFE_CAMIF_SYNC_EDGE_ActiveHigh,
|
||||
VFE_CAMIF_SYNC_EDGE_ActiveLow
|
||||
};
|
||||
|
||||
enum VFE_CAMIF_SYNC_MODE {
|
||||
VFE_CAMIF_SYNC_MODE_APS,
|
||||
VFE_CAMIF_SYNC_MODE_EFS,
|
||||
VFE_CAMIF_SYNC_MODE_ELS,
|
||||
VFE_CAMIF_SYNC_MODE_ILLEGAL
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_efs {
|
||||
uint8_t efsendofline;
|
||||
uint8_t efsstartofline;
|
||||
uint8_t efsendofframe;
|
||||
uint8_t efsstartofframe;
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_frame {
|
||||
uint16_t pixelsPerLine;
|
||||
uint16_t linesPerFrame;
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_window {
|
||||
uint16_t firstpixel;
|
||||
uint16_t lastpixel;
|
||||
uint16_t firstline;
|
||||
uint16_t lastline;
|
||||
};
|
||||
|
||||
enum CAMIF_SUBSAMPLE_FRAME_SKIP {
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_0,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_AllFrames,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_2Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_3Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_4Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_5Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_6Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_7Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_8Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_9Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_10Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_11Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_12Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_13Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_14Frame,
|
||||
CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_15Frame
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_subsample {
|
||||
uint16_t pixelskipmask;
|
||||
uint16_t lineskipmask;
|
||||
enum CAMIF_SUBSAMPLE_FRAME_SKIP frameskip;
|
||||
uint8_t frameskipmode;
|
||||
uint8_t pixelskipwrap;
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_epoch {
|
||||
uint8_t enable;
|
||||
uint16_t lineindex;
|
||||
};
|
||||
|
||||
struct vfe_cmds_camif_cfg {
|
||||
enum VFE_CAMIF_SYNC_EDGE vSyncEdge;
|
||||
enum VFE_CAMIF_SYNC_EDGE hSyncEdge;
|
||||
enum VFE_CAMIF_SYNC_MODE syncMode;
|
||||
uint8_t vfeSubSampleEnable;
|
||||
uint8_t busSubSampleEnable;
|
||||
uint8_t irqSubSampleEnable;
|
||||
uint8_t binningEnable;
|
||||
uint8_t misrEnable;
|
||||
};
|
||||
|
||||
struct vfe_cmd_camif_config {
|
||||
struct vfe_cmds_camif_cfg camifConfig;
|
||||
struct vfe_cmds_camif_efs EFS;
|
||||
struct vfe_cmds_camif_frame frame;
|
||||
struct vfe_cmds_camif_window window;
|
||||
struct vfe_cmds_camif_subsample subsample;
|
||||
struct vfe_cmds_camif_epoch epoch1;
|
||||
struct vfe_cmds_camif_epoch epoch2;
|
||||
};
|
||||
|
||||
enum VFE_AXI_OUTPUT_MODE {
|
||||
VFE_AXI_OUTPUT_MODE_Output1,
|
||||
VFE_AXI_OUTPUT_MODE_Output2,
|
||||
VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
|
||||
VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
|
||||
VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
|
||||
VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
|
||||
VFE_AXI_LAST_OUTPUT_MODE_ENUM
|
||||
};
|
||||
|
||||
enum VFE_RAW_WR_PATH_SEL {
|
||||
VFE_RAW_OUTPUT_DISABLED,
|
||||
VFE_RAW_OUTPUT_ENC_CBCR_PATH,
|
||||
VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
|
||||
VFE_RAW_OUTPUT_PATH_INVALID
|
||||
};
|
||||
|
||||
enum VFE_RAW_PIXEL_DATA_SIZE {
|
||||
VFE_RAW_PIXEL_DATA_SIZE_8BIT,
|
||||
VFE_RAW_PIXEL_DATA_SIZE_10BIT,
|
||||
VFE_RAW_PIXEL_DATA_SIZE_12BIT,
|
||||
};
|
||||
|
||||
#define VFE_AXI_OUTPUT_BURST_LENGTH 4
|
||||
#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
|
||||
#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT 3
|
||||
|
||||
struct vfe_cmds_axi_out_per_component {
|
||||
uint16_t imageWidth;
|
||||
uint16_t imageHeight;
|
||||
uint16_t outRowCount;
|
||||
uint16_t outRowIncrement;
|
||||
uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
|
||||
[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
|
||||
};
|
||||
|
||||
struct vfe_cmds_axi_per_output_path {
|
||||
uint8_t fragmentCount;
|
||||
struct vfe_cmds_axi_out_per_component outputY;
|
||||
struct vfe_cmds_axi_out_per_component outputCbcr;
|
||||
};
|
||||
|
||||
enum VFE_AXI_BURST_LENGTH {
|
||||
VFE_AXI_BURST_LENGTH_IS_2 = 2,
|
||||
VFE_AXI_BURST_LENGTH_IS_4 = 4,
|
||||
VFE_AXI_BURST_LENGTH_IS_8 = 8,
|
||||
VFE_AXI_BURST_LENGTH_IS_16 = 16
|
||||
};
|
||||
|
||||
struct vfe_cmd_axi_output_config {
|
||||
enum VFE_AXI_BURST_LENGTH burstLength;
|
||||
enum VFE_AXI_OUTPUT_MODE outputMode;
|
||||
enum VFE_RAW_PIXEL_DATA_SIZE outputDataSize;
|
||||
struct vfe_cmds_axi_per_output_path output1;
|
||||
struct vfe_cmds_axi_per_output_path output2;
|
||||
};
|
||||
|
||||
struct vfe_cmd_fov_crop_config {
|
||||
uint8_t enable;
|
||||
uint16_t firstPixel;
|
||||
uint16_t lastPixel;
|
||||
uint16_t firstLine;
|
||||
uint16_t lastLine;
|
||||
};
|
||||
|
||||
struct vfe_cmds_main_scaler_stripe_init {
|
||||
uint16_t MNCounterInit;
|
||||
uint16_t phaseInit;
|
||||
};
|
||||
|
||||
struct vfe_cmds_scaler_one_dimension {
|
||||
uint8_t enable;
|
||||
uint16_t inputSize;
|
||||
uint16_t outputSize;
|
||||
uint32_t phaseMultiplicationFactor;
|
||||
uint8_t interpolationResolution;
|
||||
};
|
||||
|
||||
struct vfe_cmd_main_scaler_config {
|
||||
uint8_t enable;
|
||||
struct vfe_cmds_scaler_one_dimension hconfig;
|
||||
struct vfe_cmds_scaler_one_dimension vconfig;
|
||||
struct vfe_cmds_main_scaler_stripe_init MNInitH;
|
||||
struct vfe_cmds_main_scaler_stripe_init MNInitV;
|
||||
};
|
||||
|
||||
struct vfe_cmd_scaler2_config {
|
||||
uint8_t enable;
|
||||
struct vfe_cmds_scaler_one_dimension hconfig;
|
||||
struct vfe_cmds_scaler_one_dimension vconfig;
|
||||
};
|
||||
|
||||
struct vfe_cmd_frame_skip_config {
|
||||
uint8_t output1Period;
|
||||
uint32_t output1Pattern;
|
||||
uint8_t output2Period;
|
||||
uint32_t output2Pattern;
|
||||
};
|
||||
|
||||
struct vfe_cmd_frame_skip_update {
|
||||
uint32_t output1Pattern;
|
||||
uint32_t output2Pattern;
|
||||
};
|
||||
|
||||
struct vfe_cmd_output_clamp_config {
|
||||
uint8_t minCh0;
|
||||
uint8_t minCh1;
|
||||
uint8_t minCh2;
|
||||
uint8_t maxCh0;
|
||||
uint8_t maxCh1;
|
||||
uint8_t maxCh2;
|
||||
};
|
||||
|
||||
struct vfe_cmd_chroma_subsample_config {
|
||||
uint8_t enable;
|
||||
uint8_t cropEnable;
|
||||
uint8_t vsubSampleEnable;
|
||||
uint8_t hsubSampleEnable;
|
||||
uint8_t vCosited;
|
||||
uint8_t hCosited;
|
||||
uint8_t vCositedPhase;
|
||||
uint8_t hCositedPhase;
|
||||
uint16_t cropWidthFirstPixel;
|
||||
uint16_t cropWidthLastPixel;
|
||||
uint16_t cropHeightFirstLine;
|
||||
uint16_t cropHeightLastLine;
|
||||
};
|
||||
|
||||
enum VFE_START_INPUT_SOURCE {
|
||||
VFE_START_INPUT_SOURCE_CAMIF,
|
||||
VFE_START_INPUT_SOURCE_TESTGEN,
|
||||
VFE_START_INPUT_SOURCE_AXI,
|
||||
VFE_START_INPUT_SOURCE_INVALID
|
||||
};
|
||||
|
||||
enum VFE_START_OPERATION_MODE {
|
||||
VFE_START_OPERATION_MODE_CONTINUOUS,
|
||||
VFE_START_OPERATION_MODE_SNAPSHOT
|
||||
};
|
||||
|
||||
enum VFE_START_PIXEL_PATTERN {
|
||||
VFE_BAYER_RGRGRG,
|
||||
VFE_BAYER_GRGRGR,
|
||||
VFE_BAYER_BGBGBG,
|
||||
VFE_BAYER_GBGBGB,
|
||||
VFE_YUV_YCbYCr,
|
||||
VFE_YUV_YCrYCb,
|
||||
VFE_YUV_CbYCrY,
|
||||
VFE_YUV_CrYCbY
|
||||
};
|
||||
|
||||
enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
|
||||
VFE_BAYER_RAW,
|
||||
VFE_YUV_INTERLEAVED,
|
||||
VFE_YUV_PSEUDO_PLANAR_Y,
|
||||
VFE_YUV_PSEUDO_PLANAR_CBCR
|
||||
};
|
||||
|
||||
enum VFE_YUV_INPUT_COSITING_MODE {
|
||||
VFE_YUV_COSITED,
|
||||
VFE_YUV_INTERPOLATED
|
||||
};
|
||||
|
||||
struct vfe_cmd_start {
|
||||
enum VFE_START_INPUT_SOURCE inputSource;
|
||||
enum VFE_START_OPERATION_MODE operationMode;
|
||||
uint8_t snapshotCount;
|
||||
enum VFE_START_PIXEL_PATTERN pixel;
|
||||
enum VFE_YUV_INPUT_COSITING_MODE yuvInputCositingMode;
|
||||
};
|
||||
|
||||
struct vfe_cmd_output_ack {
|
||||
uint32_t ybufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
|
||||
uint32_t chromabufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
|
||||
};
|
||||
|
||||
#define VFE_STATS_BUFFER_COUNT 3
|
||||
|
||||
struct vfe_cmd_stats_setting {
|
||||
uint16_t frameHDimension;
|
||||
uint16_t frameVDimension;
|
||||
uint8_t afBusPrioritySelection;
|
||||
uint8_t afBusPriority;
|
||||
uint8_t awbBusPrioritySelection;
|
||||
uint8_t awbBusPriority;
|
||||
uint8_t histBusPrioritySelection;
|
||||
uint8_t histBusPriority;
|
||||
uint32_t afBuffer[VFE_STATS_BUFFER_COUNT];
|
||||
uint32_t awbBuffer[VFE_STATS_BUFFER_COUNT];
|
||||
uint32_t histBuffer[VFE_STATS_BUFFER_COUNT];
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_af_start {
|
||||
uint8_t enable;
|
||||
uint8_t windowMode;
|
||||
uint16_t windowHOffset;
|
||||
uint16_t windowVOffset;
|
||||
uint16_t windowWidth;
|
||||
uint16_t windowHeight;
|
||||
uint8_t gridForMultiWindows[16];
|
||||
uint8_t metricSelection;
|
||||
int16_t metricMax;
|
||||
int8_t highPassCoef[7];
|
||||
int8_t bufferHeader;
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_af_update {
|
||||
uint8_t windowMode;
|
||||
uint16_t windowHOffset;
|
||||
uint16_t windowVOffset;
|
||||
uint16_t windowWidth;
|
||||
uint16_t windowHeight;
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_wb_exp_start {
|
||||
uint8_t enable;
|
||||
uint8_t wbExpRegions;
|
||||
uint8_t wbExpSubRegion;
|
||||
uint8_t awbYMin;
|
||||
uint8_t awbYMax;
|
||||
int8_t awbMCFG[4];
|
||||
int16_t awbCCFG[4];
|
||||
int8_t axwHeader;
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_wb_exp_update {
|
||||
uint8_t wbExpRegions;
|
||||
uint8_t wbExpSubRegion;
|
||||
int8_t awbYMin;
|
||||
int8_t awbYMax;
|
||||
int8_t awbMCFG[4];
|
||||
int16_t awbCCFG[4];
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_af_ack {
|
||||
uint32_t nextAFOutputBufferAddr;
|
||||
};
|
||||
|
||||
struct vfe_cmd_stats_wb_exp_ack {
|
||||
uint32_t nextWbExpOutputBufferAddr;
|
||||
};
|
||||
|
||||
struct vfe_cmd_black_level_config {
|
||||
uint8_t enable;
|
||||
uint16_t evenEvenAdjustment;
|
||||
uint16_t evenOddAdjustment;
|
||||
uint16_t oddEvenAdjustment;
|
||||
uint16_t oddOddAdjustment;
|
||||
};
|
||||
|
||||
/* 13*1 */
|
||||
#define VFE_ROLL_OFF_INIT_TABLE_SIZE 13
|
||||
/* 13*16 */
|
||||
#define VFE_ROLL_OFF_DELTA_TABLE_SIZE 208
|
||||
|
||||
struct vfe_cmd_roll_off_config {
|
||||
uint8_t enable;
|
||||
uint16_t gridWidth;
|
||||
uint16_t gridHeight;
|
||||
uint16_t yDelta;
|
||||
uint8_t gridXIndex;
|
||||
uint8_t gridYIndex;
|
||||
uint16_t gridPixelXIndex;
|
||||
uint16_t gridPixelYIndex;
|
||||
uint16_t yDeltaAccum;
|
||||
uint16_t initTableR[VFE_ROLL_OFF_INIT_TABLE_SIZE];
|
||||
uint16_t initTableGr[VFE_ROLL_OFF_INIT_TABLE_SIZE];
|
||||
uint16_t initTableB[VFE_ROLL_OFF_INIT_TABLE_SIZE];
|
||||
uint16_t initTableGb[VFE_ROLL_OFF_INIT_TABLE_SIZE];
|
||||
int16_t deltaTableR[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
|
||||
int16_t deltaTableGr[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
|
||||
int16_t deltaTableB[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
|
||||
int16_t deltaTableGb[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
|
||||
};
|
||||
|
||||
struct vfe_cmd_demux_channel_gain_config {
|
||||
uint16_t ch0EvenGain;
|
||||
uint16_t ch0OddGain;
|
||||
uint16_t ch1Gain;
|
||||
uint16_t ch2Gain;
|
||||
};
|
||||
|
||||
struct vfe_cmds_demosaic_abf {
|
||||
uint8_t enable;
|
||||
uint8_t forceOn;
|
||||
uint8_t shift;
|
||||
uint16_t lpThreshold;
|
||||
uint16_t max;
|
||||
uint16_t min;
|
||||
uint8_t ratio;
|
||||
};
|
||||
|
||||
struct vfe_cmds_demosaic_bpc {
|
||||
uint8_t enable;
|
||||
uint16_t fmaxThreshold;
|
||||
uint16_t fminThreshold;
|
||||
uint16_t redDiffThreshold;
|
||||
uint16_t blueDiffThreshold;
|
||||
uint16_t greenDiffThreshold;
|
||||
};
|
||||
|
||||
struct vfe_cmd_demosaic_config {
|
||||
uint8_t enable;
|
||||
uint8_t slopeShift;
|
||||
struct vfe_cmds_demosaic_abf abfConfig;
|
||||
struct vfe_cmds_demosaic_bpc bpcConfig;
|
||||
};
|
||||
|
||||
struct vfe_cmd_demosaic_bpc_update {
|
||||
struct vfe_cmds_demosaic_bpc bpcUpdate;
|
||||
};
|
||||
|
||||
struct vfe_cmd_demosaic_abf_update {
|
||||
struct vfe_cmds_demosaic_abf abfUpdate;
|
||||
};
|
||||
|
||||
struct vfe_cmd_white_balance_config {
|
||||
uint8_t enable;
|
||||
uint16_t ch2Gain;
|
||||
uint16_t ch1Gain;
|
||||
uint16_t ch0Gain;
|
||||
};
|
||||
|
||||
enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
|
||||
COEF_IS_Q7_SIGNED,
|
||||
COEF_IS_Q8_SIGNED,
|
||||
COEF_IS_Q9_SIGNED,
|
||||
COEF_IS_Q10_SIGNED
|
||||
};
|
||||
|
||||
struct vfe_cmd_color_correction_config {
|
||||
uint8_t enable;
|
||||
enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
|
||||
int16_t C0;
|
||||
int16_t C1;
|
||||
int16_t C2;
|
||||
int16_t C3;
|
||||
int16_t C4;
|
||||
int16_t C5;
|
||||
int16_t C6;
|
||||
int16_t C7;
|
||||
int16_t C8;
|
||||
int16_t K0;
|
||||
int16_t K1;
|
||||
int16_t K2;
|
||||
};
|
||||
|
||||
#define VFE_LA_TABLE_LENGTH 256
|
||||
struct vfe_cmd_la_config {
|
||||
uint8_t enable;
|
||||
int16_t table[VFE_LA_TABLE_LENGTH];
|
||||
};
|
||||
|
||||
#define VFE_GAMMA_TABLE_LENGTH 256
|
||||
enum VFE_RGB_GAMMA_TABLE_SELECT {
|
||||
RGB_GAMMA_CH0_SELECTED,
|
||||
RGB_GAMMA_CH1_SELECTED,
|
||||
RGB_GAMMA_CH2_SELECTED,
|
||||
RGB_GAMMA_CH0_CH1_SELECTED,
|
||||
RGB_GAMMA_CH0_CH2_SELECTED,
|
||||
RGB_GAMMA_CH1_CH2_SELECTED,
|
||||
RGB_GAMMA_CH0_CH1_CH2_SELECTED
|
||||
};
|
||||
|
||||
struct vfe_cmd_rgb_gamma_config {
|
||||
uint8_t enable;
|
||||
enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
|
||||
int16_t table[VFE_GAMMA_TABLE_LENGTH];
|
||||
};
|
||||
|
||||
struct vfe_cmd_chroma_enhan_config {
|
||||
uint8_t enable;
|
||||
int16_t am;
|
||||
int16_t ap;
|
||||
int16_t bm;
|
||||
int16_t bp;
|
||||
int16_t cm;
|
||||
int16_t cp;
|
||||
int16_t dm;
|
||||
int16_t dp;
|
||||
int16_t kcr;
|
||||
int16_t kcb;
|
||||
int16_t RGBtoYConversionV0;
|
||||
int16_t RGBtoYConversionV1;
|
||||
int16_t RGBtoYConversionV2;
|
||||
uint8_t RGBtoYConversionOffset;
|
||||
};
|
||||
|
||||
struct vfe_cmd_chroma_suppression_config {
|
||||
uint8_t enable;
|
||||
uint8_t m1;
|
||||
uint8_t m3;
|
||||
uint8_t n1;
|
||||
uint8_t n3;
|
||||
uint8_t nn1;
|
||||
uint8_t mm1;
|
||||
};
|
||||
|
||||
struct vfe_cmd_asf_config {
|
||||
uint8_t enable;
|
||||
uint8_t smoothFilterEnabled;
|
||||
uint8_t sharpMode;
|
||||
uint8_t smoothCoefCenter;
|
||||
uint8_t smoothCoefSurr;
|
||||
uint8_t normalizeFactor;
|
||||
uint8_t sharpK1;
|
||||
uint8_t sharpK2;
|
||||
uint8_t sharpThreshE1;
|
||||
int8_t sharpThreshE2;
|
||||
int8_t sharpThreshE3;
|
||||
int8_t sharpThreshE4;
|
||||
int8_t sharpThreshE5;
|
||||
int8_t filter1Coefficients[9];
|
||||
int8_t filter2Coefficients[9];
|
||||
uint8_t cropEnable;
|
||||
uint16_t cropFirstPixel;
|
||||
uint16_t cropLastPixel;
|
||||
uint16_t cropFirstLine;
|
||||
uint16_t cropLastLine;
|
||||
};
|
||||
|
||||
struct vfe_cmd_asf_update {
|
||||
uint8_t enable;
|
||||
uint8_t smoothFilterEnabled;
|
||||
uint8_t sharpMode;
|
||||
uint8_t smoothCoefCenter;
|
||||
uint8_t smoothCoefSurr;
|
||||
uint8_t normalizeFactor;
|
||||
uint8_t sharpK1;
|
||||
uint8_t sharpK2;
|
||||
uint8_t sharpThreshE1;
|
||||
int8_t sharpThreshE2;
|
||||
int8_t sharpThreshE3;
|
||||
int8_t sharpThreshE4;
|
||||
int8_t sharpThreshE5;
|
||||
int8_t filter1Coefficients[9];
|
||||
int8_t filter2Coefficients[9];
|
||||
uint8_t cropEnable;
|
||||
};
|
||||
|
||||
enum VFE_TEST_GEN_SYNC_EDGE {
|
||||
VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
|
||||
VFE_TEST_GEN_SYNC_EDGE_ActiveLow
|
||||
};
|
||||
|
||||
struct vfe_cmd_test_gen_start {
|
||||
uint8_t pixelDataSelect;
|
||||
uint8_t systematicDataSelect;
|
||||
enum VFE_TEST_GEN_SYNC_EDGE hsyncEdge;
|
||||
enum VFE_TEST_GEN_SYNC_EDGE vsyncEdge;
|
||||
uint16_t numFrame;
|
||||
enum VFE_RAW_PIXEL_DATA_SIZE pixelDataSize;
|
||||
uint16_t imageWidth;
|
||||
uint16_t imageHeight;
|
||||
uint32_t startOfFrameOffset;
|
||||
uint32_t endOfFrameNOffset;
|
||||
uint16_t startOfLineOffset;
|
||||
uint16_t endOfLineNOffset;
|
||||
uint16_t hbi;
|
||||
uint8_t vblEnable;
|
||||
uint16_t vbl;
|
||||
uint8_t startOfFrameDummyLine;
|
||||
uint8_t endOfFrameDummyLine;
|
||||
uint8_t unicolorBarEnable;
|
||||
uint8_t colorBarsSplitEnable;
|
||||
uint8_t unicolorBarSelect;
|
||||
enum VFE_START_PIXEL_PATTERN colorBarsPixelPattern;
|
||||
uint8_t colorBarsRotatePeriod;
|
||||
uint16_t testGenRandomSeed;
|
||||
};
|
||||
|
||||
struct vfe_cmd_bus_pm_start {
|
||||
uint8_t output2YWrPmEnable;
|
||||
uint8_t output2CbcrWrPmEnable;
|
||||
uint8_t output1YWrPmEnable;
|
||||
uint8_t output1CbcrWrPmEnable;
|
||||
};
|
||||
|
||||
struct vfe_cmd_camif_frame_update {
|
||||
struct vfe_cmds_camif_frame camifFrame;
|
||||
};
|
||||
|
||||
struct vfe_cmd_sync_timer_setting {
|
||||
uint8_t whichSyncTimer;
|
||||
uint8_t operation;
|
||||
uint8_t polarity;
|
||||
uint16_t repeatCount;
|
||||
uint16_t hsyncCount;
|
||||
uint32_t pclkCount;
|
||||
uint32_t outputDuration;
|
||||
};
|
||||
|
||||
struct vfe_cmd_async_timer_setting {
|
||||
uint8_t whichAsyncTimer;
|
||||
uint8_t operation;
|
||||
uint8_t polarity;
|
||||
uint16_t repeatCount;
|
||||
uint16_t inactiveCount;
|
||||
uint32_t activeCount;
|
||||
};
|
||||
|
||||
struct vfe_frame_skip_counts {
|
||||
uint32_t totalFrameCount;
|
||||
uint32_t output1Count;
|
||||
uint32_t output2Count;
|
||||
};
|
||||
|
||||
enum VFE_AXI_RD_UNPACK_HBI_SEL {
|
||||
VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
|
||||
VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
|
||||
};
|
||||
|
||||
struct vfe_cmd_axi_input_config {
|
||||
uint32_t fragAddr[4];
|
||||
uint8_t totalFragmentCount;
|
||||
uint16_t ySize;
|
||||
uint16_t xOffset;
|
||||
uint16_t xSize;
|
||||
uint16_t rowIncrement;
|
||||
uint16_t numOfRows;
|
||||
enum VFE_AXI_BURST_LENGTH burstLength;
|
||||
uint8_t unpackPhase;
|
||||
enum VFE_AXI_RD_UNPACK_HBI_SEL unpackHbi;
|
||||
enum VFE_RAW_PIXEL_DATA_SIZE pixelSize;
|
||||
uint8_t padRepeatCountLeft;
|
||||
uint8_t padRepeatCountRight;
|
||||
uint8_t padRepeatCountTop;
|
||||
uint8_t padRepeatCountBottom;
|
||||
uint8_t padLeftComponentSelectCycle0;
|
||||
uint8_t padLeftComponentSelectCycle1;
|
||||
uint8_t padLeftComponentSelectCycle2;
|
||||
uint8_t padLeftComponentSelectCycle3;
|
||||
uint8_t padLeftStopCycle0;
|
||||
uint8_t padLeftStopCycle1;
|
||||
uint8_t padLeftStopCycle2;
|
||||
uint8_t padLeftStopCycle3;
|
||||
uint8_t padRightComponentSelectCycle0;
|
||||
uint8_t padRightComponentSelectCycle1;
|
||||
uint8_t padRightComponentSelectCycle2;
|
||||
uint8_t padRightComponentSelectCycle3;
|
||||
uint8_t padRightStopCycle0;
|
||||
uint8_t padRightStopCycle1;
|
||||
uint8_t padRightStopCycle2;
|
||||
uint8_t padRightStopCycle3;
|
||||
uint8_t padTopLineCount;
|
||||
uint8_t padBottomLineCount;
|
||||
};
|
||||
|
||||
struct vfe_interrupt_status {
|
||||
uint8_t camifErrorIrq;
|
||||
uint8_t camifSofIrq;
|
||||
uint8_t camifEolIrq;
|
||||
uint8_t camifEofIrq;
|
||||
uint8_t camifEpoch1Irq;
|
||||
uint8_t camifEpoch2Irq;
|
||||
uint8_t camifOverflowIrq;
|
||||
uint8_t ceIrq;
|
||||
uint8_t regUpdateIrq;
|
||||
uint8_t resetAckIrq;
|
||||
uint8_t encYPingpongIrq;
|
||||
uint8_t encCbcrPingpongIrq;
|
||||
uint8_t viewYPingpongIrq;
|
||||
uint8_t viewCbcrPingpongIrq;
|
||||
uint8_t rdPingpongIrq;
|
||||
uint8_t afPingpongIrq;
|
||||
uint8_t awbPingpongIrq;
|
||||
uint8_t histPingpongIrq;
|
||||
uint8_t encIrq;
|
||||
uint8_t viewIrq;
|
||||
uint8_t busOverflowIrq;
|
||||
uint8_t afOverflowIrq;
|
||||
uint8_t awbOverflowIrq;
|
||||
uint8_t syncTimer0Irq;
|
||||
uint8_t syncTimer1Irq;
|
||||
uint8_t syncTimer2Irq;
|
||||
uint8_t asyncTimer0Irq;
|
||||
uint8_t asyncTimer1Irq;
|
||||
uint8_t asyncTimer2Irq;
|
||||
uint8_t asyncTimer3Irq;
|
||||
uint8_t axiErrorIrq;
|
||||
uint8_t violationIrq;
|
||||
uint8_t anyErrorIrqs;
|
||||
uint8_t anyOutput1PathIrqs;
|
||||
uint8_t anyOutput2PathIrqs;
|
||||
uint8_t anyOutputPathIrqs;
|
||||
uint8_t anyAsyncTimerIrqs;
|
||||
uint8_t anySyncTimerIrqs;
|
||||
uint8_t anyIrqForActiveStatesOnly;
|
||||
};
|
||||
|
||||
enum VFE_MESSAGE_ID {
|
||||
VFE_MSG_ID_RESET_ACK,
|
||||
VFE_MSG_ID_START_ACK,
|
||||
VFE_MSG_ID_STOP_ACK,
|
||||
VFE_MSG_ID_UPDATE_ACK,
|
||||
VFE_MSG_ID_OUTPUT1,
|
||||
VFE_MSG_ID_OUTPUT2,
|
||||
VFE_MSG_ID_SNAPSHOT_DONE,
|
||||
VFE_MSG_ID_STATS_AUTOFOCUS,
|
||||
VFE_MSG_ID_STATS_WB_EXP,
|
||||
VFE_MSG_ID_EPOCH1,
|
||||
VFE_MSG_ID_EPOCH2,
|
||||
VFE_MSG_ID_SYNC_TIMER0_DONE,
|
||||
VFE_MSG_ID_SYNC_TIMER1_DONE,
|
||||
VFE_MSG_ID_SYNC_TIMER2_DONE,
|
||||
VFE_MSG_ID_ASYNC_TIMER0_DONE,
|
||||
VFE_MSG_ID_ASYNC_TIMER1_DONE,
|
||||
VFE_MSG_ID_ASYNC_TIMER2_DONE,
|
||||
VFE_MSG_ID_ASYNC_TIMER3_DONE,
|
||||
VFE_MSG_ID_AF_OVERFLOW,
|
||||
VFE_MSG_ID_AWB_OVERFLOW,
|
||||
VFE_MSG_ID_AXI_ERROR,
|
||||
VFE_MSG_ID_CAMIF_OVERFLOW,
|
||||
VFE_MSG_ID_VIOLATION,
|
||||
VFE_MSG_ID_CAMIF_ERROR,
|
||||
VFE_MSG_ID_BUS_OVERFLOW,
|
||||
};
|
||||
|
||||
struct vfe_msg_stats_autofocus {
|
||||
uint32_t afBuffer;
|
||||
uint32_t frameCounter;
|
||||
};
|
||||
|
||||
struct vfe_msg_stats_wb_exp {
|
||||
uint32_t awbBuffer;
|
||||
uint32_t frameCounter;
|
||||
};
|
||||
|
||||
struct vfe_frame_bpc_info {
|
||||
uint32_t greenDefectPixelCount;
|
||||
uint32_t redBlueDefectPixelCount;
|
||||
};
|
||||
|
||||
struct vfe_frame_asf_info {
|
||||
uint32_t asfMaxEdge;
|
||||
uint32_t asfHbiCount;
|
||||
};
|
||||
|
||||
struct vfe_msg_camif_status {
|
||||
uint8_t camifState;
|
||||
uint32_t pixelCount;
|
||||
uint32_t lineCount;
|
||||
};
|
||||
|
||||
struct vfe_bus_pm_per_path {
|
||||
uint32_t yWrPmStats0;
|
||||
uint32_t yWrPmStats1;
|
||||
uint32_t cbcrWrPmStats0;
|
||||
uint32_t cbcrWrPmStats1;
|
||||
};
|
||||
|
||||
struct vfe_bus_performance_monitor {
|
||||
struct vfe_bus_pm_per_path encPathPmInfo;
|
||||
struct vfe_bus_pm_per_path viewPathPmInfo;
|
||||
};
|
||||
|
||||
struct vfe_irq_thread_msg {
|
||||
uint32_t vfeIrqStatus;
|
||||
uint32_t camifStatus;
|
||||
uint32_t demosaicStatus;
|
||||
uint32_t asfMaxEdge;
|
||||
struct vfe_bus_performance_monitor pmInfo;
|
||||
};
|
||||
|
||||
struct vfe_msg_output {
|
||||
uint32_t yBuffer;
|
||||
uint32_t cbcrBuffer;
|
||||
struct vfe_frame_bpc_info bpcInfo;
|
||||
struct vfe_frame_asf_info asfInfo;
|
||||
uint32_t frameCounter;
|
||||
struct vfe_bus_pm_per_path pmData;
|
||||
};
|
||||
|
||||
struct vfe_message {
|
||||
enum VFE_MESSAGE_ID _d;
|
||||
union {
|
||||
struct vfe_msg_output msgOutput1;
|
||||
struct vfe_msg_output msgOutput2;
|
||||
struct vfe_msg_stats_autofocus msgStatsAf;
|
||||
struct vfe_msg_stats_wb_exp msgStatsWbExp;
|
||||
struct vfe_msg_camif_status msgCamifError;
|
||||
struct vfe_bus_performance_monitor msgBusOverflow;
|
||||
} _u;
|
||||
};
|
||||
|
||||
/* New one for 8k */
|
||||
struct msm_vfe_command_8k {
|
||||
int32_t id;
|
||||
uint16_t length;
|
||||
void *value;
|
||||
};
|
||||
|
||||
struct vfe_frame_extra {
|
||||
struct vfe_frame_bpc_info bpcInfo;
|
||||
struct vfe_frame_asf_info asfInfo;
|
||||
uint32_t frameCounter;
|
||||
struct vfe_bus_pm_per_path pmData;
|
||||
};
|
||||
#endif /* __MSM_VFE8X_H__ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,761 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <media/msm_camera.h>
|
||||
#include <mach/gpio.h>
|
||||
#include "mt9d112.h"
|
||||
|
||||
/* Micron MT9D112 Registers and their values */
|
||||
/* Sensor Core Registers */
|
||||
#define REG_MT9D112_MODEL_ID 0x3000
|
||||
#define MT9D112_MODEL_ID 0x1580
|
||||
|
||||
/* SOC Registers Page 1 */
|
||||
#define REG_MT9D112_SENSOR_RESET 0x301A
|
||||
#define REG_MT9D112_STANDBY_CONTROL 0x3202
|
||||
#define REG_MT9D112_MCU_BOOT 0x3386
|
||||
|
||||
struct mt9d112_work {
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
static struct mt9d112_work *mt9d112_sensorw;
|
||||
static struct i2c_client *mt9d112_client;
|
||||
|
||||
struct mt9d112_ctrl {
|
||||
const struct msm_camera_sensor_info *sensordata;
|
||||
};
|
||||
|
||||
|
||||
static struct mt9d112_ctrl *mt9d112_ctrl;
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue);
|
||||
DECLARE_MUTEX(mt9d112_sem);
|
||||
|
||||
|
||||
/*=============================================================
|
||||
EXTERNAL DECLARATIONS
|
||||
==============================================================*/
|
||||
extern struct mt9d112_reg mt9d112_regs;
|
||||
|
||||
|
||||
/*=============================================================*/
|
||||
|
||||
static int mt9d112_reset(const struct msm_camera_sensor_info *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = gpio_request(dev->sensor_reset, "mt9d112");
|
||||
|
||||
if (!rc) {
|
||||
rc = gpio_direction_output(dev->sensor_reset, 0);
|
||||
mdelay(20);
|
||||
rc = gpio_direction_output(dev->sensor_reset, 1);
|
||||
}
|
||||
|
||||
gpio_free(dev->sensor_reset);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_i2c_txdata(unsigned short saddr,
|
||||
unsigned char *txdata, int length)
|
||||
{
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = saddr,
|
||||
.flags = 0,
|
||||
.len = length,
|
||||
.buf = txdata,
|
||||
},
|
||||
};
|
||||
|
||||
if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) {
|
||||
CDBG("mt9d112_i2c_txdata failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_i2c_write(unsigned short saddr,
|
||||
unsigned short waddr, unsigned short wdata, enum mt9d112_width width)
|
||||
{
|
||||
int32_t rc = -EIO;
|
||||
unsigned char buf[4];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
switch (width) {
|
||||
case WORD_LEN: {
|
||||
buf[0] = (waddr & 0xFF00)>>8;
|
||||
buf[1] = (waddr & 0x00FF);
|
||||
buf[2] = (wdata & 0xFF00)>>8;
|
||||
buf[3] = (wdata & 0x00FF);
|
||||
|
||||
rc = mt9d112_i2c_txdata(saddr, buf, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case BYTE_LEN: {
|
||||
buf[0] = waddr;
|
||||
buf[1] = wdata;
|
||||
rc = mt9d112_i2c_txdata(saddr, buf, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
CDBG(
|
||||
"i2c_write failed, addr = 0x%x, val = 0x%x!\n",
|
||||
waddr, wdata);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_i2c_write_table(
|
||||
struct mt9d112_i2c_reg_conf const *reg_conf_tbl,
|
||||
int num_of_items_in_table)
|
||||
{
|
||||
int i;
|
||||
int32_t rc = -EIO;
|
||||
|
||||
for (i = 0; i < num_of_items_in_table; i++) {
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
reg_conf_tbl->waddr, reg_conf_tbl->wdata,
|
||||
reg_conf_tbl->width);
|
||||
if (rc < 0)
|
||||
break;
|
||||
if (reg_conf_tbl->mdelay_time != 0)
|
||||
mdelay(reg_conf_tbl->mdelay_time);
|
||||
reg_conf_tbl++;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mt9d112_i2c_rxdata(unsigned short saddr,
|
||||
unsigned char *rxdata, int length)
|
||||
{
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = saddr,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = rxdata,
|
||||
},
|
||||
{
|
||||
.addr = saddr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = length,
|
||||
.buf = rxdata,
|
||||
},
|
||||
};
|
||||
|
||||
if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) {
|
||||
CDBG("mt9d112_i2c_rxdata failed!\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_i2c_read(unsigned short saddr,
|
||||
unsigned short raddr, unsigned short *rdata, enum mt9d112_width width)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
unsigned char buf[4];
|
||||
|
||||
if (!rdata)
|
||||
return -EIO;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
switch (width) {
|
||||
case WORD_LEN: {
|
||||
buf[0] = (raddr & 0xFF00)>>8;
|
||||
buf[1] = (raddr & 0x00FF);
|
||||
|
||||
rc = mt9d112_i2c_rxdata(saddr, buf, 2);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
*rdata = buf[0] << 8 | buf[1];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
CDBG("mt9d112_i2c_read failed!\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int32_t mt9d112_set_lens_roll_off(void)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0],
|
||||
mt9d112_regs.rftbl_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long mt9d112_reg_init(void)
|
||||
{
|
||||
int32_t array_length;
|
||||
int32_t i;
|
||||
long rc;
|
||||
|
||||
/* PLL Setup Start */
|
||||
rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0],
|
||||
mt9d112_regs.plltbl_size);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
/* PLL Setup End */
|
||||
|
||||
array_length = mt9d112_regs.prev_snap_reg_settings_size;
|
||||
|
||||
/* Configure sensor for Preview mode and Snapshot mode */
|
||||
for (i = 0; i < array_length; i++) {
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
mt9d112_regs.prev_snap_reg_settings[i].register_address,
|
||||
mt9d112_regs.prev_snap_reg_settings[i].register_value,
|
||||
WORD_LEN);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Configure for Noise Reduction, Saturation and Aperture Correction */
|
||||
array_length = mt9d112_regs.noise_reduction_reg_settings_size;
|
||||
|
||||
for (i = 0; i < array_length; i++) {
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
mt9d112_regs.noise_reduction_reg_settings[i].register_address,
|
||||
mt9d112_regs.noise_reduction_reg_settings[i].register_value,
|
||||
WORD_LEN);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Set Color Kill Saturation point to optimum value */
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x35A4,
|
||||
0x0593,
|
||||
WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0],
|
||||
mt9d112_regs.stbl_size);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_set_lens_roll_off();
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long mt9d112_set_sensor_mode(int mode)
|
||||
{
|
||||
uint16_t clock;
|
||||
long rc = 0;
|
||||
|
||||
switch (mode) {
|
||||
case SENSOR_PREVIEW_MODE:
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA20C, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0004, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA215, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0004, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA20B, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0000, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
clock = 0x0250;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x341C, clock, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA103, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0001, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
mdelay(5);
|
||||
break;
|
||||
|
||||
case SENSOR_SNAPSHOT_MODE:
|
||||
/* Switch to lower fps for Snapshot */
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x341C, 0x0120, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA120, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0002, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
mdelay(5);
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA103, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc =
|
||||
mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0002, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long mt9d112_set_effect(int mode, int effect)
|
||||
{
|
||||
uint16_t reg_addr;
|
||||
uint16_t reg_val;
|
||||
long rc = 0;
|
||||
|
||||
switch (mode) {
|
||||
case SENSOR_PREVIEW_MODE:
|
||||
/* Context A Special Effects */
|
||||
reg_addr = 0x2799;
|
||||
break;
|
||||
|
||||
case SENSOR_SNAPSHOT_MODE:
|
||||
/* Context B Special Effects */
|
||||
reg_addr = 0x279B;
|
||||
break;
|
||||
|
||||
default:
|
||||
reg_addr = 0x2799;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (effect) {
|
||||
case CAMERA_EFFECT_OFF: {
|
||||
reg_val = 0x6440;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_MONO: {
|
||||
reg_val = 0x6441;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_NEGATIVE: {
|
||||
reg_val = 0x6443;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_SOLARIZE: {
|
||||
reg_val = 0x6445;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_SEPIA: {
|
||||
reg_val = 0x6442;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
|
||||
case CAMERA_EFFECT_PASTEL:
|
||||
case CAMERA_EFFECT_MOSAIC:
|
||||
case CAMERA_EFFECT_RESIZE:
|
||||
return -EINVAL;
|
||||
|
||||
default: {
|
||||
reg_val = 0x6440;
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, reg_addr, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, reg_val, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Refresh Sequencer */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x338C, 0xA103, WORD_LEN);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x3390, 0x0005, WORD_LEN);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data)
|
||||
{
|
||||
uint16_t model_id = 0;
|
||||
int rc = 0;
|
||||
|
||||
CDBG("init entry \n");
|
||||
rc = mt9d112_reset(data);
|
||||
if (rc < 0) {
|
||||
CDBG("reset failed!\n");
|
||||
goto init_probe_fail;
|
||||
}
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/* Micron suggested Power up block Start:
|
||||
* Put MCU into Reset - Stop MCU */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
/* Pull MCU from Reset - Start MCU */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/* Micron Suggested - Power up block */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
/* FUSED_DEFECT_CORRECTION */
|
||||
rc = mt9d112_i2c_write(mt9d112_client->addr,
|
||||
0x33F4, 0x031D, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/* Micron suggested Power up block End */
|
||||
/* Read the Model ID of the sensor */
|
||||
rc = mt9d112_i2c_read(mt9d112_client->addr,
|
||||
REG_MT9D112_MODEL_ID, &model_id, WORD_LEN);
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
CDBG("mt9d112 model_id = 0x%x\n", model_id);
|
||||
|
||||
/* Check if it matches it with the value in Datasheet */
|
||||
if (model_id != MT9D112_MODEL_ID) {
|
||||
rc = -EINVAL;
|
||||
goto init_probe_fail;
|
||||
}
|
||||
|
||||
rc = mt9d112_reg_init();
|
||||
if (rc < 0)
|
||||
goto init_probe_fail;
|
||||
|
||||
return rc;
|
||||
|
||||
init_probe_fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mt9d112_sensor_init(const struct msm_camera_sensor_info *data)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL);
|
||||
if (!mt9d112_ctrl) {
|
||||
CDBG("mt9d112_init failed!\n");
|
||||
rc = -ENOMEM;
|
||||
goto init_done;
|
||||
}
|
||||
|
||||
if (data)
|
||||
mt9d112_ctrl->sensordata = data;
|
||||
|
||||
/* Input MCLK = 24MHz */
|
||||
msm_camio_clk_rate_set(24000000);
|
||||
mdelay(5);
|
||||
|
||||
msm_camio_camif_pad_reg_reset();
|
||||
|
||||
rc = mt9d112_sensor_init_probe(data);
|
||||
if (rc < 0) {
|
||||
CDBG("mt9d112_sensor_init failed!\n");
|
||||
goto init_fail;
|
||||
}
|
||||
|
||||
init_done:
|
||||
return rc;
|
||||
|
||||
init_fail:
|
||||
kfree(mt9d112_ctrl);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mt9d112_init_client(struct i2c_client *client)
|
||||
{
|
||||
/* Initialize the MSM_CAMI2C Chip */
|
||||
init_waitqueue_head(&mt9d112_wait_queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt9d112_sensor_config(void __user *argp)
|
||||
{
|
||||
struct sensor_cfg_data cfg_data;
|
||||
long rc = 0;
|
||||
|
||||
if (copy_from_user(&cfg_data,
|
||||
(void *)argp,
|
||||
sizeof(struct sensor_cfg_data)))
|
||||
return -EFAULT;
|
||||
|
||||
/* down(&mt9d112_sem); */
|
||||
|
||||
CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n",
|
||||
cfg_data.cfgtype, cfg_data.mode);
|
||||
|
||||
switch (cfg_data.cfgtype) {
|
||||
case CFG_SET_MODE:
|
||||
rc = mt9d112_set_sensor_mode(
|
||||
cfg_data.mode);
|
||||
break;
|
||||
|
||||
case CFG_SET_EFFECT:
|
||||
rc = mt9d112_set_effect(cfg_data.mode,
|
||||
cfg_data.cfg.effect);
|
||||
break;
|
||||
|
||||
case CFG_GET_AF_MAX_STEPS:
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* up(&mt9d112_sem); */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int mt9d112_sensor_release(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* down(&mt9d112_sem); */
|
||||
|
||||
kfree(mt9d112_ctrl);
|
||||
/* up(&mt9d112_sem); */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mt9d112_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int rc = 0;
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
rc = -ENOTSUPP;
|
||||
goto probe_failure;
|
||||
}
|
||||
|
||||
mt9d112_sensorw =
|
||||
kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL);
|
||||
|
||||
if (!mt9d112_sensorw) {
|
||||
rc = -ENOMEM;
|
||||
goto probe_failure;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, mt9d112_sensorw);
|
||||
mt9d112_init_client(client);
|
||||
mt9d112_client = client;
|
||||
|
||||
CDBG("mt9d112_probe succeeded!\n");
|
||||
|
||||
return 0;
|
||||
|
||||
probe_failure:
|
||||
kfree(mt9d112_sensorw);
|
||||
mt9d112_sensorw = NULL;
|
||||
CDBG("mt9d112_probe failed!\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id mt9d112_i2c_id[] = {
|
||||
{ "mt9d112", 0},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct i2c_driver mt9d112_i2c_driver = {
|
||||
.id_table = mt9d112_i2c_id,
|
||||
.probe = mt9d112_i2c_probe,
|
||||
.remove = __exit_p(mt9d112_i2c_remove),
|
||||
.driver = {
|
||||
.name = "mt9d112",
|
||||
},
|
||||
};
|
||||
|
||||
static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info,
|
||||
struct msm_sensor_ctrl *s)
|
||||
{
|
||||
int rc = i2c_add_driver(&mt9d112_i2c_driver);
|
||||
if (rc < 0 || mt9d112_client == NULL) {
|
||||
rc = -ENOTSUPP;
|
||||
goto probe_done;
|
||||
}
|
||||
|
||||
/* Input MCLK = 24MHz */
|
||||
msm_camio_clk_rate_set(24000000);
|
||||
mdelay(5);
|
||||
|
||||
rc = mt9d112_sensor_init_probe(info);
|
||||
if (rc < 0)
|
||||
goto probe_done;
|
||||
|
||||
s->s_init = mt9d112_sensor_init;
|
||||
s->s_release = mt9d112_sensor_release;
|
||||
s->s_config = mt9d112_sensor_config;
|
||||
|
||||
probe_done:
|
||||
CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __mt9d112_probe(struct platform_device *pdev)
|
||||
{
|
||||
return msm_camera_drv_start(pdev, mt9d112_sensor_probe);
|
||||
}
|
||||
|
||||
static struct platform_driver msm_camera_driver = {
|
||||
.probe = __mt9d112_probe,
|
||||
.driver = {
|
||||
.name = "msm_camera_mt9d112",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mt9d112_init(void)
|
||||
{
|
||||
return platform_driver_register(&msm_camera_driver);
|
||||
}
|
||||
|
||||
module_init(mt9d112_init);
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#ifndef MT9D112_H
|
||||
#define MT9D112_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <mach/camera.h>
|
||||
|
||||
enum mt9d112_width {
|
||||
WORD_LEN,
|
||||
BYTE_LEN
|
||||
};
|
||||
|
||||
struct mt9d112_i2c_reg_conf {
|
||||
unsigned short waddr;
|
||||
unsigned short wdata;
|
||||
enum mt9d112_width width;
|
||||
unsigned short mdelay_time;
|
||||
};
|
||||
|
||||
struct mt9d112_reg {
|
||||
const struct register_address_value_pair *prev_snap_reg_settings;
|
||||
uint16_t prev_snap_reg_settings_size;
|
||||
const struct register_address_value_pair *noise_reduction_reg_settings;
|
||||
uint16_t noise_reduction_reg_settings_size;
|
||||
const struct mt9d112_i2c_reg_conf *plltbl;
|
||||
uint16_t plltbl_size;
|
||||
const struct mt9d112_i2c_reg_conf *stbl;
|
||||
uint16_t stbl_size;
|
||||
const struct mt9d112_i2c_reg_conf *rftbl;
|
||||
uint16_t rftbl_size;
|
||||
};
|
||||
|
||||
#endif /* MT9D112_H */
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include "mt9d112.h"
|
||||
|
||||
struct register_address_value_pair
|
||||
preview_snapshot_mode_reg_settings_array[] = {
|
||||
{0x338C, 0x2703},
|
||||
{0x3390, 800}, /* Output Width (P) = 640 */
|
||||
{0x338C, 0x2705},
|
||||
{0x3390, 600}, /* Output Height (P) = 480 */
|
||||
{0x338C, 0x2707},
|
||||
{0x3390, 0x0640}, /* Output Width (S) = 1600 */
|
||||
{0x338C, 0x2709},
|
||||
{0x3390, 0x04B0}, /* Output Height (S) = 1200 */
|
||||
{0x338C, 0x270D},
|
||||
{0x3390, 0x0000}, /* Row Start (P) = 0 */
|
||||
{0x338C, 0x270F},
|
||||
{0x3390, 0x0000}, /* Column Start (P) = 0 */
|
||||
{0x338C, 0x2711},
|
||||
{0x3390, 0x04BD}, /* Row End (P) = 1213 */
|
||||
{0x338C, 0x2713},
|
||||
{0x3390, 0x064D}, /* Column End (P) = 1613 */
|
||||
{0x338C, 0x2715},
|
||||
{0x3390, 0x0000}, /* Extra Delay (P) = 0 */
|
||||
{0x338C, 0x2717},
|
||||
{0x3390, 0x2111}, /* Row Speed (P) = 8465 */
|
||||
{0x338C, 0x2719},
|
||||
{0x3390, 0x046C}, /* Read Mode (P) = 1132 */
|
||||
{0x338C, 0x271B},
|
||||
{0x3390, 0x024F}, /* Sensor_Sample_Time_pck(P) = 591 */
|
||||
{0x338C, 0x271D},
|
||||
{0x3390, 0x0102}, /* Sensor_Fine_Correction(P) = 258 */
|
||||
{0x338C, 0x271F},
|
||||
{0x3390, 0x0279}, /* Sensor_Fine_IT_min(P) = 633 */
|
||||
{0x338C, 0x2721},
|
||||
{0x3390, 0x0155}, /* Sensor_Fine_IT_max_margin(P) = 341 */
|
||||
{0x338C, 0x2723},
|
||||
{0x3390, 659}, /* Frame Lines (P) = 679 */
|
||||
{0x338C, 0x2725},
|
||||
{0x3390, 0x0824}, /* Line Length (P) = 2084 */
|
||||
{0x338C, 0x2727},
|
||||
{0x3390, 0x2020},
|
||||
{0x338C, 0x2729},
|
||||
{0x3390, 0x2020},
|
||||
{0x338C, 0x272B},
|
||||
{0x3390, 0x1020},
|
||||
{0x338C, 0x272D},
|
||||
{0x3390, 0x2007},
|
||||
{0x338C, 0x272F},
|
||||
{0x3390, 0x0004}, /* Row Start(S) = 4 */
|
||||
{0x338C, 0x2731},
|
||||
{0x3390, 0x0004}, /* Column Start(S) = 4 */
|
||||
{0x338C, 0x2733},
|
||||
{0x3390, 0x04BB}, /* Row End(S) = 1211 */
|
||||
{0x338C, 0x2735},
|
||||
{0x3390, 0x064B}, /* Column End(S) = 1611 */
|
||||
{0x338C, 0x2737},
|
||||
{0x3390, 0x04CE}, /* Extra Delay(S) = 1230 */
|
||||
{0x338C, 0x2739},
|
||||
{0x3390, 0x2111}, /* Row Speed(S) = 8465 */
|
||||
{0x338C, 0x273B},
|
||||
{0x3390, 0x0024}, /* Read Mode(S) = 36 */
|
||||
{0x338C, 0x273D},
|
||||
{0x3390, 0x0120}, /* Sensor sample time pck(S) = 288 */
|
||||
{0x338C, 0x2741},
|
||||
{0x3390, 0x0169}, /* Sensor_Fine_IT_min(P) = 361 */
|
||||
{0x338C, 0x2745},
|
||||
{0x3390, 0x04FF}, /* Frame Lines(S) = 1279 */
|
||||
{0x338C, 0x2747},
|
||||
{0x3390, 0x0824}, /* Line Length(S) = 2084 */
|
||||
{0x338C, 0x2751},
|
||||
{0x3390, 0x0000}, /* Crop_X0(P) = 0 */
|
||||
{0x338C, 0x2753},
|
||||
{0x3390, 0x0320}, /* Crop_X1(P) = 800 */
|
||||
{0x338C, 0x2755},
|
||||
{0x3390, 0x0000}, /* Crop_Y0(P) = 0 */
|
||||
{0x338C, 0x2757},
|
||||
{0x3390, 0x0258}, /* Crop_Y1(P) = 600 */
|
||||
{0x338C, 0x275F},
|
||||
{0x3390, 0x0000}, /* Crop_X0(S) = 0 */
|
||||
{0x338C, 0x2761},
|
||||
{0x3390, 0x0640}, /* Crop_X1(S) = 1600 */
|
||||
{0x338C, 0x2763},
|
||||
{0x3390, 0x0000}, /* Crop_Y0(S) = 0 */
|
||||
{0x338C, 0x2765},
|
||||
{0x3390, 0x04B0}, /* Crop_Y1(S) = 1200 */
|
||||
{0x338C, 0x222E},
|
||||
{0x3390, 0x00A0}, /* R9 Step = 160 */
|
||||
{0x338C, 0xA408},
|
||||
{0x3390, 0x001F},
|
||||
{0x338C, 0xA409},
|
||||
{0x3390, 0x0021},
|
||||
{0x338C, 0xA40A},
|
||||
{0x3390, 0x0025},
|
||||
{0x338C, 0xA40B},
|
||||
{0x3390, 0x0027},
|
||||
{0x338C, 0x2411},
|
||||
{0x3390, 0x00A0},
|
||||
{0x338C, 0x2413},
|
||||
{0x3390, 0x00C0},
|
||||
{0x338C, 0x2415},
|
||||
{0x3390, 0x00A0},
|
||||
{0x338C, 0x2417},
|
||||
{0x3390, 0x00C0},
|
||||
{0x338C, 0x2799},
|
||||
{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(P) */
|
||||
{0x338C, 0x279B},
|
||||
{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(S) */
|
||||
};
|
||||
|
||||
static struct register_address_value_pair
|
||||
noise_reduction_reg_settings_array[] = {
|
||||
{0x338C, 0xA76D},
|
||||
{0x3390, 0x0003},
|
||||
{0x338C, 0xA76E},
|
||||
{0x3390, 0x0003},
|
||||
{0x338C, 0xA76F},
|
||||
{0x3390, 0},
|
||||
{0x338C, 0xA770},
|
||||
{0x3390, 21},
|
||||
{0x338C, 0xA771},
|
||||
{0x3390, 37},
|
||||
{0x338C, 0xA772},
|
||||
{0x3390, 63},
|
||||
{0x338C, 0xA773},
|
||||
{0x3390, 100},
|
||||
{0x338C, 0xA774},
|
||||
{0x3390, 128},
|
||||
{0x338C, 0xA775},
|
||||
{0x3390, 151},
|
||||
{0x338C, 0xA776},
|
||||
{0x3390, 169},
|
||||
{0x338C, 0xA777},
|
||||
{0x3390, 186},
|
||||
{0x338C, 0xA778},
|
||||
{0x3390, 199},
|
||||
{0x338C, 0xA779},
|
||||
{0x3390, 210},
|
||||
{0x338C, 0xA77A},
|
||||
{0x3390, 220},
|
||||
{0x338C, 0xA77B},
|
||||
{0x3390, 228},
|
||||
{0x338C, 0xA77C},
|
||||
{0x3390, 234},
|
||||
{0x338C, 0xA77D},
|
||||
{0x3390, 240},
|
||||
{0x338C, 0xA77E},
|
||||
{0x3390, 244},
|
||||
{0x338C, 0xA77F},
|
||||
{0x3390, 248},
|
||||
{0x338C, 0xA780},
|
||||
{0x3390, 252},
|
||||
{0x338C, 0xA781},
|
||||
{0x3390, 255},
|
||||
{0x338C, 0xA782},
|
||||
{0x3390, 0},
|
||||
{0x338C, 0xA783},
|
||||
{0x3390, 21},
|
||||
{0x338C, 0xA784},
|
||||
{0x3390, 37},
|
||||
{0x338C, 0xA785},
|
||||
{0x3390, 63},
|
||||
{0x338C, 0xA786},
|
||||
{0x3390, 100},
|
||||
{0x338C, 0xA787},
|
||||
{0x3390, 128},
|
||||
{0x338C, 0xA788},
|
||||
{0x3390, 151},
|
||||
{0x338C, 0xA789},
|
||||
{0x3390, 169},
|
||||
{0x338C, 0xA78A},
|
||||
{0x3390, 186},
|
||||
{0x338C, 0xA78B},
|
||||
{0x3390, 199},
|
||||
{0x338C, 0xA78C},
|
||||
{0x3390, 210},
|
||||
{0x338C, 0xA78D},
|
||||
{0x3390, 220},
|
||||
{0x338C, 0xA78E},
|
||||
{0x3390, 228},
|
||||
{0x338C, 0xA78F},
|
||||
{0x3390, 234},
|
||||
{0x338C, 0xA790},
|
||||
{0x3390, 240},
|
||||
{0x338C, 0xA791},
|
||||
{0x3390, 244},
|
||||
{0x338C, 0xA793},
|
||||
{0x3390, 252},
|
||||
{0x338C, 0xA794},
|
||||
{0x3390, 255},
|
||||
{0x338C, 0xA103},
|
||||
{0x3390, 6},
|
||||
};
|
||||
|
||||
static const struct mt9d112_i2c_reg_conf const lens_roll_off_tbl[] = {
|
||||
{ 0x34CE, 0x81A0, WORD_LEN, 0 },
|
||||
{ 0x34D0, 0x6331, WORD_LEN, 0 },
|
||||
{ 0x34D2, 0x3394, WORD_LEN, 0 },
|
||||
{ 0x34D4, 0x9966, WORD_LEN, 0 },
|
||||
{ 0x34D6, 0x4B25, WORD_LEN, 0 },
|
||||
{ 0x34D8, 0x2670, WORD_LEN, 0 },
|
||||
{ 0x34DA, 0x724C, WORD_LEN, 0 },
|
||||
{ 0x34DC, 0xFFFD, WORD_LEN, 0 },
|
||||
{ 0x34DE, 0x00CA, WORD_LEN, 0 },
|
||||
{ 0x34E6, 0x00AC, WORD_LEN, 0 },
|
||||
{ 0x34EE, 0x0EE1, WORD_LEN, 0 },
|
||||
{ 0x34F6, 0x0D87, WORD_LEN, 0 },
|
||||
{ 0x3500, 0xE1F7, WORD_LEN, 0 },
|
||||
{ 0x3508, 0x1CF4, WORD_LEN, 0 },
|
||||
{ 0x3510, 0x1D28, WORD_LEN, 0 },
|
||||
{ 0x3518, 0x1F26, WORD_LEN, 0 },
|
||||
{ 0x3520, 0x2220, WORD_LEN, 0 },
|
||||
{ 0x3528, 0x333D, WORD_LEN, 0 },
|
||||
{ 0x3530, 0x15D9, WORD_LEN, 0 },
|
||||
{ 0x3538, 0xCFB8, WORD_LEN, 0 },
|
||||
{ 0x354C, 0x05FE, WORD_LEN, 0 },
|
||||
{ 0x3544, 0x05F8, WORD_LEN, 0 },
|
||||
{ 0x355C, 0x0596, WORD_LEN, 0 },
|
||||
{ 0x3554, 0x0611, WORD_LEN, 0 },
|
||||
{ 0x34E0, 0x00F2, WORD_LEN, 0 },
|
||||
{ 0x34E8, 0x00A8, WORD_LEN, 0 },
|
||||
{ 0x34F0, 0x0F7B, WORD_LEN, 0 },
|
||||
{ 0x34F8, 0x0CD7, WORD_LEN, 0 },
|
||||
{ 0x3502, 0xFEDB, WORD_LEN, 0 },
|
||||
{ 0x350A, 0x13E4, WORD_LEN, 0 },
|
||||
{ 0x3512, 0x1F2C, WORD_LEN, 0 },
|
||||
{ 0x351A, 0x1D20, WORD_LEN, 0 },
|
||||
{ 0x3522, 0x2422, WORD_LEN, 0 },
|
||||
{ 0x352A, 0x2925, WORD_LEN, 0 },
|
||||
{ 0x3532, 0x1D04, WORD_LEN, 0 },
|
||||
{ 0x353A, 0xFBF2, WORD_LEN, 0 },
|
||||
{ 0x354E, 0x0616, WORD_LEN, 0 },
|
||||
{ 0x3546, 0x0597, WORD_LEN, 0 },
|
||||
{ 0x355E, 0x05CD, WORD_LEN, 0 },
|
||||
{ 0x3556, 0x0529, WORD_LEN, 0 },
|
||||
{ 0x34E4, 0x00B2, WORD_LEN, 0 },
|
||||
{ 0x34EC, 0x005E, WORD_LEN, 0 },
|
||||
{ 0x34F4, 0x0F43, WORD_LEN, 0 },
|
||||
{ 0x34FC, 0x0E2F, WORD_LEN, 0 },
|
||||
{ 0x3506, 0xF9FC, WORD_LEN, 0 },
|
||||
{ 0x350E, 0x0CE4, WORD_LEN, 0 },
|
||||
{ 0x3516, 0x1E1E, WORD_LEN, 0 },
|
||||
{ 0x351E, 0x1B19, WORD_LEN, 0 },
|
||||
{ 0x3526, 0x151B, WORD_LEN, 0 },
|
||||
{ 0x352E, 0x1416, WORD_LEN, 0 },
|
||||
{ 0x3536, 0x10FC, WORD_LEN, 0 },
|
||||
{ 0x353E, 0xC018, WORD_LEN, 0 },
|
||||
{ 0x3552, 0x06B4, WORD_LEN, 0 },
|
||||
{ 0x354A, 0x0506, WORD_LEN, 0 },
|
||||
{ 0x3562, 0x06AB, WORD_LEN, 0 },
|
||||
{ 0x355A, 0x063A, WORD_LEN, 0 },
|
||||
{ 0x34E2, 0x00E5, WORD_LEN, 0 },
|
||||
{ 0x34EA, 0x008B, WORD_LEN, 0 },
|
||||
{ 0x34F2, 0x0E4C, WORD_LEN, 0 },
|
||||
{ 0x34FA, 0x0CA3, WORD_LEN, 0 },
|
||||
{ 0x3504, 0x0907, WORD_LEN, 0 },
|
||||
{ 0x350C, 0x1DFD, WORD_LEN, 0 },
|
||||
{ 0x3514, 0x1E24, WORD_LEN, 0 },
|
||||
{ 0x351C, 0x2529, WORD_LEN, 0 },
|
||||
{ 0x3524, 0x1D20, WORD_LEN, 0 },
|
||||
{ 0x352C, 0x2332, WORD_LEN, 0 },
|
||||
{ 0x3534, 0x10E9, WORD_LEN, 0 },
|
||||
{ 0x353C, 0x0BCB, WORD_LEN, 0 },
|
||||
{ 0x3550, 0x04EF, WORD_LEN, 0 },
|
||||
{ 0x3548, 0x0609, WORD_LEN, 0 },
|
||||
{ 0x3560, 0x0580, WORD_LEN, 0 },
|
||||
{ 0x3558, 0x05DD, WORD_LEN, 0 },
|
||||
{ 0x3540, 0x0000, WORD_LEN, 0 },
|
||||
{ 0x3542, 0x0000, WORD_LEN, 0 }
|
||||
};
|
||||
|
||||
static const struct mt9d112_i2c_reg_conf const pll_setup_tbl[] = {
|
||||
{ 0x341E, 0x8F09, WORD_LEN, 0 },
|
||||
{ 0x341C, 0x0250, WORD_LEN, 0 },
|
||||
{ 0x341E, 0x8F09, WORD_LEN, 5 },
|
||||
{ 0x341E, 0x8F08, WORD_LEN, 0 }
|
||||
};
|
||||
|
||||
/* Refresh Sequencer */
|
||||
static const struct mt9d112_i2c_reg_conf const sequencer_tbl[] = {
|
||||
{ 0x338C, 0x2799, WORD_LEN, 0},
|
||||
{ 0x3390, 0x6440, WORD_LEN, 5},
|
||||
{ 0x338C, 0x279B, WORD_LEN, 0},
|
||||
{ 0x3390, 0x6440, WORD_LEN, 5},
|
||||
{ 0x338C, 0xA103, WORD_LEN, 0},
|
||||
{ 0x3390, 0x0005, WORD_LEN, 5},
|
||||
{ 0x338C, 0xA103, WORD_LEN, 0},
|
||||
{ 0x3390, 0x0006, WORD_LEN, 5}
|
||||
};
|
||||
|
||||
struct mt9d112_reg mt9d112_regs = {
|
||||
.prev_snap_reg_settings = &preview_snapshot_mode_reg_settings_array[0],
|
||||
.prev_snap_reg_settings_size = ARRAY_SIZE(preview_snapshot_mode_reg_settings_array),
|
||||
.noise_reduction_reg_settings = &noise_reduction_reg_settings_array[0],
|
||||
.noise_reduction_reg_settings_size = ARRAY_SIZE(noise_reduction_reg_settings_array),
|
||||
.plltbl = pll_setup_tbl,
|
||||
.plltbl_size = ARRAY_SIZE(pll_setup_tbl),
|
||||
.stbl = sequencer_tbl,
|
||||
.stbl_size = ARRAY_SIZE(sequencer_tbl),
|
||||
.rftbl = lens_roll_off_tbl,
|
||||
.rftbl_size = ARRAY_SIZE(lens_roll_off_tbl)
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MT9T012_H
|
||||
#define MT9T012_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct reg_struct {
|
||||
uint16_t vt_pix_clk_div; /* 0x0300 */
|
||||
uint16_t vt_sys_clk_div; /* 0x0302 */
|
||||
uint16_t pre_pll_clk_div; /* 0x0304 */
|
||||
uint16_t pll_multiplier; /* 0x0306 */
|
||||
uint16_t op_pix_clk_div; /* 0x0308 */
|
||||
uint16_t op_sys_clk_div; /* 0x030A */
|
||||
uint16_t scale_m; /* 0x0404 */
|
||||
uint16_t row_speed; /* 0x3016 */
|
||||
uint16_t x_addr_start; /* 0x3004 */
|
||||
uint16_t x_addr_end; /* 0x3008 */
|
||||
uint16_t y_addr_start; /* 0x3002 */
|
||||
uint16_t y_addr_end; /* 0x3006 */
|
||||
uint16_t read_mode; /* 0x3040 */
|
||||
uint16_t x_output_size ; /* 0x034C */
|
||||
uint16_t y_output_size; /* 0x034E */
|
||||
uint16_t line_length_pck; /* 0x300C */
|
||||
uint16_t frame_length_lines; /* 0x300A */
|
||||
uint16_t coarse_int_time; /* 0x3012 */
|
||||
uint16_t fine_int_time; /* 0x3014 */
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_i2c_reg_conf {
|
||||
unsigned short waddr;
|
||||
unsigned short wdata;
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_reg {
|
||||
struct reg_struct *reg_pat;
|
||||
uint16_t reg_pat_size;
|
||||
struct mt9p012_i2c_reg_conf *ttbl;
|
||||
uint16_t ttbl_size;
|
||||
struct mt9p012_i2c_reg_conf *lctbl;
|
||||
uint16_t lctbl_size;
|
||||
struct mt9p012_i2c_reg_conf *rftbl;
|
||||
uint16_t rftbl_size;
|
||||
};
|
||||
|
||||
#endif /* MT9T012_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,573 @@
|
|||
/*
|
||||
* Copyright (C) 2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include "mt9p012.h"
|
||||
#include <linux/kernel.h>
|
||||
|
||||
/*Micron settings from Applications for lower power consumption.*/
|
||||
struct reg_struct mt9p012_reg_pat[2] = {
|
||||
{ /* Preview */
|
||||
/* vt_pix_clk_div REG=0x0300 */
|
||||
6, /* 5 */
|
||||
|
||||
/* vt_sys_clk_div REG=0x0302 */
|
||||
1,
|
||||
|
||||
/* pre_pll_clk_div REG=0x0304 */
|
||||
2,
|
||||
|
||||
/* pll_multiplier REG=0x0306 */
|
||||
60,
|
||||
|
||||
/* op_pix_clk_div REG=0x0308 */
|
||||
8, /* 10 */
|
||||
|
||||
/* op_sys_clk_div REG=0x030A */
|
||||
1,
|
||||
|
||||
/* scale_m REG=0x0404 */
|
||||
16,
|
||||
|
||||
/* row_speed REG=0x3016 */
|
||||
0x0111,
|
||||
|
||||
/* x_addr_start REG=0x3004 */
|
||||
8,
|
||||
|
||||
/* x_addr_end REG=0x3008 */
|
||||
2597,
|
||||
|
||||
/* y_addr_start REG=0x3002 */
|
||||
8,
|
||||
|
||||
/* y_addr_end REG=0x3006 */
|
||||
1949,
|
||||
|
||||
/* read_mode REG=0x3040
|
||||
* Preview 2x2 skipping */
|
||||
0x00C3,
|
||||
|
||||
/* x_output_size REG=0x034C */
|
||||
1296,
|
||||
|
||||
/* y_output_size REG=0x034E */
|
||||
972,
|
||||
|
||||
/* line_length_pck REG=0x300C */
|
||||
3784,
|
||||
|
||||
/* frame_length_lines REG=0x300A */
|
||||
1057,
|
||||
|
||||
/* coarse_integration_time REG=0x3012 */
|
||||
16,
|
||||
|
||||
/* fine_integration_time REG=0x3014 */
|
||||
1764
|
||||
},
|
||||
{ /*Snapshot*/
|
||||
/* vt_pix_clk_div REG=0x0300 */
|
||||
6,
|
||||
|
||||
/* vt_sys_clk_div REG=0x0302 */
|
||||
1,
|
||||
|
||||
/* pre_pll_clk_div REG=0x0304 */
|
||||
2,
|
||||
|
||||
/* pll_multiplier REG=0x0306
|
||||
* 60 for 10fps snapshot */
|
||||
60,
|
||||
|
||||
/* op_pix_clk_div REG=0x0308 */
|
||||
8,
|
||||
|
||||
/* op_sys_clk_div REG=0x030A */
|
||||
1,
|
||||
|
||||
/* scale_m REG=0x0404 */
|
||||
16,
|
||||
|
||||
/* row_speed REG=0x3016 */
|
||||
0x0111,
|
||||
|
||||
/* x_addr_start REG=0x3004 */
|
||||
8,
|
||||
|
||||
/* x_addr_end REG=0x3008 */
|
||||
2615,
|
||||
|
||||
/* y_addr_start REG=0x3002 */
|
||||
8,
|
||||
|
||||
/* y_addr_end REG=0x3006 */
|
||||
1967,
|
||||
|
||||
/* read_mode REG=0x3040 */
|
||||
0x0041,
|
||||
|
||||
/* x_output_size REG=0x034C */
|
||||
2608,
|
||||
|
||||
/* y_output_size REG=0x034E */
|
||||
1960,
|
||||
|
||||
/* line_length_pck REG=0x300C */
|
||||
3911,
|
||||
|
||||
/* frame_length_lines REG=0x300A //10 fps snapshot */
|
||||
2045,
|
||||
|
||||
/* coarse_integration_time REG=0x3012 */
|
||||
16,
|
||||
|
||||
/* fine_integration_time REG=0x3014 */
|
||||
882
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_i2c_reg_conf mt9p012_test_tbl[] = {
|
||||
{0x3044, 0x0544 & 0xFBFF},
|
||||
{0x30CA, 0x0004 | 0x0001},
|
||||
{0x30D4, 0x9020 & 0x7FFF},
|
||||
{0x31E0, 0x0003 & 0xFFFE},
|
||||
{0x3180, 0x91FF & 0x7FFF},
|
||||
{0x301A, (0x10CC | 0x8000) & 0xFFF7},
|
||||
{0x301E, 0x0000},
|
||||
{0x3780, 0x0000},
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_i2c_reg_conf mt9p012_lc_tbl[] = {
|
||||
/* [Lens shading 85 Percent TL84] */
|
||||
/* P_RD_P0Q0 */
|
||||
{0x360A, 0x7FEF},
|
||||
/* P_RD_P0Q1 */
|
||||
{0x360C, 0x232C},
|
||||
/* P_RD_P0Q2 */
|
||||
{0x360E, 0x7050},
|
||||
/* P_RD_P0Q3 */
|
||||
{0x3610, 0xF3CC},
|
||||
/* P_RD_P0Q4 */
|
||||
{0x3612, 0x89D1},
|
||||
/* P_RD_P1Q0 */
|
||||
{0x364A, 0xBE0D},
|
||||
/* P_RD_P1Q1 */
|
||||
{0x364C, 0x9ACB},
|
||||
/* P_RD_P1Q2 */
|
||||
{0x364E, 0x2150},
|
||||
/* P_RD_P1Q3 */
|
||||
{0x3650, 0xB26B},
|
||||
/* P_RD_P1Q4 */
|
||||
{0x3652, 0x9511},
|
||||
/* P_RD_P2Q0 */
|
||||
{0x368A, 0x2151},
|
||||
/* P_RD_P2Q1 */
|
||||
{0x368C, 0x00AD},
|
||||
/* P_RD_P2Q2 */
|
||||
{0x368E, 0x8334},
|
||||
/* P_RD_P2Q3 */
|
||||
{0x3690, 0x478E},
|
||||
/* P_RD_P2Q4 */
|
||||
{0x3692, 0x0515},
|
||||
/* P_RD_P3Q0 */
|
||||
{0x36CA, 0x0710},
|
||||
/* P_RD_P3Q1 */
|
||||
{0x36CC, 0x452D},
|
||||
/* P_RD_P3Q2 */
|
||||
{0x36CE, 0xF352},
|
||||
/* P_RD_P3Q3 */
|
||||
{0x36D0, 0x190F},
|
||||
/* P_RD_P3Q4 */
|
||||
{0x36D2, 0x4413},
|
||||
/* P_RD_P4Q0 */
|
||||
{0x370A, 0xD112},
|
||||
/* P_RD_P4Q1 */
|
||||
{0x370C, 0xF50F},
|
||||
/* P_RD_P4Q2 */
|
||||
{0x370C, 0xF50F},
|
||||
/* P_RD_P4Q3 */
|
||||
{0x3710, 0xDC11},
|
||||
/* P_RD_P4Q4 */
|
||||
{0x3712, 0xD776},
|
||||
/* P_GR_P0Q0 */
|
||||
{0x3600, 0x1750},
|
||||
/* P_GR_P0Q1 */
|
||||
{0x3602, 0xF0AC},
|
||||
/* P_GR_P0Q2 */
|
||||
{0x3604, 0x4711},
|
||||
/* P_GR_P0Q3 */
|
||||
{0x3606, 0x07CE},
|
||||
/* P_GR_P0Q4 */
|
||||
{0x3608, 0x96B2},
|
||||
/* P_GR_P1Q0 */
|
||||
{0x3640, 0xA9AE},
|
||||
/* P_GR_P1Q1 */
|
||||
{0x3642, 0xF9AC},
|
||||
/* P_GR_P1Q2 */
|
||||
{0x3644, 0x39F1},
|
||||
/* P_GR_P1Q3 */
|
||||
{0x3646, 0x016F},
|
||||
/* P_GR_P1Q4 */
|
||||
{0x3648, 0x8AB2},
|
||||
/* P_GR_P2Q0 */
|
||||
{0x3680, 0x1752},
|
||||
/* P_GR_P2Q1 */
|
||||
{0x3682, 0x70F0},
|
||||
/* P_GR_P2Q2 */
|
||||
{0x3684, 0x83F5},
|
||||
/* P_GR_P2Q3 */
|
||||
{0x3686, 0x8392},
|
||||
/* P_GR_P2Q4 */
|
||||
{0x3688, 0x1FD6},
|
||||
/* P_GR_P3Q0 */
|
||||
{0x36C0, 0x1131},
|
||||
/* P_GR_P3Q1 */
|
||||
{0x36C2, 0x3DAF},
|
||||
/* P_GR_P3Q2 */
|
||||
{0x36C4, 0x89B4},
|
||||
/* P_GR_P3Q3 */
|
||||
{0x36C6, 0xA391},
|
||||
/* P_GR_P3Q4 */
|
||||
{0x36C8, 0x1334},
|
||||
/* P_GR_P4Q0 */
|
||||
{0x3700, 0xDC13},
|
||||
/* P_GR_P4Q1 */
|
||||
{0x3702, 0xD052},
|
||||
/* P_GR_P4Q2 */
|
||||
{0x3704, 0x5156},
|
||||
/* P_GR_P4Q3 */
|
||||
{0x3706, 0x1F13},
|
||||
/* P_GR_P4Q4 */
|
||||
{0x3708, 0x8C38},
|
||||
/* P_BL_P0Q0 */
|
||||
{0x3614, 0x0050},
|
||||
/* P_BL_P0Q1 */
|
||||
{0x3616, 0xBD4C},
|
||||
/* P_BL_P0Q2 */
|
||||
{0x3618, 0x41B0},
|
||||
/* P_BL_P0Q3 */
|
||||
{0x361A, 0x660D},
|
||||
/* P_BL_P0Q4 */
|
||||
{0x361C, 0xC590},
|
||||
/* P_BL_P1Q0 */
|
||||
{0x3654, 0x87EC},
|
||||
/* P_BL_P1Q1 */
|
||||
{0x3656, 0xE44C},
|
||||
/* P_BL_P1Q2 */
|
||||
{0x3658, 0x302E},
|
||||
/* P_BL_P1Q3 */
|
||||
{0x365A, 0x106E},
|
||||
/* P_BL_P1Q4 */
|
||||
{0x365C, 0xB58E},
|
||||
/* P_BL_P2Q0 */
|
||||
{0x3694, 0x0DD1},
|
||||
/* P_BL_P2Q1 */
|
||||
{0x3696, 0x2A50},
|
||||
/* P_BL_P2Q2 */
|
||||
{0x3698, 0xC793},
|
||||
/* P_BL_P2Q3 */
|
||||
{0x369A, 0xE8F1},
|
||||
/* P_BL_P2Q4 */
|
||||
{0x369C, 0x4174},
|
||||
/* P_BL_P3Q0 */
|
||||
{0x36D4, 0x01EF},
|
||||
/* P_BL_P3Q1 */
|
||||
{0x36D6, 0x06CF},
|
||||
/* P_BL_P3Q2 */
|
||||
{0x36D8, 0x8D91},
|
||||
/* P_BL_P3Q3 */
|
||||
{0x36DA, 0x91F0},
|
||||
/* P_BL_P3Q4 */
|
||||
{0x36DC, 0x52EF},
|
||||
/* P_BL_P4Q0 */
|
||||
{0x3714, 0xA6D2},
|
||||
/* P_BL_P4Q1 */
|
||||
{0x3716, 0xA312},
|
||||
/* P_BL_P4Q2 */
|
||||
{0x3718, 0x2695},
|
||||
/* P_BL_P4Q3 */
|
||||
{0x371A, 0x3953},
|
||||
/* P_BL_P4Q4 */
|
||||
{0x371C, 0x9356},
|
||||
/* P_GB_P0Q0 */
|
||||
{0x361E, 0x7EAF},
|
||||
/* P_GB_P0Q1 */
|
||||
{0x3620, 0x2A4C},
|
||||
/* P_GB_P0Q2 */
|
||||
{0x3622, 0x49F0},
|
||||
{0x3624, 0xF1EC},
|
||||
/* P_GB_P0Q4 */
|
||||
{0x3626, 0xC670},
|
||||
/* P_GB_P1Q0 */
|
||||
{0x365E, 0x8E0C},
|
||||
/* P_GB_P1Q1 */
|
||||
{0x3660, 0xC2A9},
|
||||
/* P_GB_P1Q2 */
|
||||
{0x3662, 0x274F},
|
||||
/* P_GB_P1Q3 */
|
||||
{0x3664, 0xADAB},
|
||||
/* P_GB_P1Q4 */
|
||||
{0x3666, 0x8EF0},
|
||||
/* P_GB_P2Q0 */
|
||||
{0x369E, 0x09B1},
|
||||
/* P_GB_P2Q1 */
|
||||
{0x36A0, 0xAA2E},
|
||||
/* P_GB_P2Q2 */
|
||||
{0x36A2, 0xC3D3},
|
||||
/* P_GB_P2Q3 */
|
||||
{0x36A4, 0x7FAF},
|
||||
/* P_GB_P2Q4 */
|
||||
{0x36A6, 0x3F34},
|
||||
/* P_GB_P3Q0 */
|
||||
{0x36DE, 0x4C8F},
|
||||
/* P_GB_P3Q1 */
|
||||
{0x36E0, 0x886E},
|
||||
/* P_GB_P3Q2 */
|
||||
{0x36E2, 0xE831},
|
||||
/* P_GB_P3Q3 */
|
||||
{0x36E4, 0x1FD0},
|
||||
/* P_GB_P3Q4 */
|
||||
{0x36E6, 0x1192},
|
||||
/* P_GB_P4Q0 */
|
||||
{0x371E, 0xB952},
|
||||
/* P_GB_P4Q1 */
|
||||
{0x3720, 0x6DCF},
|
||||
/* P_GB_P4Q2 */
|
||||
{0x3722, 0x1B55},
|
||||
/* P_GB_P4Q3 */
|
||||
{0x3724, 0xA112},
|
||||
/* P_GB_P4Q4 */
|
||||
{0x3726, 0x82F6},
|
||||
/* POLY_ORIGIN_C */
|
||||
{0x3782, 0x0510},
|
||||
/* POLY_ORIGIN_R */
|
||||
{0x3784, 0x0390},
|
||||
/* POLY_SC_ENABLE */
|
||||
{0x3780, 0x8000},
|
||||
};
|
||||
|
||||
/* rolloff table for illuminant A */
|
||||
struct mt9p012_i2c_reg_conf mt9p012_rolloff_tbl[] = {
|
||||
/* P_RD_P0Q0 */
|
||||
{0x360A, 0x7FEF},
|
||||
/* P_RD_P0Q1 */
|
||||
{0x360C, 0x232C},
|
||||
/* P_RD_P0Q2 */
|
||||
{0x360E, 0x7050},
|
||||
/* P_RD_P0Q3 */
|
||||
{0x3610, 0xF3CC},
|
||||
/* P_RD_P0Q4 */
|
||||
{0x3612, 0x89D1},
|
||||
/* P_RD_P1Q0 */
|
||||
{0x364A, 0xBE0D},
|
||||
/* P_RD_P1Q1 */
|
||||
{0x364C, 0x9ACB},
|
||||
/* P_RD_P1Q2 */
|
||||
{0x364E, 0x2150},
|
||||
/* P_RD_P1Q3 */
|
||||
{0x3650, 0xB26B},
|
||||
/* P_RD_P1Q4 */
|
||||
{0x3652, 0x9511},
|
||||
/* P_RD_P2Q0 */
|
||||
{0x368A, 0x2151},
|
||||
/* P_RD_P2Q1 */
|
||||
{0x368C, 0x00AD},
|
||||
/* P_RD_P2Q2 */
|
||||
{0x368E, 0x8334},
|
||||
/* P_RD_P2Q3 */
|
||||
{0x3690, 0x478E},
|
||||
/* P_RD_P2Q4 */
|
||||
{0x3692, 0x0515},
|
||||
/* P_RD_P3Q0 */
|
||||
{0x36CA, 0x0710},
|
||||
/* P_RD_P3Q1 */
|
||||
{0x36CC, 0x452D},
|
||||
/* P_RD_P3Q2 */
|
||||
{0x36CE, 0xF352},
|
||||
/* P_RD_P3Q3 */
|
||||
{0x36D0, 0x190F},
|
||||
/* P_RD_P3Q4 */
|
||||
{0x36D2, 0x4413},
|
||||
/* P_RD_P4Q0 */
|
||||
{0x370A, 0xD112},
|
||||
/* P_RD_P4Q1 */
|
||||
{0x370C, 0xF50F},
|
||||
/* P_RD_P4Q2 */
|
||||
{0x370E, 0x6375},
|
||||
/* P_RD_P4Q3 */
|
||||
{0x3710, 0xDC11},
|
||||
/* P_RD_P4Q4 */
|
||||
{0x3712, 0xD776},
|
||||
/* P_GR_P0Q0 */
|
||||
{0x3600, 0x1750},
|
||||
/* P_GR_P0Q1 */
|
||||
{0x3602, 0xF0AC},
|
||||
/* P_GR_P0Q2 */
|
||||
{0x3604, 0x4711},
|
||||
/* P_GR_P0Q3 */
|
||||
{0x3606, 0x07CE},
|
||||
/* P_GR_P0Q4 */
|
||||
{0x3608, 0x96B2},
|
||||
/* P_GR_P1Q0 */
|
||||
{0x3640, 0xA9AE},
|
||||
/* P_GR_P1Q1 */
|
||||
{0x3642, 0xF9AC},
|
||||
/* P_GR_P1Q2 */
|
||||
{0x3644, 0x39F1},
|
||||
/* P_GR_P1Q3 */
|
||||
{0x3646, 0x016F},
|
||||
/* P_GR_P1Q4 */
|
||||
{0x3648, 0x8AB2},
|
||||
/* P_GR_P2Q0 */
|
||||
{0x3680, 0x1752},
|
||||
/* P_GR_P2Q1 */
|
||||
{0x3682, 0x70F0},
|
||||
/* P_GR_P2Q2 */
|
||||
{0x3684, 0x83F5},
|
||||
/* P_GR_P2Q3 */
|
||||
{0x3686, 0x8392},
|
||||
/* P_GR_P2Q4 */
|
||||
{0x3688, 0x1FD6},
|
||||
/* P_GR_P3Q0 */
|
||||
{0x36C0, 0x1131},
|
||||
/* P_GR_P3Q1 */
|
||||
{0x36C2, 0x3DAF},
|
||||
/* P_GR_P3Q2 */
|
||||
{0x36C4, 0x89B4},
|
||||
/* P_GR_P3Q3 */
|
||||
{0x36C6, 0xA391},
|
||||
/* P_GR_P3Q4 */
|
||||
{0x36C8, 0x1334},
|
||||
/* P_GR_P4Q0 */
|
||||
{0x3700, 0xDC13},
|
||||
/* P_GR_P4Q1 */
|
||||
{0x3702, 0xD052},
|
||||
/* P_GR_P4Q2 */
|
||||
{0x3704, 0x5156},
|
||||
/* P_GR_P4Q3 */
|
||||
{0x3706, 0x1F13},
|
||||
/* P_GR_P4Q4 */
|
||||
{0x3708, 0x8C38},
|
||||
/* P_BL_P0Q0 */
|
||||
{0x3614, 0x0050},
|
||||
/* P_BL_P0Q1 */
|
||||
{0x3616, 0xBD4C},
|
||||
/* P_BL_P0Q2 */
|
||||
{0x3618, 0x41B0},
|
||||
/* P_BL_P0Q3 */
|
||||
{0x361A, 0x660D},
|
||||
/* P_BL_P0Q4 */
|
||||
{0x361C, 0xC590},
|
||||
/* P_BL_P1Q0 */
|
||||
{0x3654, 0x87EC},
|
||||
/* P_BL_P1Q1 */
|
||||
{0x3656, 0xE44C},
|
||||
/* P_BL_P1Q2 */
|
||||
{0x3658, 0x302E},
|
||||
/* P_BL_P1Q3 */
|
||||
{0x365A, 0x106E},
|
||||
/* P_BL_P1Q4 */
|
||||
{0x365C, 0xB58E},
|
||||
/* P_BL_P2Q0 */
|
||||
{0x3694, 0x0DD1},
|
||||
/* P_BL_P2Q1 */
|
||||
{0x3696, 0x2A50},
|
||||
/* P_BL_P2Q2 */
|
||||
{0x3698, 0xC793},
|
||||
/* P_BL_P2Q3 */
|
||||
{0x369A, 0xE8F1},
|
||||
/* P_BL_P2Q4 */
|
||||
{0x369C, 0x4174},
|
||||
/* P_BL_P3Q0 */
|
||||
{0x36D4, 0x01EF},
|
||||
/* P_BL_P3Q1 */
|
||||
{0x36D6, 0x06CF},
|
||||
/* P_BL_P3Q2 */
|
||||
{0x36D8, 0x8D91},
|
||||
/* P_BL_P3Q3 */
|
||||
{0x36DA, 0x91F0},
|
||||
/* P_BL_P3Q4 */
|
||||
{0x36DC, 0x52EF},
|
||||
/* P_BL_P4Q0 */
|
||||
{0x3714, 0xA6D2},
|
||||
/* P_BL_P4Q1 */
|
||||
{0x3716, 0xA312},
|
||||
/* P_BL_P4Q2 */
|
||||
{0x3718, 0x2695},
|
||||
/* P_BL_P4Q3 */
|
||||
{0x371A, 0x3953},
|
||||
/* P_BL_P4Q4 */
|
||||
{0x371C, 0x9356},
|
||||
/* P_GB_P0Q0 */
|
||||
{0x361E, 0x7EAF},
|
||||
/* P_GB_P0Q1 */
|
||||
{0x3620, 0x2A4C},
|
||||
/* P_GB_P0Q2 */
|
||||
{0x3622, 0x49F0},
|
||||
{0x3624, 0xF1EC},
|
||||
/* P_GB_P0Q4 */
|
||||
{0x3626, 0xC670},
|
||||
/* P_GB_P1Q0 */
|
||||
{0x365E, 0x8E0C},
|
||||
/* P_GB_P1Q1 */
|
||||
{0x3660, 0xC2A9},
|
||||
/* P_GB_P1Q2 */
|
||||
{0x3662, 0x274F},
|
||||
/* P_GB_P1Q3 */
|
||||
{0x3664, 0xADAB},
|
||||
/* P_GB_P1Q4 */
|
||||
{0x3666, 0x8EF0},
|
||||
/* P_GB_P2Q0 */
|
||||
{0x369E, 0x09B1},
|
||||
/* P_GB_P2Q1 */
|
||||
{0x36A0, 0xAA2E},
|
||||
/* P_GB_P2Q2 */
|
||||
{0x36A2, 0xC3D3},
|
||||
/* P_GB_P2Q3 */
|
||||
{0x36A4, 0x7FAF},
|
||||
/* P_GB_P2Q4 */
|
||||
{0x36A6, 0x3F34},
|
||||
/* P_GB_P3Q0 */
|
||||
{0x36DE, 0x4C8F},
|
||||
/* P_GB_P3Q1 */
|
||||
{0x36E0, 0x886E},
|
||||
/* P_GB_P3Q2 */
|
||||
{0x36E2, 0xE831},
|
||||
/* P_GB_P3Q3 */
|
||||
{0x36E4, 0x1FD0},
|
||||
/* P_GB_P3Q4 */
|
||||
{0x36E6, 0x1192},
|
||||
/* P_GB_P4Q0 */
|
||||
{0x371E, 0xB952},
|
||||
/* P_GB_P4Q1 */
|
||||
{0x3720, 0x6DCF},
|
||||
/* P_GB_P4Q2 */
|
||||
{0x3722, 0x1B55},
|
||||
/* P_GB_P4Q3 */
|
||||
{0x3724, 0xA112},
|
||||
/* P_GB_P4Q4 */
|
||||
{0x3726, 0x82F6},
|
||||
/* POLY_ORIGIN_C */
|
||||
{0x3782, 0x0510},
|
||||
/* POLY_ORIGIN_R */
|
||||
{0x3784, 0x0390},
|
||||
/* POLY_SC_ENABLE */
|
||||
{0x3780, 0x8000},
|
||||
};
|
||||
|
||||
|
||||
struct mt9p012_reg mt9p012_regs = {
|
||||
.reg_pat = &mt9p012_reg_pat[0],
|
||||
.reg_pat_size = ARRAY_SIZE(mt9p012_reg_pat),
|
||||
.ttbl = &mt9p012_test_tbl[0],
|
||||
.ttbl_size = ARRAY_SIZE(mt9p012_test_tbl),
|
||||
.lctbl = &mt9p012_lc_tbl[0],
|
||||
.lctbl_size = ARRAY_SIZE(mt9p012_lc_tbl),
|
||||
.rftbl = &mt9p012_rolloff_tbl[0],
|
||||
.rftbl_size = ARRAY_SIZE(mt9p012_rolloff_tbl)
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#ifndef MT9T013_H
|
||||
#define MT9T013_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct reg_struct {
|
||||
uint16_t vt_pix_clk_div; /* 0x0300 */
|
||||
uint16_t vt_sys_clk_div; /* 0x0302 */
|
||||
uint16_t pre_pll_clk_div; /* 0x0304 */
|
||||
uint16_t pll_multiplier; /* 0x0306 */
|
||||
uint16_t op_pix_clk_div; /* 0x0308 */
|
||||
uint16_t op_sys_clk_div; /* 0x030A */
|
||||
uint16_t scale_m; /* 0x0404 */
|
||||
uint16_t row_speed; /* 0x3016 */
|
||||
uint16_t x_addr_start; /* 0x3004 */
|
||||
uint16_t x_addr_end; /* 0x3008 */
|
||||
uint16_t y_addr_start; /* 0x3002 */
|
||||
uint16_t y_addr_end; /* 0x3006 */
|
||||
uint16_t read_mode; /* 0x3040 */
|
||||
uint16_t x_output_size; /* 0x034C */
|
||||
uint16_t y_output_size; /* 0x034E */
|
||||
uint16_t line_length_pck; /* 0x300C */
|
||||
uint16_t frame_length_lines; /* 0x300A */
|
||||
uint16_t coarse_int_time; /* 0x3012 */
|
||||
uint16_t fine_int_time; /* 0x3014 */
|
||||
};
|
||||
|
||||
struct mt9t013_i2c_reg_conf {
|
||||
unsigned short waddr;
|
||||
unsigned short wdata;
|
||||
};
|
||||
|
||||
struct mt9t013_reg {
|
||||
struct reg_struct *reg_pat;
|
||||
uint16_t reg_pat_size;
|
||||
struct mt9t013_i2c_reg_conf *ttbl;
|
||||
uint16_t ttbl_size;
|
||||
struct mt9t013_i2c_reg_conf *lctbl;
|
||||
uint16_t lctbl_size;
|
||||
struct mt9t013_i2c_reg_conf *rftbl;
|
||||
uint16_t rftbl_size;
|
||||
};
|
||||
|
||||
#endif /* #define MT9T013_H */
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (C) 2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#include "mt9t013.h"
|
||||
#include <linux/kernel.h>
|
||||
|
||||
struct reg_struct const mt9t013_reg_pat[2] = {
|
||||
{ /* Preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */
|
||||
/* vt_pix_clk_div:REG=0x0300 update get_snapshot_fps
|
||||
* if this change */
|
||||
8,
|
||||
|
||||
/* vt_sys_clk_div: REG=0x0302 update get_snapshot_fps
|
||||
* if this change */
|
||||
1,
|
||||
|
||||
/* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
|
||||
* if this change */
|
||||
2,
|
||||
|
||||
/* pll_multiplier REG=0x0306 60 for 30fps preview, 40
|
||||
* for 20fps preview
|
||||
* 46 for 30fps preview, try 47/48 to increase further */
|
||||
46,
|
||||
|
||||
/* op_pix_clk_div REG=0x0308 */
|
||||
8,
|
||||
|
||||
/* op_sys_clk_div REG=0x030A */
|
||||
1,
|
||||
|
||||
/* scale_m REG=0x0404 */
|
||||
16,
|
||||
|
||||
/* row_speed REG=0x3016 */
|
||||
0x0111,
|
||||
|
||||
/* x_addr_start REG=0x3004 */
|
||||
8,
|
||||
|
||||
/* x_addr_end REG=0x3008 */
|
||||
2053,
|
||||
|
||||
/* y_addr_start REG=0x3002 */
|
||||
8,
|
||||
|
||||
/* y_addr_end REG=0x3006 */
|
||||
1541,
|
||||
|
||||
/* read_mode REG=0x3040 */
|
||||
0x046C,
|
||||
|
||||
/* x_output_size REG=0x034C */
|
||||
1024,
|
||||
|
||||
/* y_output_size REG=0x034E */
|
||||
768,
|
||||
|
||||
/* line_length_pck REG=0x300C */
|
||||
2616,
|
||||
|
||||
/* frame_length_lines REG=0x300A */
|
||||
916,
|
||||
|
||||
/* coarse_int_time REG=0x3012 */
|
||||
16,
|
||||
|
||||
/* fine_int_time REG=0x3014 */
|
||||
1461
|
||||
},
|
||||
{ /*Snapshot */
|
||||
/* vt_pix_clk_div REG=0x0300 update get_snapshot_fps
|
||||
* if this change */
|
||||
8,
|
||||
|
||||
/* vt_sys_clk_div REG=0x0302 update get_snapshot_fps
|
||||
* if this change */
|
||||
1,
|
||||
|
||||
/* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
|
||||
* if this change */
|
||||
2,
|
||||
|
||||
/* pll_multiplier REG=0x0306 50 for 15fps snapshot,
|
||||
* 40 for 10fps snapshot
|
||||
* 46 for 30fps snapshot, try 47/48 to increase further */
|
||||
46,
|
||||
|
||||
/* op_pix_clk_div REG=0x0308 */
|
||||
8,
|
||||
|
||||
/* op_sys_clk_div REG=0x030A */
|
||||
1,
|
||||
|
||||
/* scale_m REG=0x0404 */
|
||||
16,
|
||||
|
||||
/* row_speed REG=0x3016 */
|
||||
0x0111,
|
||||
|
||||
/* x_addr_start REG=0x3004 */
|
||||
8,
|
||||
|
||||
/* x_addr_end REG=0x3008 */
|
||||
2071,
|
||||
|
||||
/* y_addr_start REG=0x3002 */
|
||||
8,
|
||||
|
||||
/* y_addr_end REG=0x3006 */
|
||||
1551,
|
||||
|
||||
/* read_mode REG=0x3040 */
|
||||
0x0024,
|
||||
|
||||
/* x_output_size REG=0x034C */
|
||||
2064,
|
||||
|
||||
/* y_output_size REG=0x034E */
|
||||
1544,
|
||||
|
||||
/* line_length_pck REG=0x300C */
|
||||
2952,
|
||||
|
||||
/* frame_length_lines REG=0x300A */
|
||||
1629,
|
||||
|
||||
/* coarse_int_time REG=0x3012 */
|
||||
16,
|
||||
|
||||
/* fine_int_time REG=0x3014 */
|
||||
733
|
||||
}
|
||||
};
|
||||
|
||||
struct mt9t013_i2c_reg_conf mt9t013_test_tbl[] = {
|
||||
{ 0x3044, 0x0544 & 0xFBFF },
|
||||
{ 0x30CA, 0x0004 | 0x0001 },
|
||||
{ 0x30D4, 0x9020 & 0x7FFF },
|
||||
{ 0x31E0, 0x0003 & 0xFFFE },
|
||||
{ 0x3180, 0x91FF & 0x7FFF },
|
||||
{ 0x301A, (0x10CC | 0x8000) & 0xFFF7 },
|
||||
{ 0x301E, 0x0000 },
|
||||
{ 0x3780, 0x0000 },
|
||||
};
|
||||
|
||||
/* [Lens shading 85 Percent TL84] */
|
||||
struct mt9t013_i2c_reg_conf mt9t013_lc_tbl[] = {
|
||||
{ 0x360A, 0x0290 }, /* P_RD_P0Q0 */
|
||||
{ 0x360C, 0xC92D }, /* P_RD_P0Q1 */
|
||||
{ 0x360E, 0x0771 }, /* P_RD_P0Q2 */
|
||||
{ 0x3610, 0xE38C }, /* P_RD_P0Q3 */
|
||||
{ 0x3612, 0xD74F }, /* P_RD_P0Q4 */
|
||||
{ 0x364A, 0x168C }, /* P_RD_P1Q0 */
|
||||
{ 0x364C, 0xCACB }, /* P_RD_P1Q1 */
|
||||
{ 0x364E, 0x8C4C }, /* P_RD_P1Q2 */
|
||||
{ 0x3650, 0x0BEA }, /* P_RD_P1Q3 */
|
||||
{ 0x3652, 0xDC0F }, /* P_RD_P1Q4 */
|
||||
{ 0x368A, 0x70B0 }, /* P_RD_P2Q0 */
|
||||
{ 0x368C, 0x200B }, /* P_RD_P2Q1 */
|
||||
{ 0x368E, 0x30B2 }, /* P_RD_P2Q2 */
|
||||
{ 0x3690, 0xD04F }, /* P_RD_P2Q3 */
|
||||
{ 0x3692, 0xACF5 }, /* P_RD_P2Q4 */
|
||||
{ 0x36CA, 0xF7C9 }, /* P_RD_P3Q0 */
|
||||
{ 0x36CC, 0x2AED }, /* P_RD_P3Q1 */
|
||||
{ 0x36CE, 0xA652 }, /* P_RD_P3Q2 */
|
||||
{ 0x36D0, 0x8192 }, /* P_RD_P3Q3 */
|
||||
{ 0x36D2, 0x3A15 }, /* P_RD_P3Q4 */
|
||||
{ 0x370A, 0xDA30 }, /* P_RD_P4Q0 */
|
||||
{ 0x370C, 0x2E2F }, /* P_RD_P4Q1 */
|
||||
{ 0x370E, 0xBB56 }, /* P_RD_P4Q2 */
|
||||
{ 0x3710, 0x8195 }, /* P_RD_P4Q3 */
|
||||
{ 0x3712, 0x02F9 }, /* P_RD_P4Q4 */
|
||||
{ 0x3600, 0x0230 }, /* P_GR_P0Q0 */
|
||||
{ 0x3602, 0x58AD }, /* P_GR_P0Q1 */
|
||||
{ 0x3604, 0x18D1 }, /* P_GR_P0Q2 */
|
||||
{ 0x3606, 0x260D }, /* P_GR_P0Q3 */
|
||||
{ 0x3608, 0xF530 }, /* P_GR_P0Q4 */
|
||||
{ 0x3640, 0x17EB }, /* P_GR_P1Q0 */
|
||||
{ 0x3642, 0x3CAB }, /* P_GR_P1Q1 */
|
||||
{ 0x3644, 0x87CE }, /* P_GR_P1Q2 */
|
||||
{ 0x3646, 0xC02E }, /* P_GR_P1Q3 */
|
||||
{ 0x3648, 0xF48F }, /* P_GR_P1Q4 */
|
||||
{ 0x3680, 0x5350 }, /* P_GR_P2Q0 */
|
||||
{ 0x3682, 0x7EAF }, /* P_GR_P2Q1 */
|
||||
{ 0x3684, 0x4312 }, /* P_GR_P2Q2 */
|
||||
{ 0x3686, 0xC652 }, /* P_GR_P2Q3 */
|
||||
{ 0x3688, 0xBC15 }, /* P_GR_P2Q4 */
|
||||
{ 0x36C0, 0xB8AD }, /* P_GR_P3Q0 */
|
||||
{ 0x36C2, 0xBDCD }, /* P_GR_P3Q1 */
|
||||
{ 0x36C4, 0xE4B2 }, /* P_GR_P3Q2 */
|
||||
{ 0x36C6, 0xB50F }, /* P_GR_P3Q3 */
|
||||
{ 0x36C8, 0x5B95 }, /* P_GR_P3Q4 */
|
||||
{ 0x3700, 0xFC90 }, /* P_GR_P4Q0 */
|
||||
{ 0x3702, 0x8C51 }, /* P_GR_P4Q1 */
|
||||
{ 0x3704, 0xCED6 }, /* P_GR_P4Q2 */
|
||||
{ 0x3706, 0xB594 }, /* P_GR_P4Q3 */
|
||||
{ 0x3708, 0x0A39 }, /* P_GR_P4Q4 */
|
||||
{ 0x3614, 0x0230 }, /* P_BL_P0Q0 */
|
||||
{ 0x3616, 0x160D }, /* P_BL_P0Q1 */
|
||||
{ 0x3618, 0x08D1 }, /* P_BL_P0Q2 */
|
||||
{ 0x361A, 0x98AB }, /* P_BL_P0Q3 */
|
||||
{ 0x361C, 0xEA50 }, /* P_BL_P0Q4 */
|
||||
{ 0x3654, 0xB4EA }, /* P_BL_P1Q0 */
|
||||
{ 0x3656, 0xEA6C }, /* P_BL_P1Q1 */
|
||||
{ 0x3658, 0xFE08 }, /* P_BL_P1Q2 */
|
||||
{ 0x365A, 0x2C6E }, /* P_BL_P1Q3 */
|
||||
{ 0x365C, 0xEB0E }, /* P_BL_P1Q4 */
|
||||
{ 0x3694, 0x6DF0 }, /* P_BL_P2Q0 */
|
||||
{ 0x3696, 0x3ACF }, /* P_BL_P2Q1 */
|
||||
{ 0x3698, 0x3E0F }, /* P_BL_P2Q2 */
|
||||
{ 0x369A, 0xB2B1 }, /* P_BL_P2Q3 */
|
||||
{ 0x369C, 0xC374 }, /* P_BL_P2Q4 */
|
||||
{ 0x36D4, 0xF2AA }, /* P_BL_P3Q0 */
|
||||
{ 0x36D6, 0x8CCC }, /* P_BL_P3Q1 */
|
||||
{ 0x36D8, 0xDEF2 }, /* P_BL_P3Q2 */
|
||||
{ 0x36DA, 0xFA11 }, /* P_BL_P3Q3 */
|
||||
{ 0x36DC, 0x42F5 }, /* P_BL_P3Q4 */
|
||||
{ 0x3714, 0xF4F1 }, /* P_BL_P4Q0 */
|
||||
{ 0x3716, 0xF6F0 }, /* P_BL_P4Q1 */
|
||||
{ 0x3718, 0x8FD6 }, /* P_BL_P4Q2 */
|
||||
{ 0x371A, 0xEA14 }, /* P_BL_P4Q3 */
|
||||
{ 0x371C, 0x6338 }, /* P_BL_P4Q4 */
|
||||
{ 0x361E, 0x0350 }, /* P_GB_P0Q0 */
|
||||
{ 0x3620, 0x91AE }, /* P_GB_P0Q1 */
|
||||
{ 0x3622, 0x0571 }, /* P_GB_P0Q2 */
|
||||
{ 0x3624, 0x100D }, /* P_GB_P0Q3 */
|
||||
{ 0x3626, 0xCA70 }, /* P_GB_P0Q4 */
|
||||
{ 0x365E, 0xE6CB }, /* P_GB_P1Q0 */
|
||||
{ 0x3660, 0x50ED }, /* P_GB_P1Q1 */
|
||||
{ 0x3662, 0x3DAE }, /* P_GB_P1Q2 */
|
||||
{ 0x3664, 0xAA4F }, /* P_GB_P1Q3 */
|
||||
{ 0x3666, 0xDC50 }, /* P_GB_P1Q4 */
|
||||
{ 0x369E, 0x5470 }, /* P_GB_P2Q0 */
|
||||
{ 0x36A0, 0x1F6E }, /* P_GB_P2Q1 */
|
||||
{ 0x36A2, 0x6671 }, /* P_GB_P2Q2 */
|
||||
{ 0x36A4, 0xC010 }, /* P_GB_P2Q3 */
|
||||
{ 0x36A6, 0x8DF5 }, /* P_GB_P2Q4 */
|
||||
{ 0x36DE, 0x0B0C }, /* P_GB_P3Q0 */
|
||||
{ 0x36E0, 0x84CE }, /* P_GB_P3Q1 */
|
||||
{ 0x36E2, 0x8493 }, /* P_GB_P3Q2 */
|
||||
{ 0x36E4, 0xA610 }, /* P_GB_P3Q3 */
|
||||
{ 0x36E6, 0x50B5 }, /* P_GB_P3Q4 */
|
||||
{ 0x371E, 0x9651 }, /* P_GB_P4Q0 */
|
||||
{ 0x3720, 0x1EAB }, /* P_GB_P4Q1 */
|
||||
{ 0x3722, 0xAF76 }, /* P_GB_P4Q2 */
|
||||
{ 0x3724, 0xE4F4 }, /* P_GB_P4Q3 */
|
||||
{ 0x3726, 0x79F8 }, /* P_GB_P4Q4 */
|
||||
{ 0x3782, 0x0410 }, /* POLY_ORIGIN_C */
|
||||
{ 0x3784, 0x0320 }, /* POLY_ORIGIN_R */
|
||||
{ 0x3780, 0x8000 } /* POLY_SC_ENABLE */
|
||||
};
|
||||
|
||||
struct mt9t013_reg mt9t013_regs = {
|
||||
.reg_pat = &mt9t013_reg_pat[0],
|
||||
.reg_pat_size = ARRAY_SIZE(mt9t013_reg_pat),
|
||||
.ttbl = &mt9t013_test_tbl[0],
|
||||
.ttbl_size = ARRAY_SIZE(mt9t013_test_tbl),
|
||||
.lctbl = &mt9t013_lc_tbl[0],
|
||||
.lctbl_size = ARRAY_SIZE(mt9t013_lc_tbl),
|
||||
.rftbl = &mt9t013_lc_tbl[0], /* &mt9t013_rolloff_tbl[0], */
|
||||
.rftbl_size = ARRAY_SIZE(mt9t013_lc_tbl)
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
|
||||
*/
|
||||
|
||||
#ifndef CAMSENSOR_S5K3E2FX
|
||||
#define CAMSENSOR_S5K3E2FX
|
||||
|
||||
#include <mach/board.h>
|
||||
#endif /* CAMSENSOR_S5K3E2FX */
|
Loading…
Reference in New Issue