提交 3414df8c 编写于 作者: G Greg Kroah-Hartman

Staging: dream: remove dream driver and arch from tree

This code is stalled, with no one working on it anymore, and the main
msm code is now going through the proper channels to get merged
correctly.

So remove it as it contains a number of kernel information leaks and it
is doubtful if it even still builds anymore.
Acked-by: NPavel Machek <pavel@ucw.cz>
Acked-by: NBryan Huntsman <bryanh@codeaurora.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 1e431a9d
......@@ -87,8 +87,6 @@ source "drivers/staging/rtl8712/Kconfig"
source "drivers/staging/frontier/Kconfig"
source "drivers/staging/dream/Kconfig"
source "drivers/staging/pohmelfs/Kconfig"
source "drivers/staging/autofs/Kconfig"
......
......@@ -28,7 +28,6 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_SPECTRA) += spectra/
obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_DREAM) += dream/
obj-$(CONFIG_POHMELFS) += pohmelfs/
obj-$(CONFIG_AUTOFS_FS) += autofs/
obj-$(CONFIG_IDE_PHISON) += phison/
......
config DREAM
tristate "HTC Dream support"
depends on MACH_TROUT
if DREAM
source "drivers/staging/dream/camera/Kconfig"
config INPUT_GPIO
tristate "GPIO driver support"
help
Say Y here if you want to support gpio based keys, wheels etc...
endif
ccflags-y:=-Idrivers/staging/dream/include
obj-$(CONFIG_MSM_ADSP) += qdsp5/
obj-$(CONFIG_MSM_CAMERA) += camera/
obj-$(CONFIG_INPUT_GPIO) += gpio_axis.o gpio_event.o gpio_input.o gpio_matrix.o gpio_output.o
* camera driver uses old V4L API
* coding style in some places is lacking
* gpio_input.c has some features matrix_keypad lacks. They should be
merged to gpio_input, with gpio_input.c removed
* pmem provides interface for userspace. Needs to be reviewed at least.
* it is probably possible to simplify touchscreen driver using threaded_irq's.
* touchscreen driver should be switched to oficial multitouch API
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 && BROKEN
---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
ccflags-y:=-Idrivers/staging/dream/include
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
此差异已折叠。
/*
* 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);
}
/*
* 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);
}
/*
*
* 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 <linux/slab.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) {
kfree(ctrlcmd);
return -1;
}
#if 0
/* FIXEME */
if (pfmt->fmt.pix.pixelformat != V4L2_PIX_FMT_YVU420) {
kfree(ctrlcmd);
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");
/*
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
*/
#include <linux/msm_adsp.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/android_pmem.h>
#include <linux/slab.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(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;
}
/*
* 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__ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* 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 */
/*
* 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)
};
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* Copyright (C) 2008-2009 QUALCOMM Incorporated.
*/
#ifndef CAMSENSOR_S5K3E2FX
#define CAMSENSOR_S5K3E2FX
#include <mach/board.h>
#endif /* CAMSENSOR_S5K3E2FX */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册