@@ -0,0 +1,3 @@ | |||
if EXTERNAL_CAMERA | |||
source drivers/external_drivers/camera/drivers/Kconfig | |||
endif |
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_EXTERNAL_CAMERA) += drivers/ |
@@ -0,0 +1 @@ | |||
source drivers/external_drivers/camera/drivers/media/Kconfig |
@@ -0,0 +1 @@ | |||
obj-y += media/ |
@@ -0,0 +1,5 @@ | |||
# | |||
# Kconfig for Camera drivers | |||
# | |||
source drivers/external_drivers/camera/drivers/media/pci/Kconfig | |||
source drivers/external_drivers/camera/drivers/media/i2c/Kconfig |
@@ -0,0 +1,6 @@ | |||
# | |||
# Makefile for camera drivers. | |||
# | |||
obj-y += pci/ | |||
obj-y += i2c/ |
@@ -0,0 +1,262 @@ | |||
# | |||
# Kconfig for sensor drivers | |||
# | |||
source "drivers/external_drivers/camera/drivers/media/i2c/mt9e013/Kconfig" | |||
source "drivers/external_drivers/camera/drivers/media/i2c/ov5693/Kconfig" | |||
source "drivers/external_drivers/camera/drivers/media/i2c/imx/Kconfig" | |||
source "drivers/external_drivers/camera/drivers/media/i2c/imx135VB/Kconfig" | |||
config VIDEO_OV8865 | |||
tristate "OVT ov8865 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the OVT | |||
OV8865 raw camera. | |||
OVT is a 8MP raw sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_OV9760 | |||
tristate "OVT ov9760 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the OVT | |||
OV9760 raw camera. | |||
OVT is a 8MP raw sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_OV9724 | |||
tristate "OVT ov9724 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the OVT | |||
OV9724 raw camera. | |||
OVT is a 720P raw sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_OV2722 | |||
tristate "OVT ov2722 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the OVT | |||
OV2722 raw camera. | |||
OVT is a 2M raw sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_M10MO | |||
tristate "Fujitsu M10MO driver" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 isp driver for the Fujitsu. | |||
It currently depends on internal V4L2 extensions defined in | |||
atomisp driver. | |||
config VIDEO_M10MO_FAKE_SFI_TABLE | |||
bool "Add fake SFI entry for Fujitsu M10MO on VV board + AOB" | |||
depends on VIDEO_M10MO | |||
---help--- | |||
Enable this when working with VV board with Fujitsu AOB. | |||
Not needed if device IFWI already has M10MO in the SFI table. | |||
config VIDEO_GC2235 | |||
tristate "Galaxy gc2235 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the OVT | |||
GC2235 raw camera. | |||
GC2235 is a 2M raw sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_OV8830 | |||
tristate "Omnivision ov8830 sensor support" | |||
depends on I2C && VIDEO_V4L2 && VIDEO_ATOMISP | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Omnivision | |||
ov8830 8MP RAW sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_OV8858 | |||
tristate "Omnivision ov8858 sensor support" | |||
depends on I2C && VIDEO_V4L2 && VIDEO_ATOMISP | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Omnivision | |||
ov8858 8MP RAW sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_CSI_XACTOR | |||
tristate "csi xactor" | |||
depends on I2C && VIDEO_V4L2 && VIDEO_ATOMISP | |||
---help--- | |||
Use this if you need to send data through external csi data generator | |||
To compile this driver as a module, choose M here. | |||
config VIDEO_MSRLIST_HELPER | |||
tristate "Helper library to load, parse and apply large register lists." | |||
depends on I2C | |||
---help--- | |||
This is a helper library to be used from a sensor driver to load, parse | |||
and apply large register lists. | |||
To compile this driver as a module, choose M here: the | |||
module will be called libmsrlisthelper. | |||
config VIDEO_S5K8AAY | |||
tristate "Samsung S5K8AAY (EVT1) sensor support" | |||
depends on I2C && VIDEO_V4L2 && VIDEO_ATOMISP && VIDEO_MSRLIST_HELPER | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Samsung | |||
S5K8AAY (EVT1) 1/8" 1.2MP SoC sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_S5K6B2YX | |||
tristate "Samsung S5K6B2YX (VS) sensor support" | |||
depends on I2C && VIDEO_V4L2 && VIDEO_ATOMISP && VIDEO_MSRLIST_HELPER | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Samsung | |||
S5K6B2YX (VS) 1/6" 2MP RAW sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_MT9D113 | |||
tristate "Aptina mt9d113 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Micron | |||
mt9d113 2M camera. | |||
mt9d113 is video camera sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_MT9M114 | |||
tristate "Aptina mt9m114 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Micron | |||
mt9m114 1.3 Mpixel camera. | |||
mt9m114 is video camrea sensor. | |||
config VIDEO_MT9V113 | |||
tristate "Aptina mt9v113 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Micron | |||
mt9v113 vga camera. | |||
mt9v113 is video camerea sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_OV5640 | |||
tristate "Omnivision ov5640 sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Micron | |||
ov5640 5 Mpixel camera. | |||
ov5640 is video camrea sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_AR0543_RAW | |||
tristate "Aptina ar5693_raw with raw sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Aptina | |||
ar0543 5 Mpixel camera. | |||
ar0543 is video camrea sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_HM2056_RAW | |||
tristate "Himax hm2056_raw with raw sensor support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Himax | |||
hm2056_raw 2 Mpixel camera. | |||
hm2056_raw is video camrea sensor. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_AP1302 | |||
tristate "AP1302 external ISP support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the external | |||
ISP AP1302. | |||
AP1302 is an exteral ISP. | |||
It currently only works with the atomisp driver. | |||
config VIDEO_PIXTER | |||
tristate "Pixter 2+ MIPI CSI simulator" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for Pixter2+. | |||
Pixter 2+ is a MIPI CSI simulator. | |||
config VIDEO_OV680 | |||
tristate "OV680 external ISP support" | |||
depends on I2C && VIDEO_V4L2 | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the external | |||
ISP OV680. | |||
OV680 is an external ISP. | |||
It currently only works with the atomisp driver. | |||
# | |||
# Kconfig for flash drivers | |||
# | |||
config VIDEO_LM3554 | |||
tristate "LM3554 flash light driver" | |||
depends on VIDEO_V4L2 && I2C | |||
---help--- | |||
This is a Video4Linux2 sub-dev driver for the LM3554 | |||
flash light driver. | |||
To compile this driver as a module, choose M here: the | |||
module will be called lm3554 | |||
config VIDEO_LM3642 | |||
tristate "LM3642 flash light driver" | |||
depends on VIDEO_V4L2 && I2C | |||
---help--- | |||
This is a Video4Linux2 sub-dev driver for the LM3642 | |||
flash light driver. | |||
To compile this driver as a module, choose M here: the | |||
module will be called lm3642 | |||
config VIDEO_LM3559 | |||
tristate "LM3559 flash light driver" | |||
depends on VIDEO_V4L2 && I2C | |||
---help--- | |||
This is a Video4Linux2 sub-dev driver for the LM3559 | |||
flash light driver. | |||
To compile this driver as a module, choose M here: the | |||
module will be called lm3559 | |||
@@ -0,0 +1,59 @@ | |||
# | |||
# Makefile for sensor drivers | |||
# | |||
obj-$(CONFIG_VIDEO_IMX) += imx/ | |||
obj-$(CONFIG_VIDEO_IMXVB) += imx135VB/ | |||
ifdef CONFIG_GMIN_INTEL_MID | |||
obj-$(CONFIG_VIDEO_OV5693) += ov5693-ecs/ | |||
else | |||
obj-$(CONFIG_VIDEO_OV5693) += ov5693/ | |||
endif | |||
obj-$(CONFIG_VIDEO_MT9M114) += mt9m114.o | |||
obj-$(CONFIG_VIDEO_MT9E013) += mt9e013/ | |||
obj-$(CONFIG_VIDEO_MT9D113) += mt9d113.o | |||
obj-$(CONFIG_VIDEO_MT9V113) += mt9v113.o | |||
obj-$(CONFIG_VIDEO_OV5640) += ov5640.o | |||
obj-$(CONFIG_VIDEO_GC2235) += gc2235.o | |||
obj-$(CONFIG_VIDEO_OV9724) += ov9724.o | |||
obj-$(CONFIG_VIDEO_OV2722) += ov2722.o | |||
obj-$(CONFIG_VIDEO_OV8830) += ov8830.o | |||
obj-$(CONFIG_VIDEO_OV9760) += ov9760.o | |||
obj-$(CONFIG_VIDEO_OV8865) += ov8865.o | |||
obj-$(CONFIG_VIDEO_S5K8AAY) += s5k8aay.o | |||
obj-$(CONFIG_VIDEO_S5K6B2YX) += s5k6b2yx.o | |||
m10mo_isp-objs := m10mo.o m10mo_fw.o m10mo_tables.o m10mo_fw_type2.o m10mo_fw_type1_5.o | |||
obj-$(CONFIG_VIDEO_M10MO) += m10mo_isp.o | |||
obj-$(CONFIG_VIDEO_M10MO) += m10mo_spi.o | |||
obj-$(CONFIG_VIDEO_AR0543_RAW) += ar0543_raw.o | |||
CFFLAGS_ar0543_raw.o = -Werror | |||
obj-$(CONFIG_VIDEO_HM2056_RAW) += hm2056_raw.o | |||
CFFLAGS_hm2056_raw.o = -Werror | |||
obj-$(CONFIG_VIDEO_MSRLIST_HELPER) += libmsrlisthelper.o | |||
obj-$(CONFIG_VIDEO_AP1302) += ap1302.o | |||
obj-$(CONFIG_VIDEO_OV680) += ov680.o | |||
obj-$(CONFIG_VIDEO_CSI_XACTOR) += xactor_x.o | |||
obj-$(CONFIG_VIDEO_PIXTER) += pixter.o | |||
# | |||
# Makefile for flash drivers | |||
# | |||
obj-$(CONFIG_VIDEO_LM3554) += lm3554.o | |||
obj-$(CONFIG_VIDEO_LM3559) += lm3559.o | |||
obj-$(CONFIG_VIDEO_LM3642) += lm3642.o | |||
ccflags-y += -Werror | |||
# Add cflags to build camera sensor driver for CTP board | |||
ccflags-$(CONFIG_VIDEO_ATOMISP_CTP) += -DCSS15 |
@@ -0,0 +1,198 @@ | |||
/* | |||
* | |||
* Copyright (c) 2013 Intel Corporation. All Rights Reserved. | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License version | |||
* 2 as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |||
* 02110-1301, USA. | |||
* | |||
*/ | |||
#ifndef __AP1302_H__ | |||
#define __AP1302_H__ | |||
#include <linux/atomisp_platform.h> | |||
#include <linux/regmap.h> | |||
#include <linux/types.h> | |||
#include <media/v4l2-ctrls.h> | |||
#include <media/v4l2-subdev.h> | |||
#define AP1302_NAME "ap1302" | |||
#define AP1302_CHIP_ID 0x265 | |||
#define AP1302_I2C_MAX_LEN 65534 | |||
#define AP1302_FW_WINDOW_OFFSET 0x8000 | |||
#define AP1302_FW_WINDOW_SIZE 0x2000 | |||
#define AP1302_REG16 2 | |||
#define AP1302_REG32 4 | |||
#define REG_CHIP_VERSION 0x0000 | |||
#define REG_CHIP_REV 0x0050 | |||
#define REG_MF_ID 0x0004 | |||
#define REG_ERROR 0x0006 | |||
#define REG_CTRL 0x1000 | |||
#define REG_DZ_TGT_FCT 0x1010 | |||
#define REG_SFX_MODE 0x1016 | |||
#define REG_SS_HEAD_PT0 0x1174 | |||
#define REG_AE_BV_OFF 0x5014 | |||
#define REG_AE_BV_BIAS 0x5016 | |||
#define REG_AWB_CTRL 0x5100 | |||
#define REG_FLICK_CTRL 0x5440 | |||
#define REG_SCENE_CTRL 0x5454 | |||
#define REG_BOOTDATA_STAGE 0x6002 | |||
#define REG_SENSOR_SELECT 0x600C | |||
#define REG_SYS_START 0x601A | |||
#define REG_SIP_CRC 0xF052 | |||
#define REG_PREVIEW_BASE 0x2000 | |||
#define REG_SNAPSHOT_BASE 0x3000 | |||
#define REG_VIDEO_BASE 0x4000 | |||
#define CNTX_WIDTH 0x00 | |||
#define CNTX_HEIGHT 0x02 | |||
#define CNTX_ROI_X0 0x04 | |||
#define CNTX_ROI_Y0 0x06 | |||
#define CNTX_ROI_X1 0x08 | |||
#define CNTX_ROI_Y1 0x0A | |||
#define CNTX_ASPECT 0x0C | |||
#define CNTX_LOCK 0x0E | |||
#define CNTX_ENABLE 0x10 | |||
#define CNTX_OUT_FMT 0x12 | |||
#define CNTX_SENSOR_MODE 0x14 | |||
#define CNTX_MIPI_CTRL 0x16 | |||
#define CNTX_MIPI_II_CTRL 0x18 | |||
#define CNTX_LINE_TIME 0x1C | |||
#define CNTX_MAX_FPS 0x20 | |||
#define CNTX_AE_USG 0x22 | |||
#define CNTX_AE_UPPER_ET 0x24 | |||
#define CNTX_AE_MAX_ET 0x28 | |||
#define CNTX_SS 0x2C | |||
#define CNTX_S1_SENSOR_MODE 0x2E | |||
#define CNTX_HINF_CTRL 0x30 | |||
#define CTRL_CNTX_MASK 0x03 | |||
#define CTRL_CNTX_OFFSET 0x00 | |||
#define HINF_CTRL_LANE_MASK 0x07 | |||
#define HINF_CTRL_LANE_OFFSET 0x00 | |||
#define MIPI_CTRL_IMGVC_MASK 0xC0 | |||
#define MIPI_CTRL_IMGVC_OFFSET 0x06 | |||
#define MIPI_CTRL_IMGTYPE_AUTO 0x3F | |||
#define MIPI_CTRL_SSVC_MASK 0xC000 | |||
#define MIPI_CTRL_SSVC_OFFSET 0x0E | |||
#define MIPI_CTRL_SSTYPE_MASK 0x3F00 | |||
#define MIPI_CTRL_SSTYPE_OFFSET 0x08 | |||
#define OUT_FMT_IIS_MASK 0x30 | |||
#define OUT_FMT_IIS_OFFSET 0x08 | |||
#define OUT_FMT_SS_MASK 0x1000 | |||
#define OUT_FMT_SS_OFFSET 0x12 | |||
#define OUT_FMT_TYPE_MASK 0xFF | |||
#define SENSOR_SELECT_MASK 0x03 | |||
#define SENSOR_SELECT_OFFSET 0x00 | |||
#define AWB_CTRL_MODE_MASK 0x0F | |||
#define AWB_CTRL_MODE_OFFSET 0x00 | |||
#define AWB_CTRL_FLASH_MASK 0x100 | |||
#define AP1302_FMT_UYVY422 0x50 | |||
#define AP1302_SYS_ACTIVATE 0x8010 | |||
#define AP1302_SYS_SWITCH 0x8140 | |||
#define AP1302_SENSOR_PRI 0x01 | |||
#define AP1302_SENSOR_SEC 0x02 | |||
#define AP1302_SS_CTRL 0x31 | |||
#define AP1302_MAX_RATIO_MISMATCH 10 /* Unit in percentage */ | |||
#define AP1302_MAX_EV 2 | |||
#define AP1302_MIN_EV -2 | |||
enum ap1302_contexts { | |||
CONTEXT_PREVIEW = 0, | |||
CONTEXT_SNAPSHOT, | |||
CONTEXT_VIDEO, | |||
CONTEXT_NUM | |||
}; | |||
/* The context registers are defined according to preview/video registers. | |||
Preview and video context have the same register definition. | |||
But snapshot context does not have register S1_SENSOR_MODE. | |||
When setting snapshot registers, if the offset exceeds | |||
S1_SENSOR_MODE, the actual offset needs to minus 2. */ | |||
struct ap1302_context_config { | |||
u16 width; | |||
u16 height; | |||
u16 roi_x0; | |||
u16 roi_y0; | |||
u16 roi_x1; | |||
u16 roi_y1; | |||
u16 aspect_factor; | |||
u16 lock; | |||
u16 enable; | |||
u16 out_fmt; | |||
u16 sensor_mode; | |||
u16 mipi_ctrl; | |||
u16 mipi_ii_ctrl; | |||
u16 padding; | |||
u32 line_time; | |||
u16 max_fps; | |||
u16 ae_usg; | |||
u32 ae_upper_et; | |||
u32 ae_max_et; | |||
u16 ss; | |||
u16 s1_sensor_mode; | |||
u16 hinf_ctrl; | |||
u32 reserved; | |||
}; | |||
struct ap1302_res_struct { | |||
u16 width; | |||
u16 height; | |||
u16 fps; | |||
}; | |||
struct ap1302_context_res { | |||
s32 res_num; | |||
s32 cur_res; | |||
struct ap1302_res_struct *res_table; | |||
}; | |||
struct ap1302_device { | |||
struct v4l2_subdev sd; | |||
struct media_pad pad; | |||
struct camera_sensor_platform_data *platform_data; | |||
const struct firmware *fw; | |||
struct mutex input_lock; /* serialize sensor's ioctl */ | |||
struct v4l2_mbus_framefmt format; | |||
struct v4l2_ctrl_handler ctrl_handler; | |||
struct v4l2_ctrl *run_mode; | |||
struct ap1302_context_config cntx_config[CONTEXT_NUM]; | |||
struct ap1302_context_res cntx_res[CONTEXT_NUM]; | |||
enum ap1302_contexts cur_context; | |||
unsigned int num_lanes; | |||
struct regmap *regmap16; | |||
struct regmap *regmap32; | |||
bool sys_activated; | |||
bool power_on; | |||
}; | |||
struct ap1302_firmware { | |||
u32 crc; | |||
u32 pll_init_size; | |||
u32 total_size; | |||
u32 reserved; | |||
}; | |||
struct ap1302_context_info { | |||
u16 offset; | |||
u16 len; | |||
char *name; | |||
}; | |||
#endif |
@@ -0,0 +1,558 @@ | |||
/* | |||
* Support for GalaxyCore GC2235 2M camera sensor. | |||
* | |||
* Copyright (c) 2014 Intel Corporation. All Rights Reserved. | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License version | |||
* 2 as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |||
* 02110-1301, USA. | |||
* | |||
*/ | |||
#ifndef __GC2235_H__ | |||
#define __GC2235_H__ | |||
#include <linux/kernel.h> | |||
#include <linux/types.h> | |||
#include <linux/i2c.h> | |||
#include <linux/delay.h> | |||
#include <linux/videodev2.h> | |||
#include <linux/spinlock.h> | |||
#include <media/v4l2-subdev.h> | |||
#include <media/v4l2-device.h> | |||
#ifndef CONFIG_GMIN_INTEL_MID /* FIXME! for non-gmin*/ | |||
#include <media/v4l2-chip-ident.h> | |||
#endif | |||
#include <linux/v4l2-mediabus.h> | |||
#include <media/media-entity.h> | |||
#include <linux/atomisp_platform.h> | |||
#define GC2235_NAME "gc2235" | |||
/* Defines for register writes and register array processing */ | |||
#define I2C_MSG_LENGTH 0x2 | |||
#define I2C_RETRY_COUNT 5 | |||
#define GC2235_FOCAL_LENGTH_NUM 278 /*2.78mm*/ | |||
#define GC2235_FOCAL_LENGTH_DEM 100 | |||
#define GC2235_F_NUMBER_DEFAULT_NUM 26 | |||
#define GC2235_F_NUMBER_DEM 10 | |||
#define MAX_FMTS 1 | |||
/* | |||
* focal length bits definition: | |||
* bits 31-16: numerator, bits 15-0: denominator | |||
*/ | |||
#define GC2235_FOCAL_LENGTH_DEFAULT 0x1160064 | |||
/* | |||
* current f-number bits definition: | |||
* bits 31-16: numerator, bits 15-0: denominator | |||
*/ | |||
#define GC2235_F_NUMBER_DEFAULT 0x1a000a | |||
/* | |||
* f-number range bits definition: | |||
* bits 31-24: max f-number numerator | |||
* bits 23-16: max f-number denominator | |||
* bits 15-8: min f-number numerator | |||
* bits 7-0: min f-number denominator | |||
*/ | |||
#define GC2235_F_NUMBER_RANGE 0x1a0a1a0a | |||
#define GC2235_ID 0x2235 | |||
#define GC2235_FINE_INTG_TIME_MIN 0 | |||
#define GC2235_FINE_INTG_TIME_MAX_MARGIN 0 | |||
#define GC2235_COARSE_INTG_TIME_MIN 1 | |||
#define GC2235_COARSE_INTG_TIME_MAX_MARGIN (0xffff - 6) | |||
/* | |||
* GC2235 System control registers | |||
*/ | |||
/* | |||
* GC2235 System control registers | |||
*/ | |||
#define GC2235_SENSOR_ID_H 0xF0 | |||
#define GC2235_SENSOR_ID_L 0xF1 | |||
#define GC2235_RESET_RELATED 0xFE | |||
#define GC2235_SW_RESET 0x8 | |||
#define GC2235_MIPI_RESET 0x3 | |||
#define GC2235_RESET_BIT 0x4 | |||
#define GC2235_REGISTER_PAGE_0 0x0 | |||
#define GC2235_REGISTER_PAGE_3 0x3 | |||
#define GC2235_V_CROP_START_H 0x91 | |||
#define GC2235_V_CROP_START_L 0x92 | |||
#define GC2235_H_CROP_START_H 0x93 | |||
#define GC2235_H_CROP_START_L 0x94 | |||
#define GC2235_V_OUTSIZE_H 0x95 | |||
#define GC2235_V_OUTSIZE_L 0x96 | |||
#define GC2235_H_OUTSIZE_H 0x97 | |||
#define GC2235_H_OUTSIZE_L 0x98 | |||
#define GC2235_HB_H 0x5 | |||
#define GC2235_HB_L 0x6 | |||
#define GC2235_VB_H 0x7 | |||
#define GC2235_VB_L 0x8 | |||
#define GC2235_SH_DELAY_H 0x11 | |||
#define GC2235_SH_DELAY_L 0x12 | |||
#define GC2235_CSI2_MODE 0x10 | |||
#define GC2235_EXPOSURE_H 0x3 | |||
#define GC2235_EXPOSURE_L 0x4 | |||
#define GC2235_GLOBAL_GAIN 0xB0 | |||
#define GC2235_PRE_GAIN 0xB1 | |||
#define GC2235_AWB_R_GAIN 0xB3 | |||
#define GC2235_AWB_G_GAIN 0xB4 | |||
#define GC2235_AWB_B_GAIN 0xB5 | |||
#define GC2235_START_STREAMING 0x91 | |||
#define GC2235_STOP_STREAMING 0x0 | |||
struct regval_list { | |||
u16 reg_num; | |||
u8 value; | |||
}; | |||
struct gc2235_resolution { | |||
u8 *desc; | |||
const struct gc2235_reg *regs; | |||
int res; | |||
int width; | |||
int height; | |||
int fps; | |||
int pix_clk_freq; | |||
u32 skip_frames; | |||
u16 pixels_per_line; | |||
u16 lines_per_frame; | |||
u8 bin_factor_x; | |||
u8 bin_factor_y; | |||
u8 bin_mode; | |||
bool used; | |||
}; | |||
struct gc2235_format { | |||
u8 *desc; | |||
u32 pixelformat; | |||
struct gc2235_reg *regs; | |||
}; | |||
struct gc2235_control { | |||
struct v4l2_queryctrl qc; | |||
int (*query)(struct v4l2_subdev *sd, s32 *value); | |||
int (*tweak)(struct v4l2_subdev *sd, s32 value); | |||
}; | |||
/* | |||
* gc2235 device structure. | |||
*/ | |||
struct gc2235_device { | |||
struct v4l2_subdev sd; | |||
struct media_pad pad; | |||
struct v4l2_mbus_framefmt format; | |||
struct mutex input_lock; | |||
struct camera_sensor_platform_data *platform_data; | |||
int vt_pix_clk_freq_mhz; | |||
int fmt_idx; | |||
int run_mode; | |||
u8 res; | |||
u8 type; | |||
}; | |||
enum gc2235_tok_type { | |||
GC2235_8BIT = 0x0001, | |||
GC2235_16BIT = 0x0002, | |||
GC2235_32BIT = 0x0004, | |||
GC2235_TOK_TERM = 0xf000, /* terminating token for reg list */ | |||
GC2235_TOK_DELAY = 0xfe00, /* delay token for reg list */ | |||
GC2235_TOK_MASK = 0xfff0 | |||
}; | |||
/** | |||
* struct gc2235_reg - MI sensor register format | |||
* @type: type of the register | |||
* @reg: 8-bit offset to register | |||
* @val: 8/16/32-bit register value | |||
* | |||
* Define a structure for sensor register initialization values | |||
*/ | |||
struct gc2235_reg { | |||
enum gc2235_tok_type type; | |||
u8 reg; | |||
u32 val; /* @set value for read/mod/write, @mask */ | |||
}; | |||
#define to_gc2235_sensor(x) container_of(x, struct gc2235_device, sd) | |||
#define GC2235_MAX_WRITE_BUF_SIZE 30 | |||
struct gc2235_write_buffer { | |||
u8 addr; | |||
u8 data[GC2235_MAX_WRITE_BUF_SIZE]; | |||
}; | |||
struct gc2235_write_ctrl { | |||
int index; | |||
struct gc2235_write_buffer buffer; | |||
}; | |||
static const struct i2c_device_id gc2235_id[] = { | |||
{GC2235_NAME, 0}, | |||
{} | |||
}; | |||
static struct gc2235_reg const gc2235_stream_on[] = { | |||
{ GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */ | |||
{ GC2235_8BIT, 0x10, 0x91}, /* start mipi */ | |||
{ GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */ | |||
{ GC2235_TOK_TERM, 0, 0 } | |||
}; | |||
static struct gc2235_reg const gc2235_stream_off[] = { | |||
{ GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */ | |||
{ GC2235_8BIT, 0x10, 0x81}, /* stop mipi */ | |||
{ GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */ | |||
{ GC2235_TOK_TERM, 0, 0 } | |||
}; | |||
static struct gc2235_reg const gc2235_init_settings[] = { | |||
/* Sysytem */ | |||
{ GC2235_8BIT, 0xfe, 0x80 }, | |||
{ GC2235_8BIT, 0xfe, 0x80 }, | |||
{ GC2235_8BIT, 0xfe, 0x80 }, | |||
{ GC2235_8BIT, 0xf2, 0x00 }, | |||
{ GC2235_8BIT, 0xf6, 0x00 }, | |||
{ GC2235_8BIT, 0xfc, 0x06 }, | |||
{ GC2235_8BIT, 0xf7, 0x15 }, | |||
{ GC2235_8BIT, 0xf8, 0x85 }, | |||
{ GC2235_8BIT, 0xf9, 0xfe }, | |||
{ GC2235_8BIT, 0xfa, 0x00 }, | |||
{ GC2235_8BIT, 0xfe, 0x00 }, | |||
/* Analog & cisctl */ | |||
{ GC2235_8BIT, 0x03, 0x04 }, | |||
{ GC2235_8BIT, 0x04, 0x9e }, | |||
{ GC2235_8BIT, 0x05, 0x00 }, | |||
{ GC2235_8BIT, 0x06, 0xf4 }, | |||
{ GC2235_8BIT, 0x07, 0x00 }, | |||
{ GC2235_8BIT, 0x08, 0x88 }, | |||
{ GC2235_8BIT, 0x0a, 0x00 }, /* row start */ | |||
{ GC2235_8BIT, 0x0c, 0x00 }, /* col start */ | |||
{ GC2235_8BIT, 0x0d, 0x04 }, /* win height 1232 */ | |||
{ GC2235_8BIT, 0x0e, 0xd0 }, | |||
{ GC2235_8BIT, 0x0f, 0x06 }, /* win width: 1616 */ | |||
{ GC2235_8BIT, 0x10, 0x60 }, | |||
{ GC2235_8BIT, 0x17, 0x15 }, /* mirror flip */ | |||
{ GC2235_8BIT, 0x18, 0x12 }, | |||
{ GC2235_8BIT, 0x19, 0x06 }, | |||
{ GC2235_8BIT, 0x1a, 0x01 }, | |||
{ GC2235_8BIT, 0x1b, 0x4d }, | |||
{ GC2235_8BIT, 0x1e, 0x88 }, | |||
{ GC2235_8BIT, 0x1f, 0x48 }, | |||
{ GC2235_8BIT, 0x20, 0x03 }, | |||
{ GC2235_8BIT, 0x21, 0x7f }, | |||
{ GC2235_8BIT, 0x22, 0x83 }, | |||
{ GC2235_8BIT, 0x23, 0x42 }, | |||
{ GC2235_8BIT, 0x24, 0x16 }, | |||
{ GC2235_8BIT, 0x26, 0x01 }, /*analog gain*/ | |||
{ GC2235_8BIT, 0x27, 0x30 }, | |||
{ GC2235_8BIT, 0x3f, 0x00 }, /* PRC */ | |||
/* blk */ | |||
{ GC2235_8BIT, 0x40, 0x03 }, | |||
{ GC2235_8BIT, 0x41, 0x00 }, | |||
{ GC2235_8BIT, 0x43, 0x20 }, | |||
{ GC2235_8BIT, 0x5e, 0x00 }, | |||
{ GC2235_8BIT, 0x5f, 0x00 }, | |||
{ GC2235_8BIT, 0x60, 0x00 }, | |||
{ GC2235_8BIT, 0x61, 0x00 }, | |||
{ GC2235_8BIT, 0x62, 0x00 }, | |||
{ GC2235_8BIT, 0x63, 0x00 }, | |||
{ GC2235_8BIT, 0x64, 0x00 }, | |||
{ GC2235_8BIT, 0x65, 0x00 }, | |||
{ GC2235_8BIT, 0x66, 0x20 }, | |||
{ GC2235_8BIT, 0x67, 0x20 }, | |||
{ GC2235_8BIT, 0x68, 0x20 }, | |||
{ GC2235_8BIT, 0x69, 0x20 }, | |||
/* Gain */ | |||
{ GC2235_8BIT, 0xb2, 0x00 }, | |||
{ GC2235_8BIT, 0xb3, 0x40 }, | |||
{ GC2235_8BIT, 0xb4, 0x40 }, | |||
{ GC2235_8BIT, 0xb5, 0x40 }, | |||
/* Dark sun */ | |||
{ GC2235_8BIT, 0xbc, 0x00 }, | |||
{ GC2235_8BIT, 0xfe, 0x03 }, | |||
{ GC2235_8BIT, 0x10, 0x81 }, /* disable mipi */ | |||
{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */ | |||
{ GC2235_TOK_TERM, 0, 0 } | |||
}; | |||
/* | |||
* Register settings for various resolution | |||
*/ | |||
static struct gc2235_reg const gc2235_1616_916_30fps[] = { | |||
{ GC2235_8BIT, 0x8b, 0xa0 }, | |||
{ GC2235_8BIT, 0x8c, 0x02 }, | |||
{ GC2235_8BIT, 0x90, 0x01 }, | |||
{ GC2235_8BIT, 0x92, 0x96 }, | |||
{ GC2235_8BIT, 0x94, 0x00 }, | |||
{ GC2235_8BIT, 0x95, 0x03 }, /* crop win height 900 */ | |||
{ GC2235_8BIT, 0x96, 0x94 }, | |||
{ GC2235_8BIT, 0x97, 0x06 }, /* crop win width 1600 */ | |||
{ GC2235_8BIT, 0x98, 0x50 }, | |||
/* mimi init */ | |||
{ GC2235_8BIT, 0xfe, 0x03 }, /* switch to P3 */ | |||
{ GC2235_8BIT, 0x01, 0x07 }, | |||
{ GC2235_8BIT, 0x02, 0x11 }, | |||
{ GC2235_8BIT, 0x03, 0x11 }, | |||
{ GC2235_8BIT, 0x06, 0x80 }, | |||
{ GC2235_8BIT, 0x11, 0x2b }, | |||
/* set mipi buffer */ | |||
{ GC2235_8BIT, 0x12, 0xe4 }, /* val_low = (width * 10 / 8) & 0xFF */ | |||
{ GC2235_8BIT, 0x13, 0x07 }, /* val_high = (width * 10 / 8) >> 8 */ | |||
{ GC2235_8BIT, 0x15, 0x12 }, /* DPHY mode*/ | |||
{ GC2235_8BIT, 0x04, 0x20 }, | |||
{ GC2235_8BIT, 0x05, 0x00 }, | |||
{ GC2235_8BIT, 0x17, 0x01 }, | |||
{ GC2235_8BIT, 0x21, 0x01 }, | |||
{ GC2235_8BIT, 0x22, 0x02 }, | |||
{ GC2235_8BIT, 0x23, 0x01 }, | |||
{ GC2235_8BIT, 0x29, 0x02 }, | |||
{ GC2235_8BIT, 0x2a, 0x01 }, | |||
{ GC2235_8BIT, 0x10, 0x81 }, /* disable mipi */ | |||
{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */ | |||
{ GC2235_TOK_TERM, 0, 0 } | |||
}; | |||
static struct gc2235_reg const gc2235_1616_1082_30fps[] = { | |||
{ GC2235_8BIT, 0x8b, 0xa0 }, | |||
{ GC2235_8BIT, 0x8c, 0x02 }, | |||
{ GC2235_8BIT, 0x90, 0x01 }, | |||
{ GC2235_8BIT, 0x92, 0x4a }, | |||
{ GC2235_8BIT, 0x94, 0x00 }, | |||
{ GC2235_8BIT, 0x95, 0x04 }, /* crop win height 1082 */ | |||
{ GC2235_8BIT, 0x96, 0x3a }, | |||
{ GC2235_8BIT, 0x97, 0x06 }, /* crop win width 1616 */ | |||
{ GC2235_8BIT, 0x98, 0x50 }, | |||
/* mimi init */ | |||
{ GC2235_8BIT, 0xfe, 0x03 }, /* switch to P3 */ | |||
{ GC2235_8BIT, 0x01, 0x07 }, | |||
{ GC2235_8BIT, 0x02, 0x11 }, | |||
{ GC2235_8BIT, 0x03, 0x11 }, | |||
{ GC2235_8BIT, 0x06, 0x80 }, | |||
{ GC2235_8BIT, 0x11, 0x2b }, | |||
/* set mipi buffer */ | |||
{ GC2235_8BIT, 0x12, 0xe4 }, /* val_low = (width * 10 / 8) & 0xFF */ | |||
{ GC2235_8BIT, 0x13, 0x07 }, /* val_high = (width * 10 / 8) >> 8 */ | |||
{ GC2235_8BIT, 0x15, 0x12 }, /* DPHY mode*/ | |||
{ GC2235_8BIT, 0x04, 0x20 }, | |||
{ GC2235_8BIT, 0x05, 0x00 }, | |||
{ GC2235_8BIT, 0x17, 0x01 }, | |||
{ GC2235_8BIT, 0x21, 0x01 }, | |||
{ GC2235_8BIT, 0x22, 0x02 }, | |||
{ GC2235_8BIT, 0x23, 0x01 }, | |||
{ GC2235_8BIT, 0x29, 0x02 }, | |||
{ GC2235_8BIT, 0x2a, 0x01 }, | |||
{ GC2235_8BIT, 0x10, 0x81 }, /* disable mipi */ | |||
{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */ | |||
{ GC2235_TOK_TERM, 0, 0 } | |||
}; | |||
static struct gc2235_reg const gc2235_1616_1216_30fps[] = { | |||
{ GC2235_8BIT, 0x8b, 0xa0 }, | |||
{ GC2235_8BIT, 0x8c, 0x02 }, | |||
{ GC2235_8BIT, 0x90, 0x01 }, | |||
{ GC2235_8BIT, 0x92, 0x02 }, | |||
{ GC2235_8BIT, 0x94, 0x00 }, | |||
{ GC2235_8BIT, 0x95, 0x04 }, /* crop win height 1216 */ | |||
{ GC2235_8BIT, 0x96, 0xc0 }, | |||
{ GC2235_8BIT, 0x97, 0x06 }, /* crop win width 1616 */ | |||
{ GC2235_8BIT, 0x98, 0x50 }, | |||
/* mimi init */ | |||
{ GC2235_8BIT, 0xfe, 0x03 }, /* switch to P3 */ | |||
{ GC2235_8BIT, 0x01, 0x07 }, | |||
{ GC2235_8BIT, 0x02, 0x11 }, | |||
{ GC2235_8BIT, 0x03, 0x11 }, | |||
{ GC2235_8BIT, 0x06, 0x80 }, | |||
{ GC2235_8BIT, 0x11, 0x2b }, | |||
/* set mipi buffer */ | |||
{ GC2235_8BIT, 0x12, 0xe4 }, /* val_low = (width * 10 / 8) & 0xFF */ | |||
{ GC2235_8BIT, 0x13, 0x07 }, /* val_high = (width * 10 / 8) >> 8 */ | |||
{ GC2235_8BIT, 0x15, 0x12 }, /* DPHY mode*/ | |||
{ GC2235_8BIT, 0x04, 0x20 }, | |||
{ GC2235_8BIT, 0x05, 0x00 }, | |||
{ GC2235_8BIT, 0x17, 0x01 }, | |||
{ GC2235_8BIT, 0x21, 0x01 }, | |||
{ GC2235_8BIT, 0x22, 0x02 }, | |||
{ GC2235_8BIT, 0x23, 0x01 }, | |||
{ GC2235_8BIT, 0x29, 0x02 }, | |||
{ GC2235_8BIT, 0x2a, 0x01 }, | |||
{ GC2235_8BIT, 0x10, 0x81 }, /* disable mipi */ | |||
{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */ | |||
{ GC2235_TOK_TERM, 0, 0 } | |||
}; | |||
struct gc2235_resolution gc2235_res_preview[] = { | |||
{ | |||
.desc = "gc2235_1600_900_30fps", | |||
.width = 1616, | |||
.height = 916, | |||
.pix_clk_freq = 75, | |||
.fps = 30, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 932, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_916_30fps, | |||
}, | |||
{ | |||
.desc = "gc2235_1600_1066_30fps", | |||
.width = 1616, | |||
.height = 1082, | |||
.pix_clk_freq = 75, | |||
.fps = 30, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 1098, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_1082_30fps, | |||
}, | |||
{ | |||
.desc = "gc2235_1600_1200_30fps", | |||
.width = 1616, | |||
.height = 1216, | |||
.pix_clk_freq = 75, | |||
.fps = 27, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 1232, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_1216_30fps, | |||
}, | |||
}; | |||
#define N_RES_PREVIEW (ARRAY_SIZE(gc2235_res_preview)) | |||
struct gc2235_resolution gc2235_res_still[] = { | |||
{ | |||
.desc = "gc2235_1600_900_30fps", | |||
.width = 1616, | |||
.height = 916, | |||
.pix_clk_freq = 75, | |||
.fps = 30, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 932, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_916_30fps, | |||
}, | |||
{ | |||
.desc = "gc2235_1600_1066_30fps", | |||
.width = 1616, | |||
.height = 1082, | |||
.pix_clk_freq = 75, | |||
.fps = 30, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 1098, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_1082_30fps, | |||
}, | |||
{ | |||
.desc = "gc2235_1600_1200_30fps", | |||
.width = 1616, | |||
.height = 1216, | |||
.pix_clk_freq = 75, | |||
.fps = 27, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 1232, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_1216_30fps, | |||
}, | |||
}; | |||
#define N_RES_STILL (ARRAY_SIZE(gc2235_res_still)) | |||
struct gc2235_resolution gc2235_res_video[] = { | |||
{ | |||
.desc = "gc2235_1600_900_30fps", | |||
.width = 1616, | |||
.height = 916, | |||
.pix_clk_freq = 75, | |||
.fps = 30, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 932, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_916_30fps, | |||
}, | |||
{ | |||
.desc = "gc2235_1600_1066_30fps", | |||
.width = 1616, | |||
.height = 1082, | |||
.pix_clk_freq = 75, | |||
.fps = 30, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 1098, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_1082_30fps, | |||
}, | |||
{ | |||
.desc = "gc2235_1600_1200_30fps", | |||
.width = 1616, | |||
.height = 1216, | |||
.pix_clk_freq = 75, | |||
.fps = 27, | |||
.used = 0, | |||
.pixels_per_line = 1616, | |||
.lines_per_frame = 1232, | |||
.bin_factor_x = 0, | |||
.bin_factor_y = 0, | |||
.bin_mode = 0, | |||
.skip_frames = 3, | |||
.regs = gc2235_1616_1216_30fps, | |||
}, | |||
}; | |||
#define N_RES_VIDEO (ARRAY_SIZE(gc2235_res_video)) | |||
static struct gc2235_resolution *gc2235_res = gc2235_res_preview; | |||
static int N_RES = N_RES_PREVIEW; | |||
#endif |
@@ -0,0 +1,692 @@ | |||
/* | |||
* Support for HM056_raw Camera Sensor. | |||
* | |||
* Copyright (c) 2013 Intel Corporation. All Rights Reserved. | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License version | |||
* 2 as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |||
* 02110-1301, USA. | |||
* | |||
*/ | |||
#ifndef __HM2056_H__ | |||
#define __HM2056_H__ | |||
#include <linux/kernel.h> | |||
#include <linux/types.h> | |||
#include <linux/i2c.h> | |||
#include <linux/delay.h> | |||
#include <linux/videodev2.h> | |||
#include <linux/spinlock.h> | |||
#include <media/v4l2-subdev.h> | |||
#include <media/v4l2-device.h> | |||
#include <media/v4l2-chip-ident.h> | |||
#include <linux/v4l2-mediabus.h> | |||
#include <media/media-entity.h> | |||
#include <linux/atomisp_platform.h> | |||
#include <linux/atomisp.h> | |||
#include <linux/HWVersion.h> | |||
extern int Read_HW_ID(void); | |||
//static unsigned int HW_ID = 0xFF; | |||
#define V4L2_IDENT_HM2056_RAW 8245 | |||
#define HM2056_NAME "hm2056_raw" | |||
#define I2C_RETRY_COUNT 5 | |||
#define MSG_LEN_OFFSET 2 | |||
#define MAX_FMTS 1 | |||
//registers | |||
#define HM2056_REG_CHIP_ID_H 0x0001 | |||
#define HM2056_REG_CHIP_ID_L 0x0002 | |||
#define HM2056_REG_BLANKING_ROW_H 0x0010 | |||
#define HM2056_REG_BLANKING_ROW_L 0x0011 | |||
#define HM2056_REG_BLANKING_COLUMN_CLK 0x0012 | |||
#define HM2056_REG_BLANKING_COLUMN 0x0013 | |||
#define HM2056_REG_INTEGRATION_TIME_H 0x0015 | |||
#define HM2056_REG_INTEGRATION_TIME_L 0x0016 | |||
#define HM2056_REG_AGAIN 0x0018 | |||
#define HM2056_REG_DGAIN 0x001D | |||
#define HM2056_REG_COMMAND_UPDATE 0x0100 | |||
#define HM2056_REG_H_START_L 0x05E4 | |||
#define HM2056_REG_H_START_H 0x05E5 | |||
#define HM2056_REG_H_END_L 0x05E6 | |||
#define HM2056_REG_H_END_H 0x05E7 | |||
#define HM2056_REG_V_START_L 0x05E8 | |||
#define HM2056_REG_V_START_H 0x05E9 | |||
#define HM2056_REG_V_END_L 0x05EA | |||
#define HM2056_REG_V_END_H 0x05EB | |||
/* DEVICE_ID */ | |||
#define HM2056_MOD_ID 0x2056 | |||
#define HM2056_FINE_INTG_TIME_MIN 0 | |||
#define HM2056_FINE_INTG_TIME_MAX_MARGIN 65535 | |||
#define HM2056_COARSE_INTG_TIME_MIN 0 | |||
#define HM2056_COARSE_INTG_TIME_MAX_MARGIN 65535 | |||
enum hm2056_tok_type { | |||
HM2056_8BIT = 0x0001, | |||
HM2056_TOK_TERM = 0xf000, /* terminating token for reg list */ | |||
HM2056_TOK_DELAY = 0xfe00, /* delay token for reg list */ | |||
HM2056_TOK_MASK = 0xfff0 | |||
}; | |||
struct hm2056_reg { | |||
enum hm2056_tok_type type; | |||
u16 reg; | |||
u32 val; /* @set value for read/mod/write, @mask */ | |||
}; | |||
struct hm2056_raw_device { | |||
struct v4l2_subdev sd; | |||
struct media_pad pad; | |||
struct v4l2_mbus_framefmt format; | |||
struct mutex input_lock; | |||
struct hm2056_raw_res_struct *hm2056_raw_res; | |||
int n_res; | |||
int fmt_idx; | |||
int run_mode; | |||
struct camera_sensor_platform_data *platform_data; | |||
char name[32]; | |||
struct attribute_group sensor_i2c_attribute; //Add for ATD read camera status+++ | |||
}; | |||
struct hm2056_raw_res_struct { | |||
u8 *desc; | |||
int width; | |||
int height; | |||
int fps; | |||
int skip_frames; | |||
bool used; | |||
struct hm2056_reg const *regs; | |||
int horizontal_start; | |||
int horizontal_end; | |||
int vertical_start; | |||
int vertical_end; | |||
int pixel_clk; | |||
int line_length_pck; | |||
int frame_length_lines; | |||
u8 bin_factor_x; | |||
u8 bin_factor_y; | |||
u8 bin_mode; | |||
}; | |||
struct hm2056_raw_control { | |||
struct v4l2_queryctrl qc; | |||
int (*query)(struct v4l2_subdev *sd, s32 *value); | |||
int (*tweak)(struct v4l2_subdev *sd, int value); | |||
}; | |||
/* 2 bytes used for address: 256 bytes total */ | |||
#define HM2056_RAW_MAX_WRITE_BUF_SIZE 1024 | |||
struct hm2056_write_buffer { | |||
u16 addr; | |||
u8 data[HM2056_RAW_MAX_WRITE_BUF_SIZE]; | |||
}; | |||
struct hm2056_write_ctrl { | |||
int index; | |||
struct hm2056_write_buffer buffer; | |||
}; | |||
static const struct i2c_device_id hm2056_raw_id[] = { | |||
{HM2056_NAME, 0}, | |||
{} | |||
}; | |||
static struct hm2056_reg const hm2056_stream_on[] = { | |||
{HM2056_8BIT, 0x0000, 0x01}, | |||
{HM2056_8BIT, 0x0100, 0x01}, | |||
{HM2056_8BIT, 0x0101, 0x01}, | |||
{HM2056_8BIT, 0x0005, 0x01}, //Turn on rolling shutter | |||
{HM2056_TOK_TERM, 0, 0} | |||
}; | |||
static struct hm2056_reg const hm2056_stream_off[] = { | |||
{HM2056_8BIT, 0x0005, 0x00}, //Turn on rolling shutter | |||
{HM2056_TOK_TERM, 0, 0} | |||
}; | |||
/* | |||
* initial settings | |||
*/ | |||
static struct hm2056_reg const hm2056_init[] = { | |||
{HM2056_8BIT, 0x0022, 0x00}, // Reset | |||
{HM2056_8BIT, 0x0020, 0x00}, | |||
{HM2056_8BIT, 0x0025, 0x00}, //CKCFG 80 from system clock, 00 from PLL | |||
{HM2056_8BIT, 0x0026, 0x85}, //PLL1CFG should be 07 when system clock, should be 87 when PLL | |||
{HM2056_8BIT, 0x0027, 0x03}, //Raw output | |||
{HM2056_8BIT, 0x0028, 0xC0}, //Raw output | |||
{HM2056_8BIT, 0x002A, 0x2F}, // CLK - 20131106 | |||
{HM2056_8BIT, 0x002B, 0x04}, // CLK - 20131106 | |||
{HM2056_8BIT, 0x002C, 0x0A}, //Set default vaule for CP and resistance of LPF to 1010 | |||
{HM2056_8BIT, 0x0004, 0x10}, | |||
{HM2056_8BIT, 0x0006, 0x00}, // Flip/Mirror | |||
{HM2056_8BIT, 0x000D, 0x00}, // 20120220 to fix morie | |||
{HM2056_8BIT, 0x000E, 0x00}, // Binning ON | |||
{HM2056_8BIT, 0x000F, 0x00}, // IMGCFG | |||
{HM2056_8BIT, 0x0010, 0x00}, // VBI - 20131106 | |||
{HM2056_8BIT, 0x0011, 0x5F}, // VBI - 20131119 | |||
{HM2056_8BIT, 0x0012, 0x04}, //2012.02.08 | |||
{HM2056_8BIT, 0x0013, 0x00}, | |||
{HM2056_8BIT, 0x0040, 0x20}, //20120224 for BLC stable | |||
{HM2056_8BIT, 0x0053, 0x0A}, | |||
{HM2056_8BIT, 0x0044, 0x06}, //enable BLC_phase2 | |||
{HM2056_8BIT, 0x0046, 0xD8}, //enable BLC_phase1, disable BLC_phase2 dithering | |||
{HM2056_8BIT, 0x004A, 0x0A}, //disable BLC_phase2 hot pixel filter | |||
{HM2056_8BIT, 0x004B, 0x72}, | |||
{HM2056_8BIT, 0x0075, 0x01}, //in OMUX data swap for debug usage | |||
{HM2056_8BIT, 0x0070, 0x5F}, // HBlank related - 20131106 | |||
{HM2056_8BIT, 0x0071, 0xAB}, // HBlank related - 20131106 | |||
{HM2056_8BIT, 0x0072, 0x55}, // HBlank related - 20131106 | |||
{HM2056_8BIT, 0x0073, 0x50}, | |||
{HM2056_8BIT, 0x0077, 0x04}, | |||
{HM2056_8BIT, 0x0080, 0xC8}, //2012.02.08 | |||
{HM2056_8BIT, 0x0082, 0xE2}, | |||
{HM2056_8BIT, 0x0083, 0xF0}, | |||
{HM2056_8BIT, 0x0085, 0x11}, //Enable Thin-Oxide Case (Kwangoh kim), Set ADC power to 100% Enable thermal sensor control bit[7] 0:on 1:off 2012 02 13 (YL) | |||
{HM2056_8BIT, 0x0086, 0x02}, //K.Kim, 0x2011.12.09 | |||
{HM2056_8BIT, 0x0087, 0x80}, //K.Kim, 0x2011.12.09 | |||
{HM2056_8BIT, 0x0088, 0x6C}, | |||
{HM2056_8BIT, 0x0089, 0x2E}, | |||
{HM2056_8BIT, 0x008A, 0x7D}, //20120224 for BLC stable | |||
{HM2056_8BIT, 0x008D, 0x20}, | |||
{HM2056_8BIT, 0x0090, 0x00}, //1.5x(Change Gain Table ) | |||
{HM2056_8BIT, 0x0091, 0x10}, //3x (3x CTIA) | |||
{HM2056_8BIT, 0x0092, 0x11}, //6x (3x CTIA + 2x PGA) | |||
{HM2056_8BIT, 0x0093, 0x12}, //12x (3x CTIA + 4x PGA) | |||
{HM2056_8BIT, 0x0094, 0x16}, //24x (3x CTIA + 8x PGA) | |||
{HM2056_8BIT, 0x0095, 0x08}, //1.5x 20120217 for color shift | |||
{HM2056_8BIT, 0x0096, 0x00}, //3x 20120217 for color shift | |||
{HM2056_8BIT, 0x0097, 0x10}, //6x 20120217 for color shift | |||
{HM2056_8BIT, 0x0098, 0x11}, //12x 20120217 for color shift | |||
{HM2056_8BIT, 0x0099, 0x12}, //24x 20120217 for color shift | |||
{HM2056_8BIT, 0x009A, 0x16}, //24x | |||
{HM2056_8BIT, 0x009B, 0x34}, | |||
{HM2056_8BIT, 0x00A0, 0x00}, | |||
{HM2056_8BIT, 0x00A1, 0x04}, //2012.02.06(for Ver.C) | |||
{HM2056_8BIT, 0x011F, 0xFF}, //simple bpc P31 & P33[4] P40 P42 P44[5] | |||
{HM2056_8BIT, 0x0120, 0x13}, //36:50Hz, 37:60Hz, BV_Win_Weight_En=1 | |||
{HM2056_8BIT, 0x0121, 0x01}, //NSatScale_En=0, NSatScale=0 | |||
{HM2056_8BIT, 0x0122, 0x39}, | |||
{HM2056_8BIT, 0x0123, 0xC2}, | |||
{HM2056_8BIT, 0x0124, 0xCE}, | |||
{HM2056_8BIT, 0x0125, 0x20}, | |||
{HM2056_8BIT, 0x0126, 0x50}, | |||
{HM2056_8BIT, 0x0128, 0x1F}, | |||
{HM2056_8BIT, 0x0132, 0x10}, | |||
{HM2056_8BIT, 0x0136, 0x0A}, | |||
{HM2056_8BIT, 0x0131, 0xB8}, //simle bpc enable[4] | |||
{HM2056_8BIT, 0x0140, 0x14}, | |||
{HM2056_8BIT, 0x0141, 0x0A}, | |||
{HM2056_8BIT, 0x0142, 0x14}, | |||
{HM2056_8BIT, 0x0143, 0x0A}, | |||
{HM2056_8BIT, 0x0144, 0x06}, //Sort bpc hot pixel ratio | |||
{HM2056_8BIT, 0x0145, 0x00}, | |||
{HM2056_8BIT, 0x0146, 0x20}, | |||
{HM2056_8BIT, 0x0147, 0x0A}, | |||
{HM2056_8BIT, 0x0148, 0x10}, | |||
{HM2056_8BIT, 0x0149, 0x0C}, | |||
{HM2056_8BIT, 0x014A, 0x80}, | |||
{HM2056_8BIT, 0x014B, 0x80}, | |||
{HM2056_8BIT, 0x014C, 0x2E}, | |||
{HM2056_8BIT, 0x014D, 0x2E}, | |||
{HM2056_8BIT, 0x014E, 0x05}, | |||
{HM2056_8BIT, 0x014F, 0x05}, | |||
{HM2056_8BIT, 0x0150, 0x0D}, | |||
{HM2056_8BIT, 0x0155, 0x00}, | |||
{HM2056_8BIT, 0x0156, 0x10}, | |||
{HM2056_8BIT, 0x0157, 0x0A}, | |||
{HM2056_8BIT, 0x0158, 0x0A}, | |||
{HM2056_8BIT, 0x0159, 0x0A}, | |||
{HM2056_8BIT, 0x015A, 0x05}, | |||
{HM2056_8BIT, 0x015B, 0x05}, | |||
{HM2056_8BIT, 0x015C, 0x05}, | |||
{HM2056_8BIT, 0x015D, 0x05}, | |||
{HM2056_8BIT, 0x015E, 0x08}, | |||
{HM2056_8BIT, 0x015F, 0xFF}, | |||
{HM2056_8BIT, 0x0160, 0x50}, // OTP BPC 2line & 4line enable | |||
{HM2056_8BIT, 0x0161, 0x20}, | |||
{HM2056_8BIT, 0x0162, 0x14}, | |||
{HM2056_8BIT, 0x0163, 0x0A}, | |||
{HM2056_8BIT, 0x0164, 0x10}, // OTP 4line Strength | |||
{HM2056_8BIT, 0x0165, 0x08}, | |||
{HM2056_8BIT, 0x0166, 0x0A}, | |||
{HM2056_8BIT, 0x018C, 0x24}, | |||
{HM2056_8BIT, 0x018D, 0x04}, //Cluster correction enable singal from thermal sensor (YL 2012 02 13) | |||
{HM2056_8BIT, 0x018E, 0x00}, //Enable Thermal sensor control bit[7] (YL 2012 02 13) | |||
{HM2056_8BIT, 0x018F, 0x11}, //Cluster Pulse enable T1[0] T2[1] T3[2] T4[3] | |||
{HM2056_8BIT, 0x0190, 0x80}, //A11 BPC Strength[7:3], cluster correct P11[0]P12[1]P13[2] | |||
{HM2056_8BIT, 0x0191, 0x47}, //A11[0],A7[1],Sort[3],A13 AVG[6] | |||
{HM2056_8BIT, 0x0192, 0x48}, //A13 Strength[4:0],hot pixel detect for cluster[6] | |||
{HM2056_8BIT, 0x0193, 0x64}, | |||
{HM2056_8BIT, 0x0194, 0x32}, | |||
{HM2056_8BIT, 0x0195, 0xc8}, | |||
{HM2056_8BIT, 0x0196, 0x96}, | |||
{HM2056_8BIT, 0x0197, 0x64}, | |||
{HM2056_8BIT, 0x0198, 0x32}, | |||
{HM2056_8BIT, 0x0199, 0x14}, //A13 hot pixel th | |||
{HM2056_8BIT, 0x019A, 0x20}, // A13 edge detect th | |||
{HM2056_8BIT, 0x019B, 0x14}, | |||
{HM2056_8BIT, 0x01BA, 0x10}, //BD | |||
{HM2056_8BIT, 0x01BB, 0x04}, | |||
{HM2056_8BIT, 0x01D8, 0x40}, | |||
{HM2056_8BIT, 0x01DE, 0x60}, | |||
{HM2056_8BIT, 0x01E4, 0x04}, | |||
{HM2056_8BIT, 0x01E5, 0x04}, | |||
{HM2056_8BIT, 0x01E6, 0x04}, | |||
{HM2056_8BIT, 0x01F2, 0x0C}, | |||
{HM2056_8BIT, 0x01F3, 0x14}, | |||
{HM2056_8BIT, 0x01F8, 0x04}, | |||
{HM2056_8BIT, 0x01F9, 0x0C}, | |||
{HM2056_8BIT, 0x01FE, 0x02}, | |||
{HM2056_8BIT, 0x01FF, 0x04}, | |||
{HM2056_8BIT, 0x0380, 0xFC}, | |||
{HM2056_8BIT, 0x0381, 0x4A}, | |||
{HM2056_8BIT, 0x0382, 0x36}, | |||
{HM2056_8BIT, 0x038A, 0x40}, | |||
{HM2056_8BIT, 0x038B, 0x08}, | |||
{HM2056_8BIT, 0x038C, 0xC1}, | |||
{HM2056_8BIT, 0x038E, 0x40}, | |||
{HM2056_8BIT, 0x038F, 0x09}, | |||
{HM2056_8BIT, 0x0390, 0xD0}, | |||
{HM2056_8BIT, 0x0391, 0x05}, | |||
{HM2056_8BIT, 0x0393, 0x80}, | |||
{HM2056_8BIT, 0x0395, 0x21}, //AEAWB skip count | |||
{HM2056_8BIT, 0x0420, 0x84}, //Digital Gain offset | |||
{HM2056_8BIT, 0x0421, 0x00}, | |||
{HM2056_8BIT, 0x0422, 0x00}, | |||
{HM2056_8BIT, 0x0423, 0x83}, | |||
{HM2056_8BIT, 0x0466, 0x14}, | |||
{HM2056_8BIT, 0x0460, 0x01}, | |||
{HM2056_8BIT, 0x0461, 0xFF}, | |||
{HM2056_8BIT, 0x0462, 0xFF}, | |||
{HM2056_8BIT, 0x0478, 0x01}, | |||
{HM2056_8BIT, 0x047A, 0x00}, //ELOFFNRB | |||
{HM2056_8BIT, 0x047B, 0x00}, //ELOFFNRY | |||
{HM2056_8BIT, 0x0540, 0x00}, | |||
{HM2056_8BIT, 0x0541, 0x9D}, //60Hz Flicker | |||
{HM2056_8BIT, 0x0542, 0x00}, | |||
{HM2056_8BIT, 0x0543, 0xBC}, //50Hz Flicker | |||
{HM2056_8BIT, 0x05E4, 0x00}, //Windowing | |||
{HM2056_8BIT, 0x05E5, 0x00}, | |||
{HM2056_8BIT, 0x05E6, 0x53}, | |||
{HM2056_8BIT, 0x05E7, 0x06}, | |||
{HM2056_8BIT, 0x0698, 0x00}, | |||
{HM2056_8BIT, 0x0699, 0x00}, | |||
{HM2056_8BIT, 0x0B20, 0xAE}, //Set clock lane is on at sending packet, Patrick: 0xAE | |||
{HM2056_8BIT, 0x0078, 0x80}, //Set clock lane is on at sending packet, Patrick: new setting | |||
{HM2056_8BIT, 0x007C, 0x09}, //pre-hsync setting, Patrick: 0x09 | |||
{HM2056_8BIT, 0x007D, 0x3E}, //pre-vsync setting | |||
{HM2056_8BIT, 0x0B02, 0x01}, // TLPX WIDTH, Add by Wilson, 20111114 | |||
{HM2056_8BIT, 0x0B03, 0x03}, | |||
{HM2056_8BIT, 0x0B04, 0x01}, | |||
{HM2056_8BIT, 0x0B05, 0x08}, | |||
{HM2056_8BIT, 0x0B06, 0x02}, | |||
{HM2056_8BIT, 0x0B07, 0x28}, //MARK1 WIDTH | |||
{HM2056_8BIT, 0x0B0E, 0x0B}, //CLK FRONT PORCH WIDTH | |||
{HM2056_8BIT, 0x0B0F, 0x04}, //CLK BACK PORCH WIDTH | |||
{HM2056_8BIT, 0x0B22, 0x02}, //HS_EXIT Eanble | |||
{HM2056_8BIT, 0x0B39, 0x03}, //Clock Lane HS_EXIT WIDTH(at least 100ns) | |||
{HM2056_8BIT, 0x0B11, 0x7F}, //Clock Lane LP Driving Strength | |||
{HM2056_8BIT, 0x0B12, 0x7F}, //Data Lane LP Driving Strength | |||
{HM2056_8BIT, 0x0B17, 0xE0}, //D-PHY Power Down Control | |||
{HM2056_8BIT, 0x0B22, 0x02}, | |||
{HM2056_8BIT, 0x0B30, 0x0F}, //D-PHY Reset, set to 1 for normal operation | |||
{HM2056_8BIT, 0x0B31, 0x02}, //[1]: PHASE_SEL = 1 First Data at rising edge | |||
{HM2056_8BIT, 0x0B32, 0x00}, //[4]: DBG_ULPM | |||
{HM2056_8BIT, 0x0B33, 0x00}, //DBG_SEL | |||
{HM2056_8BIT, 0x0B35, 0x00}, | |||
{HM2056_8BIT, 0x0B36, 0x00}, | |||
{HM2056_8BIT, 0x0B37, 0x00}, | |||
{HM2056_8BIT, 0x0B38, 0x00}, | |||
{HM2056_8BIT, 0x0B39, 0x03}, | |||
{HM2056_8BIT, 0x0B3A, 0x00}, //CLK_HS_EXIT, Add by Wilson, 20111114 | |||
{HM2056_8BIT, 0x0B3B, 0x12}, //Turn on PHY LDO | |||
{HM2056_8BIT, 0x0B3F, 0x01}, //MIPI reg delay, Add by Wilson, 20111114 | |||
{HM2056_8BIT, 0x0024, 0x40}, //[6]: MIPI Enable | |||
{HM2056_TOK_TERM, 0, 0} | |||
}; | |||
static struct hm2056_reg const hm2056_uxga_14fps[] = { | |||
{HM2056_8BIT, 0x0024, 0x00}, | |||
{HM2056_8BIT, 0x0006, 0x00}, | |||
{HM2056_8BIT, 0x000D, 0x00}, | |||
{HM2056_8BIT, 0x000E, 0x00}, | |||
{HM2056_8BIT, 0x0010, 0x00}, | |||
{HM2056_8BIT, 0x0011, 0x8A}, | |||
{HM2056_8BIT, 0x0012, 0x04}, | |||
{HM2056_8BIT, 0x0013, 0x00}, | |||
{HM2056_8BIT, 0x002A, 0x2F}, | |||
{HM2056_8BIT, 0x0071, 0xAB}, | |||
{HM2056_8BIT, 0x0074, 0x13}, | |||
{HM2056_8BIT, 0x0082, 0xE2}, | |||
{HM2056_8BIT, 0x0131, 0xB8}, | |||
{HM2056_8BIT, 0x0144, 0x06}, | |||
{HM2056_8BIT, 0x0190, 0x80}, | |||
{HM2056_8BIT, 0x0192, 0x48}, | |||
{HM2056_8BIT, 0x05E6, 0x53}, | |||
{HM2056_8BIT, 0x05E7, 0x06}, | |||
{HM2056_8BIT, 0x05EA, 0xC3}, | |||
{HM2056_8BIT, 0x05EB, 0x04}, | |||
{HM2056_8BIT, 0x0024, 0x40}, | |||
{HM2056_TOK_DELAY, 0, 80}, // Delay longer than 1 frame time ~71ms | |||
{HM2056_TOK_TERM, 0, 0} | |||
}; | |||
static struct hm2056_reg const hm2056_uxga_16_9_18fps[] = { | |||
{HM2056_8BIT, 0x0024, 0x00}, | |||
{HM2056_8BIT, 0x0006, 0x14}, | |||
{HM2056_8BIT, 0x000D, 0x00}, | |||
{HM2056_8BIT, 0x000E, 0x00}, | |||
{HM2056_8BIT, 0x0010, 0x00}, | |||
{HM2056_8BIT, 0x0011, 0x8A}, | |||
{HM2056_8BIT, 0x0012, 0x04}, | |||
{HM2056_8BIT, 0x0013, 0x00}, | |||
{HM2056_8BIT, 0x002A, 0x2F}, | |||
{HM2056_8BIT, 0x0071, 0xAB}, | |||
{HM2056_8BIT, 0x0074, 0x13}, | |||
{HM2056_8BIT, 0x0082, 0xE2}, | |||
{HM2056_8BIT, 0x0131, 0xB8}, | |||
{HM2056_8BIT, 0x0144, 0x06}, | |||
{HM2056_8BIT, 0x0190, 0x80}, | |||
{HM2056_8BIT, 0x0192, 0x48}, | |||
{HM2056_8BIT, 0x05E6, 0x53}, | |||
{HM2056_8BIT, 0x05E7, 0x06}, | |||
{HM2056_8BIT, 0x05EA, 0x8F}, | |||
{HM2056_8BIT, 0x05EB, 0x03}, | |||
{HM2056_8BIT, 0x0024, 0x40}, | |||
{HM2056_TOK_DELAY, 0, 60}, // Delay longer than 1 frame time ~55ms | |||
{HM2056_TOK_TERM, 0, 0} | |||
}; | |||
/* | |||
* 1296x732 | |||
*/ | |||
static struct hm2056_reg const hm2056_720p_25fps[] = { | |||
{HM2056_8BIT, 0x0024, 0x00}, | |||
{HM2056_8BIT, 0x0006, 0x08}, // Flip/Mirror | |||
{HM2056_8BIT, 0x000D, 0x00}, // 20120220 to fix morie | |||
{HM2056_8BIT, 0x000E, 0x00}, // Binning ON | |||
{HM2056_8BIT, 0x0010, 0x00}, | |||
{HM2056_8BIT, 0x0011, 0xBE}, | |||
{HM2056_8BIT, 0x0012, 0x08}, //2012.02.08 | |||
{HM2056_8BIT, 0x0013, 0x00}, | |||
{HM2056_8BIT, 0x002A, 0x2F}, | |||
{HM2056_8BIT, 0x0071, 0x99}, | |||
{HM2056_8BIT, 0x0074, 0x13}, | |||
{HM2056_8BIT, 0x0082, 0xE2}, | |||
{HM2056_8BIT, 0x0131, 0xB8}, //simle bpc enable[4] | |||
{HM2056_8BIT, 0x0144, 0x04}, //Sort bpc hot pixel ratio | |||
{HM2056_8BIT, 0x0190, 0x87}, //A11 BPC Strength[7:3], cluster correct P11[0]P12[1]P13[2] | |||
{HM2056_8BIT, 0x0192, 0x50}, //A13 Strength[4:0],hot pixel detect for cluster[6] | |||
{HM2056_8BIT, 0x05E6, 0x0F}, | |||
{HM2056_8BIT, 0x05E7, 0x05}, | |||
{HM2056_8BIT, 0x05EA, 0xDB}, | |||
{HM2056_8BIT, 0x05EB, 0x02}, | |||
{HM2056_8BIT, 0x0024, 0x40}, | |||
{HM2056_TOK_DELAY, 0, 40}, //Delay longer than 1 frame time ~37ms | |||
{HM2056_TOK_TERM, 0, 0} | |||
}; | |||
/* | |||
* 810 x 626 | |||
*/ | |||
static struct hm2056_reg const hm2056_svga_30fps[] = { | |||
{HM2056_8BIT, 0x0024, 0x00}, | |||
{HM2056_8BIT, 0x0006, 0x00}, // Flip/Mirror | |||
{HM2056_8BIT, 0x000D, 0x11}, // 20120220 to fix morie | |||
{HM2056_8BIT, 0x000E, 0x11}, // Binning ON | |||
{HM2056_8BIT, 0x0010, 0x01}, | |||
{HM2056_8BIT, 0x0011, 0x3A}, | |||
{HM2056_8BIT, 0x0012, 0x1C}, //2012.02.08 | |||
{HM2056_8BIT, 0x0013, 0x01}, | |||
{HM2056_8BIT, 0x002A, 0x2C}, | |||
{HM2056_8BIT, 0x0071, 0xFF}, | |||
{HM2056_8BIT, 0x0074, 0x1B}, | |||
{HM2056_8BIT, 0x0082, 0xA2}, | |||
{HM2056_8BIT, 0x0131, 0xB8}, | |||
{HM2056_8BIT, 0x0144, 0x06}, | |||
{HM2056_8BIT, 0x0190, 0x80}, | |||
{HM2056_8BIT, 0x0192, 0x48}, | |||
{HM2056_8BIT, 0x05E6, 0x2B}, | |||
{HM2056_8BIT, 0x05E7, 0x03}, | |||
{HM2056_8BIT, 0x05EA, 0x71}, | |||
{HM2056_8BIT, 0x05EB, 0x02}, | |||
{HM2056_8BIT, 0x0024, 0x40}, | |||
{HM2056_TOK_DELAY, 0, 40}, // Delay longer than 1 frame time ~33ms | |||
{HM2056_TOK_TERM, 0, 0} | |||
}; | |||
/* | |||
* Modes supported by the hm2056_raw driver. | |||
* Please, keep them in ascending order. | |||
*/ | |||
static struct hm2056_raw_res_struct hm2056_raw_res_preview[] = { | |||
{ | |||
.desc = "hm2056_svga_30fps", | |||
.width = 812, | |||
.height = 626, | |||
.fps = 30, | |||
.used = 0, | |||
.regs = hm2056_svga_30fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 0, | |||
.horizontal_end = 1623, | |||
.vertical_start = 0, | |||
.vertical_end = 1251, | |||
.pixel_clk = 36000000, | |||
.line_length_pck = 1223, | |||
.frame_length_lines = 940, | |||
.bin_factor_x = 2, | |||
.bin_factor_y = 2, | |||
.bin_mode = 1, | |||
}, | |||
{ | |||
.desc = "hm2056_720p_25fps", | |||
.width = 1296, | |||
.height = 732, | |||
.fps = 27, | |||
.used = 0, | |||
.regs = hm2056_720p_25fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 162, | |||
.horizontal_end = 1457, | |||
.vertical_start = 244, | |||
.vertical_end = 975, | |||
.pixel_clk = 39000000, | |||
.line_length_pck = 1619, | |||
.frame_length_lines = 922, | |||
.bin_factor_x = 1, | |||
.bin_factor_y = 1, | |||
.bin_mode = 0, | |||
}, | |||
{ | |||
.desc = "hm2056_uxga_16_9_18fps", | |||
.width = 1620, | |||
.height = 912, | |||
.fps = 18, | |||
.used = 0, | |||
.regs = hm2056_uxga_16_9_18fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 0, | |||
.horizontal_end = 1619, | |||
.vertical_start = 0, | |||
.vertical_end = 911, | |||
.pixel_clk = 39000000, | |||
.line_length_pck = 1919, | |||
.frame_length_lines = 1050, | |||
.bin_factor_x = 1, | |||
.bin_factor_y = 1, | |||
.bin_mode = 0, | |||
}, | |||
{ | |||
.desc = "hm2056_UXGA_14fps", | |||
.width = 1620, | |||
.height = 1220, | |||
.fps = 14, | |||
.used = 0, | |||
.regs = hm2056_uxga_14fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 0, | |||
.horizontal_end = 1619, | |||
.vertical_start = 0, | |||
.vertical_end = 1219, | |||
.pixel_clk = 39000000, | |||
.line_length_pck = 1919, | |||
.frame_length_lines = 1358, | |||
.bin_factor_x = 1, | |||
.bin_factor_y = 1, | |||
.bin_mode = 0, | |||
}, | |||
}; | |||
#define N_RES_PREVIEW (ARRAY_SIZE(hm2056_raw_res_preview)) | |||
static struct hm2056_raw_res_struct hm2056_raw_res_still[] = { | |||
{ | |||
.desc = "hm2056_svga_30fps", | |||
.width = 812, | |||
.height = 626, | |||
.fps = 30, | |||
.used = 0, | |||
.regs = hm2056_svga_30fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 0, | |||
.horizontal_end = 1623, | |||
.vertical_start = 0, | |||
.vertical_end = 1251, | |||
.pixel_clk = 36000000, | |||
.line_length_pck = 1223, | |||
.frame_length_lines = 940, | |||
.bin_factor_x = 2, | |||
.bin_factor_y = 2, | |||
.bin_mode = 1, | |||
}, | |||
{ | |||
.desc = "hm2056_720p_25fps", | |||
.width = 1296, | |||
.height = 732, | |||
.fps = 27, | |||
.used = 0, | |||
.regs = hm2056_720p_25fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 162, | |||
.horizontal_end = 1457, | |||
.vertical_start = 244, | |||
.vertical_end = 975, | |||
.pixel_clk = 39000000, | |||
.line_length_pck = 1619, | |||
.frame_length_lines = 922, | |||
.bin_factor_x = 1, | |||
.bin_factor_y = 1, | |||
.bin_mode = 0, | |||
}, | |||
{ | |||
.desc = "hm2056_uxga_16_9_18fps", | |||
.width = 1620, | |||
.height = 912, | |||
.fps = 18, | |||
.used = 0, | |||
.regs = hm2056_uxga_16_9_18fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 0, | |||
.horizontal_end = 1619, | |||
.vertical_start = 0, | |||
.vertical_end = 911, | |||
.pixel_clk = 39000000, | |||
.line_length_pck = 1919, | |||
.frame_length_lines = 1050, | |||
.bin_factor_x = 1, | |||
.bin_factor_y = 1, | |||
.bin_mode = 0, | |||
}, | |||
{ | |||
.desc = "hm2056_uxga_14fps", | |||
.width = 1620, | |||
.height = 1220, | |||
.fps = 14, | |||
.used = 0, | |||
.regs = hm2056_uxga_14fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 0, | |||
.horizontal_end = 1619, | |||
.vertical_start = 0, | |||
.vertical_end = 1219, | |||
.pixel_clk = 39000000, | |||
.line_length_pck = 1919, | |||
.frame_length_lines = 1358, | |||
.bin_factor_x = 1, | |||
.bin_factor_y = 1, | |||
.bin_mode = 0, | |||
}, | |||
}; | |||
#define N_RES_STILL (ARRAY_SIZE(hm2056_raw_res_still)) | |||
static struct hm2056_raw_res_struct hm2056_raw_res_video[] = { | |||
{ | |||
.desc = "hm2056_svga_30fps", | |||
.width = 812, | |||
.height = 626, | |||
.fps = 30, | |||
.used = 0, | |||
.regs = hm2056_svga_30fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 0, | |||
.horizontal_end = 1619, | |||
.vertical_start = 0, | |||
.vertical_end = 1219, | |||
.pixel_clk = 36000000, | |||
.line_length_pck = 1223, | |||
.frame_length_lines = 940, | |||
.bin_factor_x = 2, | |||
.bin_factor_y = 2, | |||
.bin_mode = 1, | |||
}, | |||
{ | |||
.desc = "hm2056_720p_25fps", | |||
.width = 1296, | |||
.height = 732, | |||
.fps = 25, | |||
.used = 0, | |||
.regs = hm2056_720p_25fps, | |||
.skip_frames = 1, | |||
.horizontal_start = 162, | |||
.horizontal_end = 1457, | |||
.vertical_start = 244, | |||
.vertical_end = 975, | |||
.pixel_clk = 39000000, | |||
.line_length_pck = 1619, | |||
.frame_length_lines = 922, | |||
.bin_factor_x = 1, | |||
.bin_factor_y = 1, | |||
.bin_mode = 0, | |||
}, | |||
}; | |||
#define N_RES_VIDEO (ARRAY_SIZE(hm2056_raw_res_video)) | |||
#endif |
@@ -0,0 +1,9 @@ | |||
config VIDEO_IMX | |||
tristate "sony imx sensor support" | |||
depends on I2C && VIDEO_V4L2 && VIDEO_MSRLIST_HELPER | |||
---help--- | |||
This is a Video4Linux2 sensor-level driver for the Sony | |||
IMX RAW sensor. | |||
It currently depends on internal V4L2 extensions defined in | |||
atomisp driver. |
@@ -0,0 +1,8 @@ | |||
obj-$(CONFIG_VIDEO_IMX) += imx1x5.o | |||
imx1x5-objs := imx.o drv201.o ad5816g.o dw9714.o dw9719.o dw9718.o vcm.o otp.o otp_imx.o otp_brcc064_e2prom.o otp_e2prom.o | |||
ov8858_driver-objs := ../ov8858.o dw9718.o vcm.o | |||
obj-$(CONFIG_VIDEO_OV8858) += ov8858_driver.o | |||
ccflags-y += -Werror |
@@ -0,0 +1,228 @@ | |||
#include <linux/bitops.h> | |||
#include <linux/device.h> | |||
#include <linux/delay.h> | |||
#include <linux/errno.h> | |||
#include <linux/fs.h> | |||
#include <linux/gpio.h> | |||
#include <linux/init.h> | |||
#include <linux/i2c.h> | |||
#include <linux/io.h> | |||
#include <linux/kernel.h> | |||
#include <linux/mm.h> | |||
#include <linux/kmod.h> | |||
#include <linux/module.h> | |||
#include <linux/moduleparam.h> | |||
#include <linux/string.h> | |||
#include <linux/slab.h> | |||
#include <linux/types.h> | |||
#ifndef CONFIG_GMIN_INTEL_MID /* FIXME! for non-gmin*/ | |||
#include <media/v4l2-chip-ident.h> | |||
#endif | |||
#include <media/v4l2-device.h> | |||
#include "ad5816g.h" | |||
struct ad5816g_device ad5816g_dev; | |||
static int ad5816g_i2c_rd8(struct i2c_client *client, u8 reg, u8 *val) | |||
{ | |||
struct i2c_msg msg[2]; | |||
u8 buf[2]; | |||
buf[0] = reg; | |||
buf[1] = 0; | |||
msg[0].addr = AD5816G_VCM_ADDR; | |||
msg[0].flags = 0; | |||
msg[0].len = 1; | |||
msg[0].buf = &buf[0]; | |||
msg[1].addr = AD5816G_VCM_ADDR; | |||
msg[1].flags = I2C_M_RD; | |||
msg[1].len = 1; | |||
msg[1].buf = &buf[1]; | |||
*val = 0; | |||
if (i2c_transfer(client->adapter, msg, 2) != 2) | |||
return -EIO; | |||
*val = buf[1]; | |||
return 0; | |||
} | |||
static int ad5816g_i2c_wr8(struct i2c_client *client, u8 reg, u8 val) | |||
{ | |||
struct i2c_msg msg; | |||
u8 buf[2]; | |||
buf[0] = reg; | |||
buf[1] = val; | |||
msg.addr = AD5816G_VCM_ADDR; | |||
msg.flags = 0; | |||
msg.len = 2; | |||
msg.buf = &buf[0]; | |||
if (i2c_transfer(client->adapter, &msg, 1) != 1) | |||
return -EIO; | |||
return 0; | |||
} | |||
static int ad5816g_i2c_wr16(struct i2c_client *client, u8 reg, u16 val) | |||
{ | |||
struct i2c_msg msg; | |||
u8 buf[3]; | |||
buf[0] = reg; | |||
buf[1] = (u8)(val >> 8); | |||
buf[2] = (u8)(val & 0xff); | |||
msg.addr = AD5816G_VCM_ADDR; | |||
msg.flags = 0; | |||
msg.len = 3; | |||
msg.buf = &buf[0]; | |||
if (i2c_transfer(client->adapter, &msg, 1) != 1) | |||
return -EIO; | |||
return 0; | |||
} | |||
static int ad5816g_set_arc_mode(struct i2c_client *client) | |||
{ | |||
int ret; | |||
ret = ad5816g_i2c_wr8(client, AD5816G_CONTROL, AD5816G_ARC_EN); | |||
if (ret) | |||
return ret; | |||
ret = ad5816g_i2c_wr8(client, AD5816G_MODE, | |||
AD5816G_MODE_2_5M_SWITCH_CLOCK); | |||
if (ret) | |||
return ret; | |||
ret = ad5816g_i2c_wr8(client, AD5816G_VCM_FREQ, AD5816G_DEF_FREQ); | |||
return ret; | |||
} | |||
int ad5816g_vcm_power_up(struct v4l2_subdev *sd) | |||
{ | |||
struct i2c_client *client = v4l2_get_subdevdata(sd); | |||
int ret; | |||
u8 ad5816g_id; | |||
/* Enable power */ | |||
ret = ad5816g_dev.platform_data->power_ctrl(sd, 1); | |||
if (ret) | |||
return ret; | |||
/* waiting time AD5816G(vcm) - t1 + t2 | |||
* t1(1ms) -Time from VDD high to first i2c cmd | |||
* t2(100us) - exit power-down mode time | |||
*/ | |||
usleep_range(1100, 1100); | |||
/* Detect device */ | |||
ret = ad5816g_i2c_rd8(client, AD5816G_IC_INFO, &ad5816g_id); | |||
if (ret < 0) | |||
goto fail_powerdown; | |||
if (ad5816g_id != AD5816G_ID) { | |||
ret = -ENXIO; | |||
goto fail_powerdown; | |||
} | |||
ret = ad5816g_set_arc_mode(client); | |||
if (ret) | |||
return ret; | |||
/* set the VCM_THRESHOLD */ | |||
ret = ad5816g_i2c_wr8(client, AD5816G_VCM_THRESHOLD, | |||
AD5816G_DEF_THRESHOLD); | |||
return ret; | |||
fail_powerdown: | |||
ad5816g_dev.platform_data->power_ctrl(sd, 0); | |||
return ret; | |||
} | |||
int ad5816g_vcm_power_down(struct v4l2_subdev *sd) | |||
{ | |||
return ad5816g_dev.platform_data->power_ctrl(sd, 0); | |||
} | |||
int ad5816g_t_focus_vcm(struct v4l2_subdev *sd, u16 val) | |||
{ | |||
struct i2c_client *client = v4l2_get_subdevdata(sd); | |||
u16 data = val & VCM_CODE_MASK; | |||
return ad5816g_i2c_wr16(client, AD5816G_VCM_CODE_MSB, data); | |||
} | |||
int ad5816g_t_focus_abs(struct v4l2_subdev *sd, s32 value) | |||
{ | |||
int ret; | |||
value = clamp(value, 0, AD5816G_MAX_FOCUS_POS); | |||
ret = ad5816g_t_focus_vcm(sd, value); | |||
if (ret == 0) { | |||
ad5816g_dev.number_of_steps = value - ad5816g_dev.focus; | |||
ad5816g_dev.focus = value; | |||
getnstimeofday(&(ad5816g_dev.timestamp_t_focus_abs)); | |||
} | |||
return ret; | |||
} | |||
int ad5816g_t_focus_rel(struct v4l2_subdev *sd, s32 value) | |||
{ | |||
return ad5816g_t_focus_abs(sd, ad5816g_dev.focus + value); | |||
} | |||
int ad5816g_q_focus_status(struct v4l2_subdev *sd, s32 *value) | |||
{ | |||
u32 status = 0; | |||
struct timespec temptime; | |||
const struct timespec timedelay = { | |||
0, | |||
min_t(u32, abs(ad5816g_dev.number_of_steps) * DELAY_PER_STEP_NS, | |||
DELAY_MAX_PER_STEP_NS), | |||
}; | |||
ktime_get_ts(&temptime); | |||
temptime = timespec_sub(temptime, (ad5816g_dev.timestamp_t_focus_abs)); | |||
if (timespec_compare(&temptime, &timedelay) <= 0) { | |||
status |= ATOMISP_FOCUS_STATUS_MOVING; | |||
status |= ATOMISP_FOCUS_HP_IN_PROGRESS; | |||
} else { | |||
status |= ATOMISP_FOCUS_STATUS_ACCEPTS_NEW_MOVE; | |||
status |= ATOMISP_FOCUS_HP_COMPLETE; | |||
} | |||
*value = status; | |||
return 0; | |||
} | |||
int ad5816g_q_focus_abs(struct v4l2_subdev *sd, s32 *value) | |||
{ | |||
s32 val; | |||
ad5816g_q_focus_status(sd, &val); | |||
if (val & ATOMISP_FOCUS_STATUS_MOVING) | |||
*value = ad5816g_dev.focus - ad5816g_dev.number_of_steps; | |||
else | |||
*value = ad5816g_dev.focus ; | |||
return 0; | |||
} | |||
int ad5816g_t_vcm_slew(struct v4l2_subdev *sd, s32 value) | |||
{ | |||
return 0; | |||
} | |||
int ad5816g_t_vcm_timing(struct v4l2_subdev *sd, s32 value) | |||
{ | |||
return 0; | |||
} | |||
int ad5816g_vcm_init(struct v4l2_subdev *sd) | |||
{ | |||
ad5816g_dev.platform_data = camera_get_af_platform_data(); | |||
return (NULL == ad5816g_dev.platform_data) ? -ENODEV : 0; | |||
} | |||
@@ -0,0 +1,49 @@ | |||
#ifndef __AD5816G_H__ | |||
#define __AD5816G_H__ | |||
#include <linux/atomisp_platform.h> | |||
#include <linux/types.h> | |||
#include <linux/time.h> | |||
#define AD5816G_VCM_ADDR 0x0e | |||
/* ad5816g device structure */ | |||
struct ad5816g_device { | |||
const struct camera_af_platform_data *platform_data; | |||
struct timespec timestamp_t_focus_abs; | |||
struct timespec focus_time; /* Time when focus was last time set */ | |||
s32 focus; /* Current focus value */ | |||
s16 number_of_steps; | |||
}; | |||
#define AD5816G_INVALID_CONFIG 0xffffffff | |||
#define AD5816G_MAX_FOCUS_POS 1023 | |||
#define DELAY_PER_STEP_NS 1000000 | |||