Merge "arm/dt: msm8974: Add PM8941 clkdiv devices" into msm-3.4
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 40995bb..722b8ea 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -16,7 +16,7 @@
#include <asm/mach-types.h>
-#include <mach/board.h>
+#include <mach/camera.h>
#include <mach/msm_bus_board.h>
#include <mach/gpiomux.h>
@@ -369,20 +369,13 @@
},
};
-static struct camera_vreg_t apq_8064_back_cam_vreg[] = {
+static struct camera_vreg_t apq_8064_cam_vreg[] = {
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
{"cam_vio", REG_VS, 0, 0, 0},
{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
};
-static struct camera_vreg_t apq_8064_front_cam_vreg[] = {
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
-};
-
#define CAML_RSTN PM8921_GPIO_PM_TO_SYS(28)
#define CAMR_RSTN 34
@@ -482,8 +475,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
.mount_angle = 90,
- .cam_vreg = apq_8064_back_cam_vreg,
- .num_vreg = ARRAY_SIZE(apq_8064_back_cam_vreg),
+ .cam_vreg = apq_8064_cam_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_cam_vreg),
.gpio_conf = &apq8064_back_cam_gpio_conf,
.i2c_conf = &apq8064_back_cam_i2c_conf,
.csi_lane_params = &imx074_csi_lane_params,
@@ -515,21 +508,14 @@
.csi_lane_mask = 0xF,
};
-static struct camera_vreg_t apq_8064_imx091_vreg[] = {
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vio", REG_VS, 0, 0, 0},
-};
-
static struct msm_camera_sensor_flash_data flash_imx091 = {
.flash_type = MSM_CAMERA_FLASH_NONE,
};
static struct msm_camera_sensor_platform_info sensor_board_info_imx091 = {
.mount_angle = 0,
- .cam_vreg = apq_8064_imx091_vreg,
- .num_vreg = ARRAY_SIZE(apq_8064_imx091_vreg),
+ .cam_vreg = apq_8064_cam_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_cam_vreg),
.gpio_conf = &apq8064_back_cam_gpio_conf,
.i2c_conf = &apq8064_back_cam_i2c_conf,
.csi_lane_params = &imx091_csi_lane_params,
@@ -556,13 +542,6 @@
.eeprom_info = &imx091_eeprom_info,
};
-static struct camera_vreg_t apq_8064_s5k3l1yx_vreg[] = {
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
-};
-
static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
.flash_type = MSM_CAMERA_FLASH_NONE,
};
@@ -574,8 +553,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
.mount_angle = 90,
- .cam_vreg = apq_8064_s5k3l1yx_vreg,
- .num_vreg = ARRAY_SIZE(apq_8064_s5k3l1yx_vreg),
+ .cam_vreg = apq_8064_cam_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_cam_vreg),
.gpio_conf = &apq8064_back_cam_gpio_conf,
.i2c_conf = &apq8064_back_cam_i2c_conf,
.csi_lane_params = &s5k3l1yx_csi_lane_params,
@@ -591,13 +570,6 @@
.sensor_type = BAYER_SENSOR,
};
-static struct camera_vreg_t apq_8064_mt9m114_vreg[] = {
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
-};
-
static struct msm_camera_sensor_flash_data flash_mt9m114 = {
.flash_type = MSM_CAMERA_FLASH_NONE
};
@@ -609,8 +581,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
.mount_angle = 90,
- .cam_vreg = apq_8064_mt9m114_vreg,
- .num_vreg = ARRAY_SIZE(apq_8064_mt9m114_vreg),
+ .cam_vreg = apq_8064_cam_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_cam_vreg),
.gpio_conf = &apq8064_front_cam_gpio_conf,
.i2c_conf = &apq8064_front_cam_i2c_conf,
.csi_lane_params = &mt9m114_csi_lane_params,
@@ -637,8 +609,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
.mount_angle = 0,
- .cam_vreg = apq_8064_front_cam_vreg,
- .num_vreg = ARRAY_SIZE(apq_8064_front_cam_vreg),
+ .cam_vreg = apq_8064_cam_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_cam_vreg),
.gpio_conf = &apq8064_front_cam_gpio_conf,
.i2c_conf = &apq8064_front_cam_i2c_conf,
.csi_lane_params = &ov2720_csi_lane_params,
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index d3e37cd..1352928 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -13,7 +13,7 @@
#include <asm/mach-types.h>
#include <linux/gpio.h>
-#include <mach/board.h>
+#include <mach/camera.h>
#include <mach/msm_bus_board.h>
#include <mach/gpiomux.h>
#include "devices.h"
@@ -377,19 +377,13 @@
},
};
-static struct camera_vreg_t msm_8930_back_cam_vreg[] = {
+static struct camera_vreg_t msm_8930_cam_vreg[] = {
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
{"cam_vio", REG_VS, 0, 0, 0},
{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
};
-static struct camera_vreg_t msm_8930_front_cam_vreg[] = {
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
-};
-
static struct gpio msm8930_common_cam_gpio[] = {
{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
{21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
@@ -466,8 +460,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
.mount_angle = 90,
- .cam_vreg = msm_8930_back_cam_vreg,
- .num_vreg = ARRAY_SIZE(msm_8930_back_cam_vreg),
+ .cam_vreg = msm_8930_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_cam_vreg),
.gpio_conf = &msm_8930_back_cam_gpio_conf,
.csi_lane_params = &imx074_csi_lane_params,
};
@@ -484,13 +478,6 @@
.actuator_info = &msm_act_main_cam_0_info,
};
-static struct camera_vreg_t msm_8930_mt9m114_vreg[] = {
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
-};
-
static struct msm_camera_sensor_flash_data flash_mt9m114 = {
.flash_type = MSM_CAMERA_FLASH_NONE
};
@@ -502,8 +489,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
.mount_angle = 90,
- .cam_vreg = msm_8930_mt9m114_vreg,
- .num_vreg = ARRAY_SIZE(msm_8930_mt9m114_vreg),
+ .cam_vreg = msm_8930_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_cam_vreg),
.gpio_conf = &msm_8930_front_cam_gpio_conf,
.csi_lane_params = &mt9m114_csi_lane_params,
};
@@ -529,8 +516,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
.mount_angle = 0,
- .cam_vreg = msm_8930_front_cam_vreg,
- .num_vreg = ARRAY_SIZE(msm_8930_front_cam_vreg),
+ .cam_vreg = msm_8930_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_cam_vreg),
.gpio_conf = &msm_8930_front_cam_gpio_conf,
.csi_lane_params = &ov2720_csi_lane_params,
};
@@ -545,13 +532,6 @@
.sensor_type = BAYER_SENSOR,
};
-static struct camera_vreg_t msm_8930_s5k3l1yx_vreg[] = {
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
-};
-
static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
.flash_type = MSM_CAMERA_FLASH_LED,
.flash_src = &msm_flash_src
@@ -564,8 +544,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
.mount_angle = 90,
- .cam_vreg = msm_8930_s5k3l1yx_vreg,
- .num_vreg = ARRAY_SIZE(msm_8930_s5k3l1yx_vreg),
+ .cam_vreg = msm_8930_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_cam_vreg),
.gpio_conf = &msm_8930_back_cam_gpio_conf,
.csi_lane_params = &s5k3l1yx_csi_lane_params,
};
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index a21c4c3..c00535b 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -13,7 +13,7 @@
#include <asm/mach-types.h>
#include <linux/gpio.h>
-#include <mach/board.h>
+#include <mach/camera.h>
#include <mach/msm_bus_board.h>
#include <mach/gpiomux.h>
#include "devices.h"
@@ -452,19 +452,13 @@
},
};
-static struct camera_vreg_t msm_8960_back_cam_vreg[] = {
+static struct camera_vreg_t msm_8960_cam_vreg[] = {
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
{"cam_vio", REG_VS, 0, 0, 0},
{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
};
-static struct camera_vreg_t msm_8960_front_cam_vreg[] = {
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
-};
-
static struct gpio msm8960_common_cam_gpio[] = {
{5, GPIOF_DIR_IN, "CAMIF_MCLK"},
{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
@@ -549,8 +543,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
.mount_angle = 90,
- .cam_vreg = msm_8960_back_cam_vreg,
- .num_vreg = ARRAY_SIZE(msm_8960_back_cam_vreg),
+ .cam_vreg = msm_8960_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_cam_vreg),
.gpio_conf = &msm_8960_back_cam_gpio_conf,
.csi_lane_params = &imx074_csi_lane_params,
};
@@ -577,13 +571,6 @@
.eeprom_info = &imx074_eeprom_info,
};
-static struct camera_vreg_t msm_8960_mt9m114_vreg[] = {
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
-};
-
static struct msm_camera_sensor_flash_data flash_mt9m114 = {
.flash_type = MSM_CAMERA_FLASH_NONE
};
@@ -593,10 +580,16 @@
.csi_lane_mask = 0x1,
};
+static struct camera_vreg_t mt9m114_cam_vreg[] = {
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000, 50},
+ {"cam_vio", REG_VS, 0, 0, 0, 50},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600, 50},
+};
+
static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
.mount_angle = 90,
- .cam_vreg = msm_8960_mt9m114_vreg,
- .num_vreg = ARRAY_SIZE(msm_8960_mt9m114_vreg),
+ .cam_vreg = mt9m114_cam_vreg,
+ .num_vreg = ARRAY_SIZE(mt9m114_cam_vreg),
.gpio_conf = &msm_8960_front_cam_gpio_conf,
.csi_lane_params = &mt9m114_csi_lane_params,
};
@@ -622,8 +615,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
.mount_angle = 0,
- .cam_vreg = msm_8960_front_cam_vreg,
- .num_vreg = ARRAY_SIZE(msm_8960_front_cam_vreg),
+ .cam_vreg = msm_8960_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_cam_vreg),
.gpio_conf = &msm_8960_front_cam_gpio_conf,
.csi_lane_params = &ov2720_csi_lane_params,
};
@@ -638,13 +631,6 @@
.sensor_type = BAYER_SENSOR,
};
-static struct camera_vreg_t msm_8960_s5k3l1yx_vreg[] = {
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vio", REG_VS, 0, 0, 0},
- {"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
-};
-
static struct msm_camera_sensor_flash_data flash_s5k3l1yx = {
.flash_type = MSM_CAMERA_FLASH_NONE,
};
@@ -656,8 +642,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_s5k3l1yx = {
.mount_angle = 0,
- .cam_vreg = msm_8960_s5k3l1yx_vreg,
- .num_vreg = ARRAY_SIZE(msm_8960_s5k3l1yx_vreg),
+ .cam_vreg = msm_8960_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_cam_vreg),
.gpio_conf = &msm_8960_back_cam_gpio_conf,
.csi_lane_params = &s5k3l1yx_csi_lane_params,
};
@@ -686,13 +672,6 @@
.csi_lane_mask = 0xF,
};
-static struct camera_vreg_t msm_8960_imx091_vreg[] = {
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
- {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
- {"cam_vio", REG_VS, 0, 0, 0},
-};
-
static struct msm_camera_sensor_flash_data flash_imx091 = {
.flash_type = MSM_CAMERA_FLASH_LED,
#ifdef CONFIG_MSM_CAMERA_FLASH
@@ -702,8 +681,8 @@
static struct msm_camera_sensor_platform_info sensor_board_info_imx091 = {
.mount_angle = 0,
- .cam_vreg = msm_8960_imx091_vreg,
- .num_vreg = ARRAY_SIZE(msm_8960_imx091_vreg),
+ .cam_vreg = msm_8960_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_cam_vreg),
.gpio_conf = &msm_8960_back_cam_gpio_conf,
.csi_lane_params = &imx091_csi_lane_params,
};
@@ -715,6 +694,9 @@
static struct msm_eeprom_info imx091_eeprom_info = {
.board_info = &imx091_eeprom_i2c_info,
.bus_id = MSM_8960_GSBI4_QUP_I2C_BUS_ID,
+ .eeprom_i2c_slave_addr = 0xA1,
+ .eeprom_reg_addr = 0x05,
+ .eeprom_read_length = 6,
};
static struct msm_camera_sensor_info msm_camera_sensor_imx091_data = {
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 1e198a7..59b3162 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -19,7 +19,7 @@
#include <linux/module.h>
#include <asm/mach-types.h>
#include <mach/msm_iomap.h>
-#include <mach/board.h>
+#include <mach/camera.h>
#include <mach/irqs-7xxx.h>
#include "devices-msm7x2xa.h"
#include "board-msm7627a.h"
diff --git a/arch/arm/mach-msm/board-msm8x60-camera.c b/arch/arm/mach-msm/board-msm8x60-camera.c
index cd95630..acd7f74 100644
--- a/arch/arm/mach-msm/board-msm8x60-camera.c
+++ b/arch/arm/mach-msm/board-msm8x60-camera.c
@@ -15,7 +15,7 @@
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/mfd/pmic8901.h>
-#include <mach/board.h>
+#include <mach/camera.h>
#include <mach/board-msm8660.h>
#include <mach/gpiomux.h>
#include <mach/msm_bus_board.h>
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 6fa45c6..7556931 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -132,12 +132,12 @@
#define MSM_PMEM_MDP_SIZE 0x1B00000
#define MSM_PMEM_ADSP_SIZE 0x1200000
-#define MSM_ION_AUDIO_SIZE (MSM_PMEM_AUDIO_SIZE + PMEM_KERNEL_EBI1_SIZE)
-#define MSM_ION_CAMERA_SIZE MSM_PMEM_ADSP_SIZE
-#define MSM_ION_SF_SIZE MSM_PMEM_MDP_SIZE
-#define MSM_ION_HEAP_NUM 4
#ifdef CONFIG_ION_MSM
+#define MSM_ION_HEAP_NUM 4
static struct platform_device ion_dev;
+static int msm_ion_camera_size;
+static int msm_ion_audio_size;
+static int msm_ion_sf_size;
#endif
#endif
@@ -759,6 +759,15 @@
}
early_param("pmem_audio_size", pmem_audio_size_setup);
+static void fix_sizes(void)
+{
+#ifdef CONFIG_ION_MSM
+ msm_ion_camera_size = pmem_adsp_size;
+ msm_ion_audio_size = (MSM_PMEM_AUDIO_SIZE + PMEM_KERNEL_EBI1_SIZE);
+ msm_ion_sf_size = pmem_mdp_size;
+#endif
+}
+
#ifdef CONFIG_ION_MSM
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
static struct ion_co_heap_pdata co_ion_pdata = {
@@ -786,7 +795,6 @@
.id = ION_CAMERA_HEAP_ID,
.type = ION_HEAP_TYPE_CARVEOUT,
.name = ION_CAMERA_HEAP_NAME,
- .size = MSM_ION_CAMERA_SIZE,
.memory_type = ION_EBI_TYPE,
.extra_data = (void *)&co_ion_pdata,
},
@@ -795,7 +803,6 @@
.id = ION_AUDIO_HEAP_ID,
.type = ION_HEAP_TYPE_CARVEOUT,
.name = ION_AUDIO_HEAP_NAME,
- .size = MSM_ION_AUDIO_SIZE,
.memory_type = ION_EBI_TYPE,
.extra_data = (void *)&co_ion_pdata,
},
@@ -804,7 +811,6 @@
.id = ION_SF_HEAP_ID,
.type = ION_HEAP_TYPE_CARVEOUT,
.name = ION_SF_HEAP_NAME,
- .size = MSM_ION_SF_SIZE,
.memory_type = ION_EBI_TYPE,
.extra_data = (void *)&co_ion_pdata,
},
@@ -873,19 +879,30 @@
#endif
}
+static void __init size_ion_devices(void)
+{
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ ion_pdata.heaps[1].size = msm_ion_camera_size;
+ ion_pdata.heaps[2].size = msm_ion_audio_size;
+ ion_pdata.heaps[3].size = msm_ion_sf_size;
+#endif
+}
+
static void __init reserve_ion_memory(void)
{
#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
- msm7627a_reserve_table[MEMTYPE_EBI1].size += MSM_ION_CAMERA_SIZE;
- msm7627a_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
- msm7627a_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+ msm7627a_reserve_table[MEMTYPE_EBI1].size += msm_ion_camera_size;
+ msm7627a_reserve_table[MEMTYPE_EBI1].size += msm_ion_audio_size;
+ msm7627a_reserve_table[MEMTYPE_EBI1].size += msm_ion_sf_size;
#endif
}
static void __init msm7627a_calculate_reserve_sizes(void)
{
+ fix_sizes();
size_pmem_devices();
reserve_pmem_memory();
+ size_ion_devices();
reserve_ion_memory();
}
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 93fd12d..5295cbc 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -905,8 +905,13 @@
if (cpu_is_msm8625()) {
kgsl_3d0_pdata.idle_timeout = HZ/5;
kgsl_3d0_pdata.strtstp_sleepwake = false;
- /* 8x25 supports a higher GPU frequency */
- kgsl_3d0_pdata.pwrlevel[0].gpu_freq = 320000000;
+
+ if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) >= 2)
+ /* 8x25 v2.0 & above supports a higher GPU frequency */
+ kgsl_3d0_pdata.pwrlevel[0].gpu_freq = 320000000;
+ else
+ kgsl_3d0_pdata.pwrlevel[0].gpu_freq = 300000000;
+
kgsl_3d0_pdata.pwrlevel[0].bus_freq = 200000000;
}
}
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index ab246a5..1060a9d 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -64,18 +64,6 @@
uint8_t is_vpe;
struct msm_bus_scale_pdata *cam_bus_scale_table;
};
-enum msm_camera_csi_data_format {
- CSI_8BIT,
- CSI_10BIT,
- CSI_12BIT,
-};
-struct msm_camera_csi_params {
- enum msm_camera_csi_data_format data_format;
- uint8_t lane_cnt;
- uint8_t lane_assign;
- uint8_t settle_cnt;
- uint8_t dpcm_scheme;
-};
#ifdef CONFIG_SENSORS_MT9T013
struct msm_camera_legacy_device_platform_data {
@@ -180,21 +168,6 @@
YUV_SENSOR,
};
-enum camera_vreg_type {
- REG_LDO,
- REG_VS,
- REG_GPIO,
- REG_MAX
-};
-
-struct camera_vreg_t {
- const char *reg_name;
- enum camera_vreg_type type;
- int min_voltage;
- int max_voltage;
- int op_mode;
-};
-
struct msm_gpio_set_tbl {
unsigned gpio;
unsigned long flags;
@@ -234,6 +207,13 @@
enum msm_camera_i2c_mux_mode i2c_mux_mode;
};
+enum msm_camera_vreg_name_t {
+ CAM_VDIG,
+ CAM_VIO,
+ CAM_VANA,
+ CAM_VAF,
+};
+
struct msm_camera_sensor_platform_info {
int mount_angle;
int sensor_reset;
@@ -268,6 +248,9 @@
struct msm_eeprom_info {
struct i2c_board_info const *board_info;
int bus_id;
+ int eeprom_reg_addr;
+ int eeprom_read_length;
+ int eeprom_i2c_slave_addr;
};
struct msm_camera_sensor_info {
@@ -285,7 +268,6 @@
uint8_t num_resources;
struct msm_camera_sensor_flash_data *flash_data;
int csi_if;
- struct msm_camera_csi_params csi_params;
struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
char *eeprom_data;
enum msm_camera_type camera_type;
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index a51a6b5..0511225 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -127,30 +127,6 @@
uint32_t frame_id;
};
-struct msm_camera_csid_lut_params {
- uint8_t num_cid;
- struct msm_camera_csid_vc_cfg *vc_cfg;
-};
-
-struct msm_camera_csid_params {
- uint8_t lane_cnt;
- uint16_t lane_assign;
- uint8_t phy_sel;
- struct msm_camera_csid_lut_params lut_params;
-};
-
-struct msm_camera_csiphy_params {
- uint8_t lane_cnt;
- uint8_t settle_cnt;
- uint16_t lane_mask;
- uint8_t combo_mode;
-};
-
-struct msm_camera_csi2_params {
- struct msm_camera_csid_params csid_params;
- struct msm_camera_csiphy_params csiphy_params;
-};
-
#ifndef CONFIG_MSM_CAMERA_V4L2
#define VFE31_OUTPUT_MODE_PT (0x1 << 0)
#define VFE31_OUTPUT_MODE_S (0x1 << 1)
@@ -332,34 +308,6 @@
uint16_t i2c_queue;
};
-enum msm_camera_i2c_reg_addr_type {
- MSM_CAMERA_I2C_BYTE_ADDR = 1,
- MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-enum msm_camera_i2c_data_type {
- MSM_CAMERA_I2C_BYTE_DATA = 1,
- MSM_CAMERA_I2C_WORD_DATA,
- MSM_CAMERA_I2C_SET_BYTE_MASK,
- MSM_CAMERA_I2C_UNSET_BYTE_MASK,
- MSM_CAMERA_I2C_SET_WORD_MASK,
- MSM_CAMERA_I2C_UNSET_WORD_MASK,
- MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA,
-};
-
-enum msm_camera_i2c_cmd_type {
- MSM_CAMERA_I2C_CMD_WRITE,
- MSM_CAMERA_I2C_CMD_POLL,
-};
-
-struct msm_camera_i2c_reg_conf {
- uint16_t reg_addr;
- uint16_t reg_data;
- enum msm_camera_i2c_data_type dt;
- enum msm_camera_i2c_cmd_type cmd_type;
- int16_t mask;
-};
-
struct msm_camera_cci_i2c_write_cfg {
struct msm_camera_i2c_reg_conf *reg_conf_tbl;
enum msm_camera_i2c_reg_addr_type addr_type;
@@ -406,6 +354,7 @@
atomic_t on_heap;
struct timespec ts;
uint32_t error_code;
+ uint32_t trans_code;
};
struct msm_device_queue {
@@ -673,11 +622,6 @@
S_EXIT
};
-struct msm_cam_clk_info {
- const char *clk_name;
- long clk_rate;
-};
-
int msm_camio_enable(struct platform_device *dev);
int msm_camio_vpe_clk_enable(uint32_t);
int msm_camio_vpe_clk_disable(void);
@@ -733,9 +677,11 @@
int msm_cam_core_reset(void);
int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
- int num_vreg, struct regulator **reg_ptr, int config);
+ int num_vreg, enum msm_camera_vreg_name_t *vreg_seq,
+ int num_vreg_seq, struct regulator **reg_ptr, int config);
int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
- int num_vreg, struct regulator **reg_ptr, int enable);
+ int num_vreg, enum msm_camera_vreg_name_t *vreg_seq,
+ int num_vreg_seq, struct regulator **reg_ptr, int enable);
int msm_camera_config_gpio_table
(struct msm_camera_sensor_info *sinfo, int gpio_en);
diff --git a/drivers/media/video/msm/csi/Makefile b/drivers/media/video/msm/csi/Makefile
index 547eb13..5aaaff7 100644
--- a/drivers/media/video/msm/csi/Makefile
+++ b/drivers/media/video/msm/csi/Makefile
@@ -1,5 +1,5 @@
GCC_VERSION := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-ccflags-y += -Idrivers/media/video/msm
+ccflags-y += -Idrivers/media/video/msm -Idrivers/media/video/msm/server
ifeq ($(CONFIG_MSM_CSI20_HEADER),y)
ccflags-y += -Idrivers/media/video/msm/csi/include/csi2.0
else ifeq ($(CONFIG_MSM_CSI30_HEADER),y)
diff --git a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
index c678ea2..ae842b2 100644
--- a/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi2.0/msm_ispif_hwreg.h
@@ -67,13 +67,19 @@
#define PIX_INTF_0_OVERFLOW_IRQ 12
#define RAW_INTF_0_OVERFLOW_IRQ 25
#define RAW_INTF_1_OVERFLOW_IRQ 25
+#define RAW_INTF_2_OVERFLOW_IRQ 12
#define RESET_DONE_IRQ 27
-#define ISPIF_IRQ_STATUS_MASK 0xA493249
-#define ISPIF_IRQ_1_STATUS_MASK 0xA493249
-#define ISPIF_IRQ_STATUS_RDI_SOF_MASK 0x492000
-#define ISPIF_IRQ_STATUS_PIX_SOF_MASK 0x249
-#define ISPIF_IRQ_STATUS_SOF_MASK 0x492249
+#define ISPIF_IRQ_STATUS_MASK 0x0A493249
+#define ISPIF_IRQ_STATUS_1_MASK 0x02493249
+#define ISPIF_IRQ_STATUS_2_MASK 0x00001249
+
+#define ISPIF_IRQ_STATUS_PIX_SOF_MASK 0x249
+#define ISPIF_IRQ_STATUS_RDI0_SOF_MASK 0x492000
+#define ISPIF_IRQ_STATUS_RDI1_SOF_MASK 0x492000
+#define ISPIF_IRQ_STATUS_RDI2_SOF_MASK 0x249
+
+#define ISPIF_IRQ_STATUS_SOF_MASK 0x492249
#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x1
#endif
diff --git a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
index 4b17538..5b13cc5 100644
--- a/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
+++ b/drivers/media/video/msm/csi/include/csi3.0/msm_ispif_hwreg.h
@@ -81,14 +81,19 @@
#define PIX_INTF_0_OVERFLOW_IRQ 12
#define RAW_INTF_0_OVERFLOW_IRQ 25
#define RAW_INTF_1_OVERFLOW_IRQ 25
+#define RAW_INTF_2_OVERFLOW_IRQ 12
#define RESET_DONE_IRQ 27
-#define ISPIF_IRQ_STATUS_MASK 0xA493249
-#define ISPIF_IRQ_1_STATUS_MASK 0xA493249
-#define ISPIF_IRQ_STATUS_RDI_SOF_MASK 0x492000
-#define ISPIF_IRQ_STATUS_PIX_SOF_MASK 0x249
-#define ISPIF_IRQ_STATUS_SOF_MASK 0x492249
-#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x1
+#define ISPIF_IRQ_STATUS_MASK 0x0A493249
+#define ISPIF_IRQ_STATUS_1_MASK 0x02493249
+#define ISPIF_IRQ_STATUS_2_MASK 0x00001249
+#define ISPIF_IRQ_STATUS_PIX_SOF_MASK 0x249
+#define ISPIF_IRQ_STATUS_RDI0_SOF_MASK 0x492000
+#define ISPIF_IRQ_STATUS_RDI1_SOF_MASK 0x492000
+#define ISPIF_IRQ_STATUS_RDI2_SOF_MASK 0x249
+
+#define ISPIF_IRQ_STATUS_SOF_MASK 0x492249
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x1
#endif
diff --git a/drivers/media/video/msm/csi/msm_csic.c b/drivers/media/video/msm/csi/msm_csic.c
index bcb7bb3..c34d9f7 100644
--- a/drivers/media/video/msm/csi/msm_csic.c
+++ b/drivers/media/video/msm/csi/msm_csic.c
@@ -137,18 +137,17 @@
#define MIPI_PWR_CNTL_EN 0x07
#define MIPI_PWR_CNTL_DIS 0x0
-static int msm_csic_config(struct csic_cfg_params *cfg_params)
+static int msm_csic_config(struct v4l2_subdev *sd,
+ struct msm_camera_csi_params *csic_params)
{
int rc = 0;
uint32_t val = 0;
struct csic_device *csic_dev;
- struct msm_camera_csi_params *csic_params;
void __iomem *csicbase;
int i;
- csic_dev = v4l2_get_subdevdata(cfg_params->subdev);
+ csic_dev = v4l2_get_subdevdata(sd);
csicbase = csic_dev->base;
- csic_params = cfg_params->parms;
/* Enable error correction for DATA lane. Applies to all data lanes */
msm_camera_io_w(0x4, csicbase + MIPI_PHY_CONTROL);
@@ -259,7 +258,7 @@
{"csi_pclk", -1},
};
-static int msm_csic_init(struct v4l2_subdev *sd, uint32_t *csic_version)
+static int msm_csic_init(struct v4l2_subdev *sd)
{
int rc = 0;
struct csic_device *csic_dev;
@@ -355,17 +354,40 @@
return 0;
}
+static long msm_csic_cmd(struct v4l2_subdev *sd, void *arg)
+{
+ long rc = 0;
+ struct csic_cfg_data cdata;
+ struct msm_camera_csi_params csic_params;
+ if (copy_from_user(&cdata,
+ (void *)arg,
+ sizeof(struct csic_cfg_data)))
+ return -EFAULT;
+ CDBG("%s cfgtype = %d\n", __func__, cdata.cfgtype);
+ switch (cdata.cfgtype) {
+ case CSIC_INIT:
+ rc = msm_csic_init(sd);
+ break;
+ case CSIC_CFG:
+ if (copy_from_user(&csic_params,
+ (void *)cdata.csic_params,
+ sizeof(struct msm_camera_csi_params)))
+ return -EFAULT;
+ rc = msm_csic_config(sd, &csic_params);
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
static long msm_csic_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
- struct csic_cfg_params cfg_params;
switch (cmd) {
case VIDIOC_MSM_CSIC_CFG:
- cfg_params.subdev = sd;
- cfg_params.parms = arg;
- return msm_csic_config((struct csic_cfg_params *)&cfg_params);
- case VIDIOC_MSM_CSIC_INIT:
- return msm_csic_init(sd, (uint32_t *)arg);
+ return msm_csic_cmd(sd, arg);
case VIDIOC_MSM_CSIC_RELEASE:
return msm_csic_release(sd);
default:
diff --git a/drivers/media/video/msm/csi/msm_csic.h b/drivers/media/video/msm/csi/msm_csic.h
index 177e9d1..c8f1f99 100644
--- a/drivers/media/video/msm/csi/msm_csic.h
+++ b/drivers/media/video/msm/csi/msm_csic.h
@@ -33,19 +33,10 @@
struct clk *csic_clk[5];
};
-struct csic_cfg_params {
- struct v4l2_subdev *subdev;
- void *parms;
-};
-
#define VIDIOC_MSM_CSIC_CFG \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csic_cfg_params)
-
-#define VIDIOC_MSM_CSIC_INIT \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csic_cfg_data*)
#define VIDIOC_MSM_CSIC_RELEASE \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct v4l2_subdev*)
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
#endif
-
diff --git a/drivers/media/video/msm/csi/msm_csid.c b/drivers/media/video/msm/csi/msm_csid.c
index 6ee87b7..8f6a98b 100644
--- a/drivers/media/video/msm/csi/msm_csid.c
+++ b/drivers/media/video/msm/csi/msm_csid.c
@@ -11,8 +11,6 @@
*/
#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <mach/board.h>
@@ -21,11 +19,15 @@
#include "msm_csid.h"
#include "msm_csid_hwreg.h"
#include "msm.h"
+#include "msm_cam_server.h"
#define V4L2_IDENT_CSID 50002
#define DBG_CSID 0
+#define TRUE 1
+#define FALSE 0
+
static int msm_csid_cid_lut(
struct msm_camera_csid_lut_params *csid_lut_params,
void __iomem *csidbase)
@@ -33,7 +35,17 @@
int rc = 0, i = 0;
uint32_t val = 0;
+ if (!csid_lut_params) {
+ pr_err("%s:%d csid_lut_params NULL\n", __func__, __LINE__);
+ return -EINVAL;
+ }
for (i = 0; i < csid_lut_params->num_cid && i < 16; i++) {
+ CDBG("%s lut params num_cid = %d, cid = %d, dt = %x, df = %d\n",
+ __func__,
+ csid_lut_params->num_cid,
+ csid_lut_params->vc_cfg[i].cid,
+ csid_lut_params->vc_cfg[i].dt,
+ csid_lut_params->vc_cfg[i].decode_format);
if (csid_lut_params->vc_cfg[i].dt < 0x12 ||
csid_lut_params->vc_cfg[i].dt > 0x37) {
CDBG("%s: unsupported data type 0x%x\n",
@@ -68,19 +80,23 @@
struct msm_camera_csid_params *csid_params) {}
#endif
-static int msm_csid_config(struct csid_cfg_params *cfg_params)
+static int msm_csid_config(struct csid_device *csid_dev,
+ struct msm_camera_csid_params *csid_params)
{
int rc = 0;
uint32_t val = 0;
- struct csid_device *csid_dev;
- struct msm_camera_csid_params *csid_params;
void __iomem *csidbase;
- csid_dev = v4l2_get_subdevdata(cfg_params->subdev);
csidbase = csid_dev->base;
- if (csidbase == NULL)
- return -ENOMEM;
- csid_params = cfg_params->parms;
+ if (!csidbase || !csid_params) {
+ pr_err("%s:%d csidbase %p, csid params %p\n", __func__,
+ __LINE__, csidbase, csid_params);
+ return -EINVAL;
+ }
+ CDBG("%s csid_params, lane_cnt = %d, lane_assign = %x\n",
+ __func__,
+ csid_params->lane_cnt,
+ csid_params->lane_assign);
val = csid_params->lane_cnt - 1;
val |= csid_params->lane_assign << CSID_DL_INPUT_SEL_SHIFT;
if (csid_dev->hw_version < 0x30000000) {
@@ -98,7 +114,6 @@
return rc;
msm_csid_set_debug_reg(csidbase, csid_params);
-
return rc;
}
@@ -106,6 +121,10 @@
{
uint32_t irq;
struct csid_device *csid_dev = data;
+ if (!csid_dev) {
+ pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
+ return IRQ_HANDLED;
+ }
irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
__func__, csid_dev->pdev->id, irq);
@@ -115,6 +134,16 @@
return IRQ_HANDLED;
}
+int msm_csid_irq_routine(struct v4l2_subdev *sd, u32 status, bool *handled)
+{
+ struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
+ irqreturn_t ret;
+ CDBG("%s E\n", __func__);
+ ret = msm_csid_irq(csid_dev->irq->start, csid_dev);
+ *handled = TRUE;
+ return 0;
+}
+
static void msm_csid_reset(struct csid_device *csid_dev)
{
msm_camera_io_w(CSID_RST_STB_ALL, csid_dev->base + CSID_RST_CMD_ADDR);
@@ -142,32 +171,32 @@
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
};
-static int msm_csid_init(struct v4l2_subdev *sd, uint32_t *csid_version)
+static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
{
int rc = 0;
- struct csid_device *csid_dev;
- csid_dev = v4l2_get_subdevdata(sd);
- if (csid_dev == NULL) {
- rc = -ENOMEM;
+
+ if (!csid_version) {
+ pr_err("%s:%d csid_version NULL\n", __func__, __LINE__);
+ rc = -EINVAL;
return rc;
}
-
csid_dev->base = ioremap(csid_dev->mem->start,
resource_size(csid_dev->mem));
if (!csid_dev->base) {
+ pr_err("%s csid_dev->base NULL\n", __func__);
rc = -ENOMEM;
return rc;
}
rc = msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info,
- ARRAY_SIZE(csid_vreg_info), &csid_dev->csi_vdd, 1);
+ ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1);
if (rc < 0) {
pr_err("%s: regulator on failed\n", __func__);
goto vreg_config_failed;
}
rc = msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info,
- ARRAY_SIZE(csid_vreg_info), &csid_dev->csi_vdd, 1);
+ ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1);
if (rc < 0) {
pr_err("%s: regulator enable failed\n", __func__);
goto vreg_enable_failed;
@@ -186,68 +215,126 @@
init_completion(&csid_dev->reset_complete);
- rc = request_irq(csid_dev->irq->start, msm_csid_irq,
- IRQF_TRIGGER_RISING, "csid", csid_dev);
+ enable_irq(csid_dev->irq->start);
msm_csid_reset(csid_dev);
return rc;
clk_enable_failed:
msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info,
- ARRAY_SIZE(csid_vreg_info), &csid_dev->csi_vdd, 0);
+ ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0);
vreg_enable_failed:
msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info,
- ARRAY_SIZE(csid_vreg_info), &csid_dev->csi_vdd, 0);
+ ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0);
vreg_config_failed:
iounmap(csid_dev->base);
csid_dev->base = NULL;
return rc;
}
-static int msm_csid_release(struct v4l2_subdev *sd)
+static int msm_csid_release(struct csid_device *csid_dev)
{
uint32_t irq;
- struct csid_device *csid_dev;
- csid_dev = v4l2_get_subdevdata(sd);
irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
msm_camera_io_w(0, csid_dev->base + CSID_IRQ_MASK_ADDR);
- free_irq(csid_dev->irq->start, csid_dev);
+ disable_irq(csid_dev->irq->start);
msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info,
csid_dev->csid_clk, ARRAY_SIZE(csid_clk_info), 0);
msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info,
- ARRAY_SIZE(csid_vreg_info), &csid_dev->csi_vdd, 0);
+ ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0);
msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info,
- ARRAY_SIZE(csid_vreg_info), &csid_dev->csi_vdd, 0);
+ ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0);
iounmap(csid_dev->base);
csid_dev->base = NULL;
return 0;
}
+static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
+{
+ int rc = 0;
+ struct csid_cfg_data cdata;
+
+ if (!csid_dev) {
+ pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&cdata,
+ (void *)arg,
+ sizeof(struct csid_cfg_data))) {
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ CDBG("%s cfgtype = %d\n", __func__, cdata.cfgtype);
+ switch (cdata.cfgtype) {
+ case CSID_INIT:
+ rc = msm_csid_init(csid_dev, &cdata.cfg.csid_version);
+ if (copy_to_user((void *)arg,
+ &cdata,
+ sizeof(struct csid_cfg_data))) {
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ }
+ break;
+ case CSID_CFG: {
+ struct msm_camera_csid_params csid_params;
+ struct msm_camera_csid_vc_cfg *vc_cfg = NULL;
+ if (copy_from_user(&csid_params,
+ (void *)cdata.cfg.csid_params,
+ sizeof(struct msm_camera_csid_params))) {
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+ vc_cfg = kzalloc(csid_params.lut_params.num_cid *
+ sizeof(struct msm_camera_csid_vc_cfg),
+ GFP_KERNEL);
+ if (!vc_cfg) {
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ rc = -ENOMEM;
+ break;
+ }
+ if (copy_from_user(vc_cfg,
+ (void *)csid_params.lut_params.vc_cfg,
+ (csid_params.lut_params.num_cid *
+ sizeof(struct msm_camera_csid_vc_cfg)))) {
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ kfree(vc_cfg);
+ rc = -EFAULT;
+ break;
+ }
+ csid_params.lut_params.vc_cfg = vc_cfg;
+ rc = msm_csid_config(csid_dev, &csid_params);
+ kfree(vc_cfg);
+ break;
+ }
+ default:
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+ return rc;
+}
+
static long msm_csid_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = -ENOIOCTLCMD;
- struct csid_cfg_params cfg_params;
struct csid_device *csid_dev = v4l2_get_subdevdata(sd);
mutex_lock(&csid_dev->mutex);
switch (cmd) {
case VIDIOC_MSM_CSID_CFG:
- cfg_params.subdev = sd;
- cfg_params.parms = arg;
- rc = msm_csid_config((struct csid_cfg_params *)&cfg_params);
- break;
- case VIDIOC_MSM_CSID_INIT:
- rc = msm_csid_init(sd, (uint32_t *)arg);
+ rc = msm_csid_cmd(csid_dev, arg);
break;
case VIDIOC_MSM_CSID_RELEASE:
- rc = msm_csid_release(sd);
+ rc = msm_csid_release(csid_dev);
break;
default:
pr_err("%s: command not found\n", __func__);
@@ -261,6 +348,7 @@
static struct v4l2_subdev_core_ops msm_csid_subdev_core_ops = {
.g_chip_ident = &msm_csid_subdev_g_chip_ident,
.ioctl = &msm_csid_subdev_ioctl,
+ .interrupt_service_routine = msm_csid_irq_routine,
};
static const struct v4l2_subdev_ops msm_csid_subdev_ops = {
@@ -271,9 +359,10 @@
{
struct csid_device *new_csid_dev;
struct msm_cam_subdev_info sd_info;
+ struct intr_table_entry irq_req;
int rc = 0;
- CDBG("%s: device id = %d\n", __func__, pdev->id);
+ CDBG("%s:%d called\n", __func__, __LINE__);
new_csid_dev = kzalloc(sizeof(struct csid_device), GFP_KERNEL);
if (!new_csid_dev) {
pr_err("%s: no enough memory\n", __func__);
@@ -293,6 +382,7 @@
of_property_read_u32((&pdev->dev)->of_node,
"cell-index", &pdev->id);
+ CDBG("%s device id %d\n", __func__, pdev->id);
new_csid_dev->mem = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "csid");
if (!new_csid_dev->mem) {
@@ -327,6 +417,44 @@
new_csid_dev->subdev.entity.name = pdev->name;
new_csid_dev->subdev.entity.revision =
new_csid_dev->subdev.devnode->num;
+
+ /* Request for this device irq from the camera server. If the
+ * IRQ Router is present on this target, the interrupt will be
+ * handled by the camera server and the interrupt service
+ * routine called. If the request_irq call returns ENXIO, then
+ * the IRQ Router hardware is not present on this target. We
+ * have to request for the irq ourselves and register the
+ * appropriate interrupt handler. */
+ irq_req.cam_hw_idx = MSM_CAM_HW_CSI0 + pdev->id;
+ irq_req.dev_name = "csid";
+ irq_req.irq_idx = CAMERA_SS_IRQ_2 + pdev->id;
+ irq_req.irq_num = new_csid_dev->irq->start;
+ irq_req.is_composite = 0;
+ irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
+ irq_req.num_hwcore = 1;
+ irq_req.subdev_list[0] = &new_csid_dev->subdev;
+ irq_req.data = (void *)new_csid_dev;
+ rc = msm_cam_server_request_irq(&irq_req);
+ if (rc == -ENXIO) {
+ /* IRQ Router hardware is not present on this hardware.
+ * Request for the IRQ and register the interrupt handler. */
+ rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
+ IRQF_TRIGGER_RISING, "csid", new_csid_dev);
+ if (rc < 0) {
+ release_mem_region(new_csid_dev->mem->start,
+ resource_size(new_csid_dev->mem));
+ pr_err("%s: irq request fail\n", __func__);
+ rc = -EBUSY;
+ goto csid_no_resource;
+ }
+ disable_irq(new_csid_dev->irq->start);
+ } else if (rc < 0) {
+ release_mem_region(new_csid_dev->mem->start,
+ resource_size(new_csid_dev->mem));
+ pr_err("%s Error registering irq ", __func__);
+ goto csid_no_resource;
+ }
+
return 0;
csid_no_resource:
diff --git a/drivers/media/video/msm/csi/msm_csid.h b/drivers/media/video/msm/csi/msm_csid.h
index 2eae49c..398acbc 100644
--- a/drivers/media/video/msm/csi/msm_csid.h
+++ b/drivers/media/video/msm/csi/msm_csid.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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 and
@@ -16,6 +16,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
struct csid_device {
struct platform_device *pdev;
@@ -32,19 +33,10 @@
struct clk *csid_clk[5];
};
-struct csid_cfg_params {
- struct v4l2_subdev *subdev;
- void *parms;
-};
-
#define VIDIOC_MSM_CSID_CFG \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csid_cfg_params)
-
-#define VIDIOC_MSM_CSID_INIT \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct csic_cfg_data*)
#define VIDIOC_MSM_CSID_RELEASE \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct v4l2_subdev*)
-
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct v4l2_subdev*)
#endif
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index bec7ae3..4e07b6a 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -16,7 +16,6 @@
#include <linux/of.h>
#include <linux/module.h>
#include <mach/board.h>
-#include <mach/camera.h>
#include <mach/vreg.h>
#include <media/msm_isp.h>
#include "msm_csiphy.h"
@@ -27,31 +26,35 @@
#define V4L2_IDENT_CSIPHY 50003
#define CSIPHY_VERSION_V3 0x10
-int msm_csiphy_config(struct csiphy_cfg_params *cfg_params)
+int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev,
+ struct msm_camera_csiphy_params *csiphy_params)
{
int rc = 0;
int j = 0;
uint32_t val = 0;
uint8_t lane_cnt = 0;
uint16_t lane_mask = 0;
- struct csiphy_device *csiphy_dev;
- struct msm_camera_csiphy_params *csiphy_params;
void __iomem *csiphybase;
- csiphy_dev = v4l2_get_subdevdata(cfg_params->subdev);
csiphybase = csiphy_dev->base;
- if (csiphybase == NULL)
- return -ENOMEM;
+ if (!csiphybase) {
+ pr_err("%s: csiphybase NULL\n", __func__);
+ return -EINVAL;
+ }
- csiphy_params = cfg_params->parms;
csiphy_dev->lane_mask[csiphy_dev->pdev->id] |= csiphy_params->lane_mask;
lane_mask = csiphy_dev->lane_mask[csiphy_dev->pdev->id];
lane_cnt = csiphy_params->lane_cnt;
if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) {
- CDBG("%s: unsupported lane cnt %d\n",
+ pr_err("%s: unsupported lane cnt %d\n",
__func__, csiphy_params->lane_cnt);
return rc;
}
+ CDBG("%s csiphy_params, mask = %x, cnt = %d, settle cnt = %x\n",
+ __func__,
+ csiphy_params->lane_mask,
+ csiphy_params->lane_cnt,
+ csiphy_params->settle_cnt);
msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR);
msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
@@ -92,7 +95,7 @@
j++;
lane_mask >>= 1;
}
-
+ msleep(20);
return rc;
}
@@ -138,12 +141,11 @@
{"csiphy_timer_clk", -1},
};
-static int msm_csiphy_init(struct v4l2_subdev *sd)
+static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
{
int rc = 0;
- struct csiphy_device *csiphy_dev;
- csiphy_dev = v4l2_get_subdevdata(sd);
if (csiphy_dev == NULL) {
+ pr_err("%s: csiphy_dev NULL\n", __func__);
rc = -ENOMEM;
return rc;
}
@@ -157,6 +159,7 @@
csiphy_dev->base = ioremap(csiphy_dev->mem->start,
resource_size(csiphy_dev->mem));
if (!csiphy_dev->base) {
+ pr_err("%s: csiphy_dev->base NULL\n", __func__);
csiphy_dev->ref_count--;
rc = -ENOMEM;
return rc;
@@ -166,6 +169,7 @@
csiphy_dev->csiphy_clk, ARRAY_SIZE(csiphy_clk_info), 1);
if (rc < 0) {
+ pr_err("%s: csiphy clk enable failed\n", __func__);
csiphy_dev->ref_count--;
iounmap(csiphy_dev->base);
csiphy_dev->base = NULL;
@@ -183,13 +187,11 @@
return 0;
}
-static int msm_csiphy_release(struct v4l2_subdev *sd, void *arg)
+static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
{
- struct csiphy_device *csiphy_dev;
int i = 0;
struct msm_camera_csi_lane_params *csi_lane_params;
uint16_t csi_lane_mask;
- csiphy_dev = v4l2_get_subdevdata(sd);
csi_lane_params = (struct msm_camera_csi_lane_params *)arg;
csi_lane_mask = csi_lane_params->csi_lane_mask;
@@ -197,6 +199,10 @@
pr_err("%s csiphy dev NULL / ref_count ZERO\n", __func__);
return 0;
}
+ CDBG("%s csiphy_params, lane assign %x mask = %x\n",
+ __func__,
+ csi_lane_params->csi_lane_assign,
+ csi_lane_params->csi_lane_mask);
if (csiphy_dev->hw_version != CSIPHY_VERSION_V3) {
csiphy_dev->lane_mask[csiphy_dev->pdev->id] = 0;
@@ -237,25 +243,55 @@
return 0;
}
+static long msm_csiphy_cmd(struct csiphy_device *csiphy_dev, void *arg)
+{
+ int rc = 0;
+ struct csiphy_cfg_data cdata;
+ struct msm_camera_csiphy_params csiphy_params;
+ if (!csiphy_dev) {
+ pr_err("%s: csiphy_dev NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (copy_from_user(&cdata,
+ (void *)arg,
+ sizeof(struct csiphy_cfg_data))) {
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ switch (cdata.cfgtype) {
+ case CSIPHY_INIT:
+ rc = msm_csiphy_init(csiphy_dev);
+ break;
+ case CSIPHY_CFG:
+ if (copy_from_user(&csiphy_params,
+ (void *)cdata.csiphy_params,
+ sizeof(struct msm_camera_csiphy_params))) {
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+ rc = msm_csiphy_lane_config(csiphy_dev, &csiphy_params);
+ break;
+ default:
+ pr_err("%s: %d failed\n", __func__, __LINE__);
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+ return rc;
+}
+
static long msm_csiphy_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = -ENOIOCTLCMD;
- struct csiphy_cfg_params cfg_params;
struct csiphy_device *csiphy_dev = v4l2_get_subdevdata(sd);
mutex_lock(&csiphy_dev->mutex);
switch (cmd) {
case VIDIOC_MSM_CSIPHY_CFG:
- cfg_params.subdev = sd;
- cfg_params.parms = arg;
- rc = msm_csiphy_config(
- (struct csiphy_cfg_params *)&cfg_params);
- break;
- case VIDIOC_MSM_CSIPHY_INIT:
- rc = msm_csiphy_init(sd);
+ rc = msm_csiphy_cmd(csiphy_dev, arg);
break;
case VIDIOC_MSM_CSIPHY_RELEASE:
- rc = msm_csiphy_release(sd, arg);
+ rc = msm_csiphy_release(csiphy_dev, arg);
break;
default:
pr_err("%s: command not found\n", __func__);
diff --git a/drivers/media/video/msm/csi/msm_csiphy.h b/drivers/media/video/msm/csi/msm_csiphy.h
index 1fab9c1..01eacb6 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.h
+++ b/drivers/media/video/msm/csi/msm_csiphy.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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 and
@@ -16,6 +16,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
#define MAX_CSIPHY 3
@@ -34,18 +35,9 @@
uint16_t lane_mask[MAX_CSIPHY];
};
-struct csiphy_cfg_params {
- struct v4l2_subdev *subdev;
- void *parms;
-};
-
#define VIDIOC_MSM_CSIPHY_CFG \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 7, void *)
-
-#define VIDIOC_MSM_CSIPHY_INIT \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct v4l2_subdev*)
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct csiphy_cfg_data*)
#define VIDIOC_MSM_CSIPHY_RELEASE \
_IOWR('V', BASE_VIDIOC_PRIVATE + 9, void *)
-
#endif
diff --git a/drivers/media/video/msm/csi/msm_ispif.c b/drivers/media/video/msm/csi/msm_ispif.c
index 092ee90..479fc028 100644
--- a/drivers/media/video/msm/csi/msm_ispif.c
+++ b/drivers/media/video/msm/csi/msm_ispif.c
@@ -29,6 +29,7 @@
static atomic_t ispif_irq_cnt;
static spinlock_t ispif_tasklet_lock;
+static spinlock_t ispif_sof_lock;
static struct list_head ispif_tasklet_q;
static int msm_ispif_intf_reset(struct ispif_device *ispif,
@@ -167,22 +168,27 @@
(0x200 * vfe_intf));
switch (intftype) {
case PIX0:
+ data &= ~(0x3);
data |= csid;
break;
case RDI0:
+ data &= ~(0x3 << 4);
data |= (csid << 4);
break;
case PIX1:
+ data &= ~(0x3 << 8);
data |= (csid << 8);
break;
case RDI1:
+ data &= ~(0x3 << 12);
data |= (csid << 12);
break;
case RDI2:
+ data &= ~(0x3 << 20);
data |= (csid << 20);
break;
}
@@ -289,6 +295,8 @@
ispif_params = params_list->params;
CDBG("Enable interface\n");
msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_ADDR);
+ msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_1_ADDR);
+ msm_camera_io_w(0x00000000, ispif->base + ISPIF_IRQ_MASK_2_ADDR);
for (i = 0; i < params_len; i++) {
intftype = ispif_params[i].intftype;
vfe_intf = ispif_params[i].vfe_intf;
@@ -319,6 +327,14 @@
ISPIF_IRQ_MASK_ADDR);
msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
ISPIF_IRQ_CLEAR_ADDR);
+ msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
+ ISPIF_IRQ_MASK_1_ADDR);
+ msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base +
+ ISPIF_IRQ_CLEAR_1_ADDR);
+ msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
+ ISPIF_IRQ_MASK_2_ADDR);
+ msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base +
+ ISPIF_IRQ_CLEAR_2_ADDR);
msm_camera_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
return rc;
@@ -534,13 +550,25 @@
return rc;
}
+static void send_rdi_sof(struct ispif_device *ispif,
+ enum msm_ispif_intftype interface, int count)
+{
+ struct rdi_count_msg sof_msg;
+ sof_msg.rdi_interface = interface;
+ sof_msg.count = count;
+ v4l2_subdev_notify(&ispif->subdev, NOTIFY_AXI_RDI_SOF_COUNT,
+ (void *)&sof_msg);
+}
+
static void ispif_do_tasklet(unsigned long data)
{
unsigned long flags;
struct ispif_isr_queue_cmd *qcmd = NULL;
+ struct ispif_device *ispif;
CDBG("=== ispif_do_tasklet start ===\n");
+ ispif = (struct ispif_device *)data;
while (atomic_read(&ispif_irq_cnt)) {
spin_lock_irqsave(&ispif_tasklet_lock, flags);
qcmd = list_first_entry(&ispif_tasklet_q,
@@ -555,21 +583,32 @@
list_del(&qcmd->list);
spin_unlock_irqrestore(&ispif_tasklet_lock,
flags);
+
+ spin_lock_irqsave(&ispif_sof_lock, flags);
if (qcmd->ispifInterruptStatus0 &
- ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
- CDBG("ispif rdi irq status\n");
+ ISPIF_IRQ_STATUS_RDI0_SOF_MASK) {
+ CDBG("%s: ispif RDI0 irq status", __func__);
+ ispif->rdi0_sof_count++;
+ send_rdi_sof(ispif, RDI_0, ispif->rdi0_sof_count);
}
if (qcmd->ispifInterruptStatus1 &
- ISPIF_IRQ_STATUS_RDI_SOF_MASK) {
- CDBG("ispif rdi1 irq status\n");
+ ISPIF_IRQ_STATUS_RDI1_SOF_MASK) {
+ CDBG("%s: ispif RDI1 irq status", __func__);
+ ispif->rdi1_sof_count++;
+ send_rdi_sof(ispif, RDI_1, ispif->rdi1_sof_count);
}
+ if (qcmd->ispifInterruptStatus2 &
+ ISPIF_IRQ_STATUS_RDI2_SOF_MASK) {
+ CDBG("%s: ispif RDI2 irq status", __func__);
+ ispif->rdi2_sof_count++;
+ send_rdi_sof(ispif, RDI_2, ispif->rdi2_sof_count);
+ }
+ spin_unlock_irqrestore(&ispif_sof_lock, flags);
kfree(qcmd);
}
CDBG("=== ispif_do_tasklet end ===\n");
}
-DECLARE_TASKLET(ispif_tasklet, ispif_do_tasklet, 0);
-
static void ispif_process_irq(struct ispif_device *ispif,
struct ispif_irq_status *out)
{
@@ -585,12 +624,14 @@
}
qcmd->ispifInterruptStatus0 = out->ispifIrqStatus0;
qcmd->ispifInterruptStatus1 = out->ispifIrqStatus1;
-
- if (qcmd->ispifInterruptStatus0 & ISPIF_IRQ_STATUS_PIX_SOF_MASK) {
- CDBG("%s: ispif PIX sof irq\n", __func__);
- ispif->pix_sof_count++;
- v4l2_subdev_notify(&ispif->subdev, NOTIFY_VFE_SOF_COUNT,
- (void *)&ispif->pix_sof_count);
+ qcmd->ispifInterruptStatus2 = out->ispifIrqStatus2;
+ if (qcmd->ispifInterruptStatus0 &
+ ISPIF_IRQ_STATUS_PIX_SOF_MASK) {
+ CDBG("%s: ispif PIX irq status", __func__);
+ ispif->pix_sof_count++;
+ v4l2_subdev_notify(&ispif->subdev,
+ NOTIFY_VFE_PIX_SOF_COUNT,
+ (void *)&ispif->pix_sof_count);
}
spin_lock_irqsave(&ispif_tasklet_lock, flags);
@@ -598,7 +639,7 @@
atomic_add(1, &ispif_irq_cnt);
spin_unlock_irqrestore(&ispif_tasklet_lock, flags);
- tasklet_schedule(&ispif_tasklet);
+ tasklet_schedule(&ispif->ispif_tasklet);
return;
}
@@ -610,10 +651,14 @@
ISPIF_IRQ_STATUS_ADDR);
out->ispifIrqStatus1 = msm_camera_io_r(ispif->base +
ISPIF_IRQ_STATUS_1_ADDR);
+ out->ispifIrqStatus2 = msm_camera_io_r(ispif->base +
+ ISPIF_IRQ_STATUS_2_ADDR);
msm_camera_io_w(out->ispifIrqStatus0,
ispif->base + ISPIF_IRQ_CLEAR_ADDR);
msm_camera_io_w(out->ispifIrqStatus1,
ispif->base + ISPIF_IRQ_CLEAR_1_ADDR);
+ msm_camera_io_w(out->ispifIrqStatus2,
+ ispif->base + ISPIF_IRQ_CLEAR_2_ADDR);
CDBG("%s: irq ispif->irq: Irq_status0 = 0x%x\n", __func__,
out->ispifIrqStatus0);
@@ -624,11 +669,14 @@
pr_err("%s: pix intf 0 overflow.\n", __func__);
if (out->ispifIrqStatus0 & (0x1 << RAW_INTF_0_OVERFLOW_IRQ))
pr_err("%s: rdi intf 0 overflow.\n", __func__);
+ if (out->ispifIrqStatus1 & (0x1 << RAW_INTF_1_OVERFLOW_IRQ))
+ pr_err("%s: rdi intf 1 overflow.\n", __func__);
+ if (out->ispifIrqStatus2 & (0x1 << RAW_INTF_2_OVERFLOW_IRQ))
+ pr_err("%s: rdi intf 2 overflow.\n", __func__);
if ((out->ispifIrqStatus0 & ISPIF_IRQ_STATUS_SOF_MASK) ||
- (out->ispifIrqStatus1 &
- ISPIF_IRQ_STATUS_SOF_MASK)) {
+ (out->ispifIrqStatus1 & ISPIF_IRQ_STATUS_SOF_MASK) ||
+ (out->ispifIrqStatus2 & ISPIF_IRQ_STATUS_RDI2_SOF_MASK))
ispif_process_irq(ispif, out);
- }
}
msm_camera_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
@@ -660,6 +708,9 @@
IRQF_TRIGGER_RISING, "ispif", ispif);
init_completion(&ispif->reset_complete);
+ tasklet_init(&ispif->ispif_tasklet,
+ ispif_do_tasklet, (unsigned long)ispif);
+
ispif->csid_version = *csid_version;
if (ispif->csid_version >= CSID_VERSION_V2) {
rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info,
@@ -679,8 +730,8 @@
static void msm_ispif_release(struct ispif_device *ispif)
{
CDBG("%s, free_irq\n", __func__);
- free_irq(ispif->irq->start, 0);
- tasklet_kill(&ispif_tasklet);
+ free_irq(ispif->irq->start, ispif);
+ tasklet_kill(&ispif->ispif_tasklet);
if (ispif->csid_version == CSID_VERSION_V2)
msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info,
diff --git a/drivers/media/video/msm/csi/msm_ispif.h b/drivers/media/video/msm/csi/msm_ispif.h
index f4ad661..a581a37 100644
--- a/drivers/media/video/msm/csi/msm_ispif.h
+++ b/drivers/media/video/msm/csi/msm_ispif.h
@@ -20,6 +20,7 @@
struct ispif_irq_status {
uint32_t ispifIrqStatus0;
uint32_t ispifIrqStatus1;
+ uint32_t ispifIrqStatus2;
};
struct ispif_device {
@@ -35,12 +36,17 @@
uint32_t csid_version;
struct clk *ispif_clk[5];
uint32_t pix_sof_count;
+ uint32_t rdi0_sof_count;
+ uint32_t rdi1_sof_count;
+ uint32_t rdi2_sof_count;
+ struct tasklet_struct ispif_tasklet;
};
struct ispif_isr_queue_cmd {
struct list_head list;
uint32_t ispifInterruptStatus0;
uint32_t ispifInterruptStatus1;
+ uint32_t ispifInterruptStatus2;
};
#define VIDIOC_MSM_ISPIF_CFG \
diff --git a/drivers/media/video/msm/eeprom/imx074_eeprom.c b/drivers/media/video/msm/eeprom/imx074_eeprom.c
index 21cbafa..a99b17e 100644
--- a/drivers/media/video/msm/eeprom/imx074_eeprom.c
+++ b/drivers/media/video/msm/eeprom/imx074_eeprom.c
@@ -47,14 +47,15 @@
.core = &imx074_eeprom_subdev_core_ops,
};
-uint8_t imx074_wbcalib_data[6];
-struct msm_calib_wb imx074_wb_data;
+static uint8_t imx074_wbcalib_data[6];
+static struct msm_calib_wb imx074_wb_data;
static struct msm_camera_eeprom_info_t imx074_calib_supp_info = {
{FALSE, 0, 0, 1},
{TRUE, 6, 0, 1024},
{FALSE, 0, 0, 1},
{FALSE, 0, 0, 1},
+ {FALSE, 0, 0, 1},
};
static struct msm_camera_eeprom_read_t imx074_eeprom_read_tbl[] = {
diff --git a/drivers/media/video/msm/eeprom/imx091_eeprom.c b/drivers/media/video/msm/eeprom/imx091_eeprom.c
index 68a2361..c53eb20 100644
--- a/drivers/media/video/msm/eeprom/imx091_eeprom.c
+++ b/drivers/media/video/msm/eeprom/imx091_eeprom.c
@@ -47,16 +47,17 @@
.core = &imx091_eeprom_subdev_core_ops,
};
-uint8_t imx091_wbcalib_data[6];
-uint8_t imx091_afcalib_data[6];
-struct msm_calib_wb imx091_wb_data;
-struct msm_calib_af imx091_af_data;
+static uint8_t imx091_wbcalib_data[6];
+static uint8_t imx091_afcalib_data[6];
+static struct msm_calib_wb imx091_wb_data;
+static struct msm_calib_af imx091_af_data;
static struct msm_camera_eeprom_info_t imx091_calib_supp_info = {
{TRUE, 6, 1, 1},
{TRUE, 6, 0, 32768},
{FALSE, 0, 0, 1},
{FALSE, 0, 0, 1},
+ {FALSE, 0, 0, 1},
};
static struct msm_camera_eeprom_read_t imx091_eeprom_read_tbl[] = {
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index 82bca02..d05f1f2 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -336,6 +336,39 @@
return rc;
}
+int32_t msm_camera_i2c_write_bayer_table(
+ struct msm_camera_i2c_client *client,
+ struct msm_camera_i2c_reg_setting *write_setting)
+{
+ int i;
+ int32_t rc = -EFAULT;
+ struct msm_camera_i2c_reg_array *reg_setting;
+
+ if (!client || !write_setting)
+ return rc;
+
+ reg_setting = write_setting->reg_setting;
+ client->addr_type = write_setting->addr_type;
+ if ((write_setting->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+ && write_setting->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+ || (write_setting->data_type != MSM_CAMERA_I2C_BYTE_DATA
+ && write_setting->data_type != MSM_CAMERA_I2C_WORD_DATA))
+ return rc;
+ for (i = 0; i < write_setting->size; i++) {
+ rc = msm_camera_i2c_write(client, reg_setting->reg_addr,
+ reg_setting->reg_data, write_setting->data_type);
+ if (rc < 0)
+ break;
+ reg_setting++;
+ }
+ if (write_setting->delay > 20)
+ msleep(write_setting->delay);
+ else if (write_setting->delay)
+ usleep_range(write_setting->delay * 1000, (write_setting->delay
+ * 1000) + 1000);
+ return rc;
+}
+
int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
enum msm_camera_i2c_data_type data_type)
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
index 169a0b3..605efff 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c.h
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <mach/camera.h>
#include <media/v4l2-subdev.h>
+#include <media/msm_camera.h>
#define CONFIG_MSM_CAMERA_I2C_DBG 0
@@ -26,6 +27,19 @@
#define S_I2C_DBG(fmt, args...) CDBG(fmt, ##args)
#endif
+enum msm_camera_i2c_cmd_type {
+ MSM_CAMERA_I2C_CMD_WRITE,
+ MSM_CAMERA_I2C_CMD_POLL,
+};
+
+struct msm_camera_i2c_reg_conf {
+ uint16_t reg_addr;
+ uint16_t reg_data;
+ enum msm_camera_i2c_data_type dt;
+ enum msm_camera_i2c_cmd_type cmd_type;
+ int16_t mask;
+};
+
struct msm_camera_i2c_client {
struct i2c_client *client;
struct msm_camera_cci_client *cci_client;
@@ -92,6 +106,10 @@
struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
enum msm_camera_i2c_data_type data_type);
+int32_t msm_camera_i2c_write_bayer_table(
+ struct msm_camera_i2c_client *client,
+ struct msm_camera_i2c_reg_setting *write_setting);
+
int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
enum msm_camera_i2c_data_type data_type);
diff --git a/drivers/media/video/msm/io/msm_camera_io_util.c b/drivers/media/video/msm/io/msm_camera_io_util.c
index 4049266..5dfa6a2 100644
--- a/drivers/media/video/msm/io/msm_camera_io_util.c
+++ b/drivers/media/video/msm/io/msm_camera_io_util.c
@@ -20,6 +20,7 @@
#include <mach/gpiomux.h>
#define BUFF_SIZE_128 128
+static int gpio_ref_count;
void msm_camera_io_w(u32 data, void __iomem *addr)
{
@@ -133,6 +134,12 @@
clk_info[i].clk_name);
goto cam_clk_enable_err;
}
+ if (clk_info[i].delay > 20) {
+ msleep(clk_info[i].delay);
+ } else if (clk_info[i].delay) {
+ usleep_range(clk_info[i].delay * 1000,
+ (clk_info[i].delay * 1000) + 1000);
+ }
}
} else {
for (i = num_clk - 1; i >= 0; i--) {
@@ -163,26 +170,41 @@
}
int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
- int num_vreg, struct regulator **reg_ptr, int config)
+ int num_vreg, enum msm_camera_vreg_name_t *vreg_seq,
+ int num_vreg_seq, struct regulator **reg_ptr, int config)
{
- int i = 0;
+ int i = 0, j = 0;
int rc = 0;
struct camera_vreg_t *curr_vreg;
+
+ if (num_vreg_seq > num_vreg) {
+ pr_err("%s:%d vreg sequence invalid\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ if (!num_vreg_seq)
+ num_vreg_seq = num_vreg;
+
if (config) {
- for (i = 0; i < num_vreg; i++) {
- curr_vreg = &cam_vreg[i];
- reg_ptr[i] = regulator_get(dev,
+ for (i = 0; i < num_vreg_seq; i++) {
+ if (vreg_seq) {
+ j = vreg_seq[i];
+ if (j >= num_vreg)
+ continue;
+ } else
+ j = i;
+ curr_vreg = &cam_vreg[j];
+ reg_ptr[j] = regulator_get(dev,
curr_vreg->reg_name);
- if (IS_ERR(reg_ptr[i])) {
+ if (IS_ERR(reg_ptr[j])) {
pr_err("%s: %s get failed\n",
__func__,
curr_vreg->reg_name);
- reg_ptr[i] = NULL;
+ reg_ptr[j] = NULL;
goto vreg_get_fail;
}
if (curr_vreg->type == REG_LDO) {
rc = regulator_set_voltage(
- reg_ptr[i],
+ reg_ptr[j],
curr_vreg->min_voltage,
curr_vreg->max_voltage);
if (rc < 0) {
@@ -193,7 +215,7 @@
}
if (curr_vreg->op_mode >= 0) {
rc = regulator_set_optimum_mode(
- reg_ptr[i],
+ reg_ptr[j],
curr_vreg->op_mode);
if (rc < 0) {
pr_err(
@@ -206,20 +228,26 @@
}
}
} else {
- for (i = num_vreg-1; i >= 0; i--) {
- curr_vreg = &cam_vreg[i];
- if (reg_ptr[i]) {
+ for (i = num_vreg_seq-1; i >= 0; i--) {
+ if (vreg_seq) {
+ j = vreg_seq[i];
+ if (j >= num_vreg)
+ continue;
+ } else
+ j = i;
+ curr_vreg = &cam_vreg[j];
+ if (reg_ptr[j]) {
if (curr_vreg->type == REG_LDO) {
if (curr_vreg->op_mode >= 0) {
regulator_set_optimum_mode(
- reg_ptr[i], 0);
+ reg_ptr[j], 0);
}
regulator_set_voltage(
- reg_ptr[i], 0, curr_vreg->
+ reg_ptr[j], 0, curr_vreg->
max_voltage);
}
- regulator_put(reg_ptr[i]);
- reg_ptr[i] = NULL;
+ regulator_put(reg_ptr[j]);
+ reg_ptr[j] = NULL;
}
}
}
@@ -227,52 +255,100 @@
vreg_unconfig:
if (curr_vreg->type == REG_LDO)
- regulator_set_optimum_mode(reg_ptr[i], 0);
+ regulator_set_optimum_mode(reg_ptr[j], 0);
vreg_set_opt_mode_fail:
if (curr_vreg->type == REG_LDO)
- regulator_set_voltage(reg_ptr[i], 0,
+ regulator_set_voltage(reg_ptr[j], 0,
curr_vreg->max_voltage);
vreg_set_voltage_fail:
- regulator_put(reg_ptr[i]);
- reg_ptr[i] = NULL;
+ regulator_put(reg_ptr[j]);
+ reg_ptr[j] = NULL;
vreg_get_fail:
for (i--; i >= 0; i--) {
- curr_vreg = &cam_vreg[i];
+ if (vreg_seq) {
+ j = vreg_seq[i];
+ if (j >= num_vreg)
+ continue;
+ } else
+ j = i;
+ curr_vreg = &cam_vreg[j];
goto vreg_unconfig;
}
return -ENODEV;
}
int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
- int num_vreg, struct regulator **reg_ptr, int enable)
+ int num_vreg, enum msm_camera_vreg_name_t *vreg_seq,
+ int num_vreg_seq, struct regulator **reg_ptr, int enable)
{
- int i = 0, rc = 0;
+ int i = 0, j = 0, rc = 0;
+
+ if (num_vreg_seq > num_vreg) {
+ pr_err("%s:%d vreg sequence invalid\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ if (!num_vreg_seq)
+ num_vreg_seq = num_vreg;
+
if (enable) {
- for (i = 0; i < num_vreg; i++) {
- if (IS_ERR(reg_ptr[i])) {
+ for (i = 0; i < num_vreg_seq; i++) {
+ if (vreg_seq) {
+ j = vreg_seq[i];
+ if (j >= num_vreg)
+ continue;
+ } else
+ j = i;
+ if (IS_ERR(reg_ptr[j])) {
pr_err("%s: %s null regulator\n",
- __func__, cam_vreg[i].reg_name);
+ __func__, cam_vreg[j].reg_name);
goto disable_vreg;
}
- rc = regulator_enable(reg_ptr[i]);
+ rc = regulator_enable(reg_ptr[j]);
if (rc < 0) {
pr_err("%s: %s enable failed\n",
- __func__, cam_vreg[i].reg_name);
+ __func__, cam_vreg[j].reg_name);
goto disable_vreg;
}
+ if (cam_vreg[j].delay > 20)
+ msleep(cam_vreg[j].delay);
+ else if (cam_vreg[j].delay)
+ usleep_range(cam_vreg[j].delay * 1000,
+ (cam_vreg[j].delay * 1000) + 1000);
}
} else {
- for (i = num_vreg-1; i >= 0; i--)
- regulator_disable(reg_ptr[i]);
+ for (i = num_vreg_seq-1; i >= 0; i--) {
+ if (vreg_seq) {
+ j = vreg_seq[i];
+ if (j >= num_vreg)
+ continue;
+ } else
+ j = i;
+ regulator_disable(reg_ptr[j]);
+ if (cam_vreg[j].delay > 20)
+ msleep(cam_vreg[j].delay);
+ else if (cam_vreg[j].delay)
+ usleep_range(cam_vreg[j].delay * 1000,
+ (cam_vreg[j].delay * 1000) + 1000);
+ }
}
return rc;
disable_vreg:
for (i--; i >= 0; i--) {
- regulator_disable(reg_ptr[i]);
- goto disable_vreg;
+ if (vreg_seq) {
+ j = vreg_seq[i];
+ if (j >= num_vreg)
+ continue;
+ } else
+ j = i;
+ regulator_disable(reg_ptr[j]);
+ if (cam_vreg[j].delay > 20)
+ msleep(cam_vreg[j].delay);
+ else if (cam_vreg[j].delay)
+ usleep_range(cam_vreg[j].delay * 1000,
+ (cam_vreg[j].delay * 1000) + 1000);
}
return rc;
}
@@ -319,7 +395,7 @@
config_gpio_table(gpio_conf);
if (gpio_en) {
- if (!gpio_conf->gpio_no_mux) {
+ if (!gpio_conf->gpio_no_mux && !gpio_ref_count) {
if (gpio_conf->cam_gpiomux_conf_tbl != NULL) {
msm_gpiomux_install(
(struct msm_gpiomux_config *)
@@ -334,6 +410,7 @@
return rc;
}
}
+ gpio_ref_count++;
if (gpio_conf->cam_gpio_req_tbl_size) {
rc = gpio_request_array(gpio_conf->cam_gpio_req_tbl,
gpio_conf->cam_gpio_req_tbl_size);
@@ -346,9 +423,10 @@
}
}
} else {
+ gpio_ref_count--;
gpio_free_array(gpio_conf->cam_gpio_req_tbl,
gpio_conf->cam_gpio_req_tbl_size);
- if (!gpio_conf->gpio_no_mux)
+ if (!gpio_conf->gpio_no_mux && !gpio_ref_count)
gpio_free_array(gpio_conf->cam_gpio_common_tbl,
gpio_conf->cam_gpio_common_tbl_size);
}
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index e5c1091..c6d568c 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -92,6 +92,20 @@
return rc;
}
+static int msm_camera_v4l2_private_general(struct file *f, void *pctx,
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+ int rc = 0;
+ struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+
+ WARN_ON(pctx != f->private_data);
+
+ rc = msm_server_private_general(pcam, ioctl_ptr);
+ if (rc < 0)
+ pr_err("%s: Private command failed rc %d\n", __func__, rc);
+ return rc;
+}
+
static int msm_camera_v4l2_private_g_ctrl(struct file *f, void *pctx,
struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
{
@@ -690,6 +704,16 @@
return OUTPUT_TYPE_R;
case MSM_V4L2_EXT_CAPTURE_MODE_RDI1:
return OUTPUT_TYPE_R1;
+ case MSM_V4L2_EXT_CAPTURE_MODE_AEC:
+ return OUTPUT_TYPE_SAEC;
+ case MSM_V4L2_EXT_CAPTURE_MODE_AF:
+ return OUTPUT_TYPE_SAFC;
+ case MSM_V4L2_EXT_CAPTURE_MODE_AWB:
+ return OUTPUT_TYPE_SAWB;
+ case MSM_V4L2_EXT_CAPTURE_MODE_IHIST:
+ return OUTPUT_TYPE_IHST;
+ case MSM_V4L2_EXT_CAPTURE_MODE_CSTA:
+ return OUTPUT_TYPE_CSTA;
case MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT:
case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW:
default:
@@ -761,6 +785,7 @@
{
int rc = -EINVAL;
struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+ struct msm_cam_v4l2_device *pcam = video_drvdata(file);
D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
switch (cmd) {
@@ -770,6 +795,47 @@
case MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL:
rc = msm_camera_v4l2_private_g_ctrl(file, fh, ioctl_ptr);
break;
+ case MSM_CAM_V4L2_IOCTL_PRIVATE_GENERAL:
+ rc = msm_camera_v4l2_private_general(file, fh, ioctl_ptr);
+ break;
+ case MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD: {
+ struct msm_queue_cmd *event_cmd;
+ void *payload;
+ mutex_lock(&pcam->event_lock);
+ event_cmd = msm_dequeue(&pcam->eventData_q, list_eventdata);
+ if (!event_cmd) {
+ pr_err("%s: No event payload\n", __func__);
+ rc = -EINVAL;
+ mutex_unlock(&pcam->event_lock);
+ return rc;
+ }
+ payload = event_cmd->command;
+ if (event_cmd->trans_code != ioctl_ptr->trans_code) {
+ pr_err("%s: Events don't match\n", __func__);
+ kfree(payload);
+ kfree(event_cmd);
+ rc = -EINVAL;
+ mutex_unlock(&pcam->event_lock);
+ break;
+ }
+ if (ioctl_ptr->len > 0) {
+ if (copy_to_user(ioctl_ptr->ioctl_ptr, payload,
+ ioctl_ptr->len)) {
+ pr_err("%s Copy to user failed for cmd %d",
+ __func__, cmd);
+ kfree(payload);
+ kfree(event_cmd);
+ rc = -EINVAL;
+ mutex_unlock(&pcam->event_lock);
+ break;
+ }
+ }
+ kfree(payload);
+ kfree(event_cmd);
+ mutex_unlock(&pcam->event_lock);
+ rc = 0;
+ break;
+ }
default:
pr_err("%s Unsupported ioctl cmd %d ", __func__, cmd);
break;
@@ -908,6 +974,8 @@
msm_setup_v4l2_event_queue(&pcam_inst->eventHandle,
pcam->pvdev);
+ mutex_init(&pcam->event_lock);
+ msm_queue_init(&pcam->eventData_q, "eventData");
}
pcam_inst->vbqueue_initialized = 0;
rc = 0;
@@ -930,6 +998,7 @@
return rc;
msm_send_open_server_failed:
+ msm_drain_eventq(&pcam->eventData_q);
msm_destroy_v4l2_event_queue(&pcam_inst->eventHandle);
if (pmctl->mctl_release)
@@ -1071,8 +1140,13 @@
D("%s index %d nodeid %d count %d\n", __func__, pcam_inst->my_index,
pcam->vnode_id, pcam->use_count);
pcam->dev_inst[pcam_inst->my_index] = NULL;
- if (pcam_inst->my_index == 0)
+ if (pcam_inst->my_index == 0) {
+ mutex_lock(&pcam->event_lock);
+ msm_drain_eventq(&pcam->eventData_q);
+ mutex_unlock(&pcam->event_lock);
+ mutex_destroy(&pcam->event_lock);
msm_destroy_v4l2_event_queue(&pcam_inst->eventHandle);
+ }
CLR_VIDEO_INST_IDX(pcam_inst->inst_handle);
CLR_IMG_MODE(pcam_inst->inst_handle);
@@ -1135,24 +1209,60 @@
unsigned int cmd, unsigned long evt)
{
struct v4l2_event v4l2_ev;
+ struct v4l2_event_and_payload evt_payload;
struct msm_cam_v4l2_device *pcam = NULL;
-
+ int rc = 0;
+ struct msm_queue_cmd *event_qcmd;
+ void *payload;
if (!mctl) {
pr_err("%s: mctl is NULL\n", __func__);
return -EINVAL;
}
- if (copy_from_user(&v4l2_ev, (void __user *)evt,
- sizeof(struct v4l2_event))) {
+ if (copy_from_user(&evt_payload, (void __user *)evt,
+ sizeof(struct v4l2_event_and_payload))) {
ERR_COPY_FROM_USER();
return -EFAULT;
}
+ v4l2_ev = evt_payload.evt;
v4l2_ev.id = 0;
pcam = mctl->pcam_ptr;
ktime_get_ts(&v4l2_ev.timestamp);
+ if (evt_payload.payload_length > 0 && evt_payload.payload != NULL) {
+ mutex_lock(&pcam->event_lock);
+ event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+ if (!event_qcmd) {
+ pr_err("%s Insufficient memory. return", __func__);
+ rc = -ENOMEM;
+ goto event_qcmd_alloc_fail;
+ }
+ payload = kzalloc(evt_payload.payload_length, GFP_KERNEL);
+ if (!payload) {
+ pr_err("%s Insufficient memory. return", __func__);
+ rc = -ENOMEM;
+ goto payload_alloc_fail;
+ }
+ if (copy_from_user(payload,
+ (void __user *)evt_payload.payload,
+ evt_payload.payload_length)) {
+ ERR_COPY_FROM_USER();
+ rc = -EFAULT;
+ goto copy_from_user_failed;
+ }
+ event_qcmd->command = payload;
+ event_qcmd->trans_code = evt_payload.transaction_id;
+ msm_enqueue(&pcam->eventData_q, &event_qcmd->list_eventdata);
+ mutex_unlock(&pcam->event_lock);
+ }
v4l2_event_queue(pcam->pvdev, &v4l2_ev);
- return 0;
+ return rc;
+copy_from_user_failed:
+ kfree(payload);
+payload_alloc_fail:
+ kfree(event_qcmd);
+event_qcmd_alloc_fail:
+ return rc;
}
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index a2c21bd..5b618f8 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -140,6 +140,11 @@
uint32_t frameCounter;
};
+struct rdi_count_msg {
+ uint32_t rdi_interface;
+ uint32_t count;
+};
+
/* message id for v4l2_subdev_notify*/
enum msm_camera_v4l2_subdev_notify {
NOTIFY_ISP_MSG_EVT, /* arg = enum ISP_MESSAGE_ID */
@@ -148,11 +153,9 @@
NOTIFY_VFE_MSG_COMP_STATS, /* arg = struct msm_stats_buf */
NOTIFY_VFE_BUF_EVT, /* arg = struct msm_vfe_resp */
NOTIFY_VFE_CAMIF_ERROR,
- NOTIFY_VFE_SOF_COUNT, /*arg = int*/
+ NOTIFY_VFE_PIX_SOF_COUNT, /*arg = int*/
+ NOTIFY_AXI_RDI_SOF_COUNT, /*arg = struct rdi_count_msg*/
NOTIFY_PCLK_CHANGE, /* arg = pclk */
- NOTIFY_CSIPHY_CFG, /* arg = msm_camera_csiphy_params */
- NOTIFY_CSID_CFG, /* arg = msm_camera_csid_params */
- NOTIFY_CSIC_CFG, /* arg = msm_camera_csic_params */
NOTIFY_VFE_IRQ,
NOTIFY_AXI_IRQ,
NOTIFY_GESTURE_EVT, /* arg = v4l2_event */
@@ -201,10 +204,36 @@
enum v4l2_colorspace colorspace;
};
+struct msm_cam_return_frame_info {
+ int dirty;
+ int node_type;
+ struct timeval timestamp;
+};
+
+struct msm_cam_timestamp {
+ uint8_t present;
+ struct timeval timestamp;
+};
+
+struct msm_cam_buf_map_info {
+ int fd;
+ uint32_t data_offset;
+ unsigned long paddr;
+ unsigned long len;
+ struct file *file;
+ struct ion_handle *handle;
+};
+
+struct msm_cam_meta_frame {
+ struct msm_pp_frame frame;
+ /* Mapping information per plane */
+ struct msm_cam_buf_map_info map[VIDEO_MAX_PLANES];
+};
+
struct msm_mctl_pp_frame_info {
int user_cmd;
- struct msm_pp_frame src_frame;
- struct msm_pp_frame dest_frame;
+ struct msm_cam_meta_frame src_frame;
+ struct msm_cam_meta_frame dest_frame;
struct msm_mctl_pp_frame_cmd pp_frame_cmd;
struct msm_cam_media_controller *p_mctl;
};
@@ -242,6 +271,10 @@
int (*mctl_vbqueue_init)(struct msm_cam_v4l2_dev_inst *pcam,
struct vb2_queue *q, enum v4l2_buf_type type);
int (*mctl_ufmt_init)(struct msm_cam_media_controller *p_mctl);
+ int (*isp_config)(struct msm_cam_media_controller *pmctl,
+ unsigned int cmd, unsigned long arg);
+ int (*isp_notify)(struct msm_cam_media_controller *pmctl,
+ struct v4l2_subdev *sd, unsigned int notification, void *arg);
/* the following reflect the HW topology information*/
struct v4l2_subdev *sensor_sdev; /* sensor sub device */
@@ -253,10 +286,10 @@
struct v4l2_subdev *gemini_sdev; /* gemini sub device */
struct v4l2_subdev *vpe_sdev; /* vpe sub device */
struct v4l2_subdev *axi_sdev; /* axi sub device */
+ struct v4l2_subdev *vfe_sdev; /* vfe sub device */
struct v4l2_subdev *eeprom_sdev; /* eeprom sub device */
struct v4l2_subdev *cpp_sdev;/*cpp sub device*/
- struct msm_isp_ops *isp_sdev; /* isp sub device : camif/VFE */
struct msm_cam_config_dev *config_device;
/*mctl session control information*/
@@ -284,21 +317,6 @@
uint32_t pong_imem_cbcr;
};
-/* abstract camera device represents a VFE and connected sensor */
-struct msm_isp_ops {
- char *config_dev_name;
-
- int (*isp_config)(struct msm_cam_media_controller *pmctl,
- unsigned int cmd, unsigned long arg);
- int (*isp_notify)(struct v4l2_subdev *sd,
- unsigned int notification, void *arg);
- int (*isp_pp_cmd)(struct msm_cam_media_controller *pmctl,
- struct msm_mctl_pp_cmd, void *data);
-
- /* vfe subdevice */
- struct v4l2_subdev *sd;
-};
-
struct msm_isp_buf_info {
int type;
unsigned long buffer;
@@ -373,6 +391,9 @@
struct v4l2_subdev *act_sdev; /* actuator sub device */
struct v4l2_subdev *eeprom_sdev; /* actuator sub device */
struct msm_camera_sensor_info *sdata;
+
+ struct msm_device_queue eventData_q; /*payload for events sent to app*/
+ struct mutex event_lock;
};
static inline struct msm_cam_v4l2_device *to_pcam(
@@ -571,11 +592,13 @@
/* ISP related functions */
void msm_isp_vfe_dev_init(struct v4l2_subdev *vd);
+int msm_isp_config(struct msm_cam_media_controller *pmctl,
+ unsigned int cmd, unsigned long arg);
+int msm_isp_notify(struct msm_cam_media_controller *pmctl,
+ struct v4l2_subdev *sd, unsigned int notification, void *arg);
/*
int msm_isp_register(struct msm_cam_v4l2_device *pcam);
*/
-int msm_isp_register(struct msm_cam_server_dev *psvr);
-void msm_isp_unregister(struct msm_cam_server_dev *psvr);
int msm_sensor_register(struct v4l2_subdev *);
int msm_isp_init_module(int g_num_config_nodes);
@@ -589,7 +612,8 @@
uint32_t frame_id);
int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
struct msm_cam_buf_handle *buf_handle,
- struct msm_free_buf *frame, int dirty, int node_type);
+ struct msm_free_buf *frame,
+ struct msm_cam_return_frame_info *ret_frame);
int msm_mctl_reserve_free_buf(struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst,
struct msm_cam_buf_handle *buf_handle,
@@ -670,6 +694,10 @@
struct msm_cam_buf_handle *buf_handle);
int msm_mctl_buf_return_buf(struct msm_cam_media_controller *pmctl,
int image_mode, struct msm_frame_buffer *buf);
+int msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
+ struct ion_client *client);
+int msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
+ struct ion_client *client);
int msm_mctl_pp_mctl_divert_done(struct msm_cam_media_controller *p_mctl,
void __user *arg);
void msm_release_ion_client(struct kref *ref);
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index 3d94afd..83f762c 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -73,7 +73,7 @@
struct msm_camvfe_params vfe_params;
int rc;
- cfgcmd.cmd_type = CMD_VFE_SOF_COUNT_UPDATE;
+ cfgcmd.cmd_type = CMD_VFE_PIX_SOF_COUNT_UPDATE;
cfgcmd.value = NULL;
vfe_params.vfe_cfg = &cfgcmd;
vfe_params.data = arg;
@@ -156,15 +156,14 @@
return image_mode;
}
-static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg)
+static int msm_isp_notify_VFE_BUF_EVT(struct msm_cam_media_controller *pmctl,
+ struct v4l2_subdev *sd, void *arg)
{
int rc = -EINVAL;
struct msm_vfe_resp *vdata = (struct msm_vfe_resp *)arg;
struct msm_free_buf free_buf, temp_free_buf;
struct msm_camvfe_params vfe_params;
struct msm_vfe_cfg_cmd cfgcmd;
- struct msm_cam_media_controller *pmctl =
- (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
struct msm_cam_v4l2_device *pcam = pmctl->pcam_ptr;
struct msm_frame_info *frame_info =
(struct msm_frame_info *)vdata->evt_msg.data;
@@ -172,7 +171,7 @@
struct msm_cam_buf_handle buf_handle;
if (!pcam) {
- pr_debug("%s pcam is null. return\n", __func__);
+ pr_err("%s pcam is null. return\n", __func__);
msm_isp_sync_free(vdata);
return rc;
}
@@ -275,14 +274,12 @@
/*
* This function executes in interrupt context.
*/
-static int msm_isp_notify_vfe(struct v4l2_subdev *sd,
- unsigned int notification, void *arg)
+static int msm_isp_notify_vfe(struct msm_cam_media_controller *pmctl,
+ struct v4l2_subdev *sd, unsigned int notification, void *arg)
{
int rc = 0;
struct v4l2_event v4l2_evt;
struct msm_isp_event_ctrl *isp_event;
- struct msm_cam_media_controller *pmctl =
- (struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
struct msm_free_buf buf;
if (!pmctl) {
@@ -292,9 +289,9 @@
}
if (notification == NOTIFY_VFE_BUF_EVT)
- return msm_isp_notify_VFE_BUF_EVT(sd, arg);
+ return msm_isp_notify_VFE_BUF_EVT(pmctl, sd, arg);
- if (notification == NOTIFY_VFE_SOF_COUNT)
+ if (notification == NOTIFY_VFE_PIX_SOF_COUNT)
return msm_isp_notify_VFE_SOF_COUNT_EVT(sd, arg);
isp_event = kzalloc(sizeof(struct msm_isp_event_ctrl), GFP_ATOMIC);
@@ -493,11 +490,12 @@
return rc;
}
-static int msm_isp_notify(struct v4l2_subdev *sd,
- unsigned int notification, void *arg)
+int msm_isp_notify(struct msm_cam_media_controller *pmctl,
+ struct v4l2_subdev *sd, unsigned int notification, void *arg)
{
- return msm_isp_notify_vfe(sd, notification, arg);
+ return msm_isp_notify_vfe(pmctl, sd, notification, arg);
}
+EXPORT_SYMBOL(msm_isp_notify);
static int msm_config_vfe(struct v4l2_subdev *sd,
struct msm_cam_media_controller *mctl, void __user *arg)
@@ -703,13 +701,13 @@
return rc;
}
/* config function simliar to origanl msm_ioctl_config*/
-static int msm_isp_config(struct msm_cam_media_controller *pmctl,
+int msm_isp_config(struct msm_cam_media_controller *pmctl,
unsigned int cmd, unsigned long arg)
{
int rc = -EINVAL;
void __user *argp = (void __user *)arg;
- struct v4l2_subdev *sd = pmctl->isp_sdev->sd;
+ struct v4l2_subdev *sd = pmctl->vfe_sdev;
D("%s: cmd %d\n", __func__, _IOC_NR(cmd));
switch (cmd) {
@@ -742,47 +740,7 @@
return rc;
}
-
-static struct msm_isp_ops isp_subdev[MSM_MAX_CAMERA_CONFIGS];
-
-/**/
-int msm_isp_init_module(int g_num_config_nodes)
-{
- int i = 0;
-
- for (i = 0; i < g_num_config_nodes; i++) {
- isp_subdev[i].isp_config = msm_isp_config;
- isp_subdev[i].isp_notify = msm_isp_notify;
- }
- return 0;
-}
-EXPORT_SYMBOL(msm_isp_init_module);
-
-/*
-*/
-int msm_isp_register(struct msm_cam_server_dev *psvr)
-{
- int i = 0;
-
- D("%s\n", __func__);
-
- BUG_ON(!psvr);
-
- /* Initialize notify function for v4l2_dev */
- for (i = 0; i < psvr->config_info.num_config_nodes; i++)
- psvr->isp_subdev[i] = &(isp_subdev[i]);
-
- return 0;
-}
-EXPORT_SYMBOL(msm_isp_register);
-
-/**/
-void msm_isp_unregister(struct msm_cam_server_dev *psvr)
-{
- int i = 0;
- for (i = 0; i < psvr->config_info.num_config_nodes; i++)
- psvr->isp_subdev[i] = NULL;
-}
+EXPORT_SYMBOL(msm_isp_config);
int msm_isp_subdev_ioctl(struct v4l2_subdev *isp_subdev,
struct msm_vfe_cfg_cmd *cfgcmd, void *data)
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index d876f12..fac1ffd 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -138,7 +138,38 @@
.pxlcode = V4L2_MBUS_FMT_YUYV8_2X8, /* YUV sensor */
.colorspace = V4L2_COLORSPACE_JPEG,
},
-
+ {
+ .name = "SAEC",
+ .depth = 16,
+ .bitsperpxl = 16,
+ .fourcc = V4L2_PIX_FMT_STATS_AE,
+ .pxlcode = V4L2_MBUS_FMT_SBGGR10_1X10, /* YUV sensor */
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ .name = "SAWB",
+ .depth = 16,
+ .bitsperpxl = 16,
+ .fourcc = V4L2_PIX_FMT_STATS_AWB,
+ .pxlcode = V4L2_MBUS_FMT_SBGGR10_1X10, /* YUV sensor */
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ .name = "SAFC",
+ .depth = 16,
+ .bitsperpxl = 16,
+ .fourcc = V4L2_PIX_FMT_STATS_AF,
+ .pxlcode = V4L2_MBUS_FMT_SBGGR10_1X10, /* YUV sensor */
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+ {
+ .name = "SHST",
+ .depth = 16,
+ .bitsperpxl = 16,
+ .fourcc = V4L2_PIX_FMT_STATS_IHST,
+ .pxlcode = V4L2_MBUS_FMT_SBGGR10_1X10, /* YUV sensor */
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
};
static int msm_get_sensor_info(
@@ -422,17 +453,36 @@
rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
VIDIOC_MSM_AXI_CFG, (void __user *)arg);
else
- rc = p_mctl->isp_sdev->isp_config(p_mctl, cmd, arg);
+ rc = p_mctl->isp_config(p_mctl, cmd, arg);
break;
case MSM_CAM_IOCTL_ISPIF_IO_CFG:
rc = v4l2_subdev_call(p_mctl->ispif_sdev,
core, ioctl, VIDIOC_MSM_ISPIF_CFG, argp);
break;
+
+ case MSM_CAM_IOCTL_CSIPHY_IO_CFG:
+ if (p_mctl->csiphy_sdev)
+ rc = v4l2_subdev_call(p_mctl->csiphy_sdev,
+ core, ioctl, VIDIOC_MSM_CSIPHY_CFG, argp);
+ break;
+
+ case MSM_CAM_IOCTL_CSIC_IO_CFG:
+ if (p_mctl->csic_sdev)
+ rc = v4l2_subdev_call(p_mctl->csic_sdev,
+ core, ioctl, VIDIOC_MSM_CSIC_CFG, argp);
+ break;
+
+ case MSM_CAM_IOCTL_CSID_IO_CFG:
+ if (p_mctl->csid_sdev)
+ rc = v4l2_subdev_call(p_mctl->csid_sdev,
+ core, ioctl, VIDIOC_MSM_CSID_CFG, argp);
+ break;
+
default:
/* ISP config*/
D("%s:%d: go to default. Calling msm_isp_config\n",
__func__, __LINE__);
- rc = p_mctl->isp_sdev->isp_config(p_mctl, cmd, arg);
+ rc = p_mctl->isp_config(p_mctl, cmd, arg);
break;
}
D("%s: !!! cmd = %d, rc = %d\n",
@@ -459,7 +509,6 @@
/* open sub devices - once only*/
if (!p_mctl->opencnt) {
struct msm_sensor_csi_info csi_info;
- uint32_t csid_version = 0;
wake_lock(&p_mctl->wake_lock);
csid_core = camdev->csid_core;
@@ -485,39 +534,10 @@
goto act_power_up_failed;
}
- if (p_mctl->csiphy_sdev) {
- rc = v4l2_subdev_call(p_mctl->csiphy_sdev, core, ioctl,
- VIDIOC_MSM_CSIPHY_INIT, NULL);
- if (rc < 0) {
- pr_err("%s: csiphy initialization failed %d\n",
- __func__, rc);
- goto csiphy_init_failed;
- }
- }
-
- if (p_mctl->csid_sdev) {
- rc = v4l2_subdev_call(p_mctl->csid_sdev, core, ioctl,
- VIDIOC_MSM_CSID_INIT, &csid_version);
- if (rc < 0) {
- pr_err("%s: csid initialization failed %d\n",
- __func__, rc);
- goto csid_init_failed;
- }
- csi_info.is_csic = 0;
- }
-
- if (p_mctl->csic_sdev) {
- rc = v4l2_subdev_call(p_mctl->csic_sdev, core, ioctl,
- VIDIOC_MSM_CSIC_INIT, &csid_version);
- if (rc < 0) {
- pr_err("%s: csic initialization failed %d\n",
- __func__, rc);
- goto csic_init_failed;
- }
+ if (p_mctl->csic_sdev)
csi_info.is_csic = 1;
- }
-
- csi_info.csid_version = csid_version;
+ else
+ csi_info.is_csic = 0;
rc = v4l2_subdev_call(p_mctl->sensor_sdev, core, ioctl,
VIDIOC_MSM_SENSOR_CSID_INFO, &csi_info);
if (rc < 0) {
@@ -540,26 +560,6 @@
return rc;
msm_csi_version:
- if (p_mctl->csic_sdev)
- if (v4l2_subdev_call(p_mctl->csic_sdev, core, ioctl,
- VIDIOC_MSM_CSIC_RELEASE, NULL) < 0)
- pr_err("%s: csic release failed %d\n", __func__, rc);
-csic_init_failed:
- if (p_mctl->csid_sdev)
- if (v4l2_subdev_call(p_mctl->csid_sdev, core, ioctl,
- VIDIOC_MSM_CSID_RELEASE, NULL) < 0)
- pr_err("%s: csid release failed %d\n", __func__, rc);
-csid_init_failed:
- if (p_mctl->csiphy_sdev)
- if (v4l2_subdev_call(p_mctl->csiphy_sdev, core, ioctl,
- VIDIOC_MSM_CSIPHY_RELEASE,
- sinfo->sensor_platform_info->csi_lane_params) < 0)
- pr_err("%s: csiphy release failed %d\n", __func__, rc);
-csiphy_init_failed:
- if (p_mctl->act_sdev)
- if (v4l2_subdev_call(p_mctl->act_sdev, core,
- s_power, 0) < 0)
- pr_err("%s: act power down failed:%d\n", __func__, rc);
act_power_up_failed:
if (v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 0) < 0)
pr_err("%s: sensor powerdown failed: %d\n", __func__, rc);
@@ -707,6 +707,9 @@
pmctl->mctl_open = msm_mctl_open;
pmctl->mctl_cmd = msm_mctl_cmd;
pmctl->mctl_release = msm_mctl_release;
+ pmctl->isp_config = msm_isp_config;
+ pmctl->isp_notify = msm_isp_notify;
+
/* init mctl buf */
msm_mctl_buf_init(pcam);
memset(&pmctl->pp_info, 0, sizeof(pmctl->pp_info));
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 9f7f689..a0cbed5 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -411,7 +411,8 @@
struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst,
struct msm_free_buf *fbuf,
- uint32_t *frame_id, int gen_timestamp)
+ uint32_t *frame_id,
+ struct msm_cam_timestamp *cam_ts)
{
struct msm_frame_buffer *buf = NULL;
int del_buf = 1;
@@ -422,11 +423,15 @@
__func__, fbuf->ch_paddr[0]);
return -EINVAL;
}
- if (gen_timestamp) {
+ if (!cam_ts->present) {
if (frame_id)
buf->vidbuf.v4l2_buf.sequence = *frame_id;
msm_mctl_gettimeofday(
&buf->vidbuf.v4l2_buf.timestamp);
+ } else {
+ D("%s Copying timestamp as %ld.%ld", __func__,
+ cam_ts->timestamp.tv_sec, cam_ts->timestamp.tv_usec);
+ buf->vidbuf.v4l2_buf.timestamp = cam_ts->timestamp;
}
vb2_buffer_done(&buf->vidbuf, VB2_BUF_STATE_DONE);
return 0;
@@ -442,6 +447,7 @@
int idx, rc;
int pp_divert_type = 0, pp_type = 0;
uint32_t image_mode;
+ struct msm_cam_timestamp cam_ts;
if (!p_mctl || !buf_handle || !fbuf) {
pr_err("%s Invalid argument. ", __func__);
@@ -507,8 +513,9 @@
__func__);
return -EINVAL;
}
+ memset(&cam_ts, 0, sizeof(cam_ts));
rc = msm_mctl_buf_done_proc(p_mctl, pcam_inst,
- fbuf, &frame_id, 1);
+ fbuf, &frame_id, &cam_ts);
}
return rc;
}
@@ -752,12 +759,14 @@
int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
struct msm_cam_buf_handle *buf_handle,
- struct msm_free_buf *frame, int dirty, int node_type)
+ struct msm_free_buf *frame,
+ struct msm_cam_return_frame_info *ret_frame)
{
struct msm_cam_v4l2_dev_inst *pcam_inst = NULL;
int rc = 0, idx;
+ struct msm_cam_timestamp cam_ts;
- if (!pmctl || !buf_handle) {
+ if (!pmctl || !buf_handle || !ret_frame) {
pr_err("%s Invalid argument ", __func__);
return -EINVAL;
}
@@ -773,13 +782,13 @@
}
} else if (buf_handle->buf_lookup_type == BUF_LOOKUP_BY_IMG_MODE) {
idx = msm_mctl_img_mode_to_inst_index(pmctl,
- buf_handle->image_mode, node_type);
+ buf_handle->image_mode, ret_frame->node_type);
if (idx < 0) {
pr_err("%s Invalid instance, buffer not released\n",
__func__);
return idx;
}
- if (node_type)
+ if (ret_frame->node_type)
pcam_inst = pmctl->pcam_ptr->mctl_node.dev_inst[idx];
else
pcam_inst = pmctl->pcam_ptr->dev_inst[idx];
@@ -791,12 +800,15 @@
}
D("%s:inst=0x%p, paddr=0x%x, dirty=%d",
- __func__, pcam_inst, frame->ch_paddr[0], dirty);
- if (dirty)
+ __func__, pcam_inst, frame->ch_paddr[0], ret_frame->dirty);
+ cam_ts.present = 1;
+ cam_ts.timestamp = ret_frame->timestamp;
+ if (ret_frame->dirty)
/* the frame is dirty, not going to disptach to app */
rc = msm_mctl_release_free_buf(pmctl, pcam_inst, frame);
else
- rc = msm_mctl_buf_done_proc(pmctl, pcam_inst, frame, NULL, 0);
+ rc = msm_mctl_buf_done_proc(pmctl, pcam_inst, frame,
+ NULL, &cam_ts);
return rc;
}
@@ -840,3 +852,199 @@
spin_unlock_irqrestore(&pcam_inst->vq_irqlock, flags);
return -EINVAL;
}
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+/* Unmap using ION APIs */
+static void __msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
+ struct ion_client *client)
+{
+ int i = 0;
+ for (i = 0; i < meta_frame->frame.num_planes; i++) {
+ D("%s Plane %d handle %p", __func__, i,
+ meta_frame->map[i].handle);
+ ion_unmap_iommu(client, meta_frame->map[i].handle,
+ CAMERA_DOMAIN, GEN_POOL);
+ ion_free(client, meta_frame->map[i].handle);
+ }
+}
+
+/* Map using ION APIs */
+static int __msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
+ struct ion_client *client)
+{
+ unsigned long paddr = 0;
+ unsigned long len = 0;
+ int i = 0, j = 0;
+
+ for (i = 0; i < meta_frame->frame.num_planes; i++) {
+ meta_frame->map[i].handle = ion_import_dma_buf(client,
+ meta_frame->frame.mp[i].fd);
+ if (IS_ERR_OR_NULL(meta_frame->map[i].handle)) {
+ pr_err("%s: ion_import failed for plane = %d fd = %d",
+ __func__, i, meta_frame->frame.mp[i].fd);
+ /* Roll back previous plane mappings, if any */
+ for (j = i-1; j >= 0; j--) {
+ ion_unmap_iommu(client,
+ meta_frame->map[j].handle,
+ CAMERA_DOMAIN, GEN_POOL);
+ ion_free(client, meta_frame->map[j].handle);
+ }
+ return -EACCES;
+ }
+ D("%s Mapping fd %d plane %d handle %p", __func__,
+ meta_frame->frame.mp[i].fd, i,
+ meta_frame->map[i].handle);
+ if (ion_map_iommu(client, meta_frame->map[i].handle,
+ CAMERA_DOMAIN, GEN_POOL, SZ_4K,
+ 0, &paddr, &len, UNCACHED, 0) < 0) {
+ pr_err("%s: cannot map address plane %d", __func__, i);
+ ion_free(client, meta_frame->map[i].handle);
+ /* Roll back previous plane mappings, if any */
+ for (j = i-1; j >= 0; j--) {
+ if (meta_frame->map[j].handle) {
+ ion_unmap_iommu(client,
+ meta_frame->map[j].handle,
+ CAMERA_DOMAIN, GEN_POOL);
+ ion_free(client,
+ meta_frame->map[j].handle);
+ }
+ }
+ return -EFAULT;
+ }
+
+ /* Validate the offsets with the mapped length. */
+ if ((meta_frame->frame.mp[i].addr_offset > len) ||
+ (meta_frame->frame.mp[i].data_offset +
+ meta_frame->frame.mp[i].length > len)) {
+ pr_err("%s: Invalid offsets A %d D %d L %d len %ld",
+ __func__, meta_frame->frame.mp[i].addr_offset,
+ meta_frame->frame.mp[i].data_offset,
+ meta_frame->frame.mp[i].length, len);
+ /* Roll back previous plane mappings, if any */
+ for (j = i; j >= 0; j--) {
+ if (meta_frame->map[j].handle) {
+ ion_unmap_iommu(client,
+ meta_frame->map[j].handle,
+ CAMERA_DOMAIN, GEN_POOL);
+ ion_free(client,
+ meta_frame->map[j].handle);
+ }
+ }
+ return -EINVAL;
+ }
+ meta_frame->map[i].data_offset =
+ meta_frame->frame.mp[i].data_offset;
+ /* Add the addr_offset to the paddr here itself. The addr_offset
+ * will be non-zero only if the user has allocated a buffer with
+ * a single fd, but logically partitioned it into
+ * multiple planes or buffers.*/
+ paddr += meta_frame->frame.mp[i].addr_offset;
+ meta_frame->map[i].paddr = paddr;
+ meta_frame->map[i].len = len;
+ D("%s Plane %d fd %d handle %p paddr %x", __func__,
+ i, meta_frame->frame.mp[i].fd,
+ meta_frame->map[i].handle,
+ (uint32_t)meta_frame->map[i].paddr);
+ }
+ D("%s Frame mapped successfully ", __func__);
+ return 0;
+}
+#else
+/* Unmap using PMEM APIs */
+static int __msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
+ struct ion_client *client)
+{
+ int i = 0, rc = 0;
+
+ for (i = 0; i < meta_frame->frame.num_planes; i++) {
+ D("%s Plane %d handle %p", __func__, i,
+ meta_frame->map[i].handle);
+ put_pmem_file(meta_frame->map[i].file);
+ }
+}
+
+/* Map using PMEM APIs */
+static int __msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
+ struct ion_client *client)
+{
+ unsigned long kvstart = 0;
+ unsigned long paddr = 0;
+ struct file *file = NULL;
+ unsigned long len;
+ int i = 0, j = 0;
+
+ for (i = 0; i < meta_frame->frame.num_planes; i++) {
+ rc = get_pmem_file(meta_frame->frame.mp[i].fd,
+ &paddr, &kvstart, &len, &file);
+ if (rc < 0) {
+ pr_err("%s: get_pmem_file fd %d error %d\n",
+ __func__, meta_frame->frame.mp[i].fd, rc);
+ /* Roll back previous plane mappings, if any */
+ for (j = i-1; j >= 0; j--)
+ if (meta_frame->map[j].file)
+ put_pmem_file(meta_frame->map[j].file);
+
+ return -EACCES;
+ }
+ D("%s Got pmem file for fd %d plane %d as %p", __func__,
+ meta_frame->frame.mp[i].fd, i, file);
+ meta_frame->map[i].file = file;
+ /* Validate the offsets with the mapped length. */
+ if ((meta_frame->frame.mp[i].addr_offset > len) ||
+ (meta_frame->frame.mp[i].data_offset +
+ meta_frame->frame.mp[i].length > len)) {
+ pr_err("%s: Invalid offsets A %d D %d L %d len %ld",
+ __func__, meta_frame->frame.mp[i].addr_offset,
+ meta_frame->frame.mp[i].data_offset,
+ meta_frame->frame.mp[i].length, len);
+ /* Roll back previous plane mappings, if any */
+ for (j = i; j >= 0; j--)
+ if (meta_frame->map[j].file)
+ put_pmem_file(meta_frame->map[j].file);
+
+ return -EINVAL;
+ }
+ meta_frame->map[i].data_offset =
+ meta_frame->frame.mp[i].data_offset;
+ /* Add the addr_offset to the paddr here itself. The addr_offset
+ * will be non-zero only if the user has allocated a buffer with
+ * a single fd, but logically partitioned it into
+ * multiple planes or buffers.*/
+ paddr += meta_frame->frame.mp[i].addr_offset;
+ meta_frame->map[i].paddr = paddr;
+ meta_frame->map[i].len = len;
+ D("%s Plane %d fd %d handle %p paddr %x", __func__,
+ i, meta_frame->frame.mp[i].fd,
+ meta_frame->map[i].handle,
+ (uint32_t)meta_frame->map[i].paddr);
+ }
+ D("%s Frame mapped successfully ", __func__);
+ return 0;
+}
+#endif
+
+int msm_mctl_map_user_frame(struct msm_cam_meta_frame *meta_frame,
+ struct ion_client *client)
+{
+
+ if ((NULL == meta_frame) || (NULL == client)) {
+ pr_err("%s Invalid input ", __func__);
+ return -EINVAL;
+ }
+
+ memset(&meta_frame->map[0], 0,
+ sizeof(struct msm_cam_buf_map_info) * VIDEO_MAX_PLANES);
+
+ return __msm_mctl_map_user_frame(meta_frame, client);
+}
+
+int msm_mctl_unmap_user_frame(struct msm_cam_meta_frame *meta_frame,
+ struct ion_client *client)
+{
+ if ((NULL == meta_frame) || (NULL == client)) {
+ pr_err("%s Invalid input ", __func__);
+ return -EINVAL;
+ }
+ __msm_mctl_unmap_user_frame(meta_frame, client);
+ return 0;
+}
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index dcb7c51..1f5b739 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -364,49 +364,6 @@
return 0;
}
-static int msm_mctl_pp_copy_timestamp_and_frame_id(
- uint32_t src_handle, uint32_t dest_handle)
-{
- struct msm_frame_buffer *src_vb;
- struct msm_frame_buffer *dest_vb;
-
- src_vb = (struct msm_frame_buffer *)src_handle;
- dest_vb = (struct msm_frame_buffer *)dest_handle;
- dest_vb->vidbuf.v4l2_buf.timestamp =
- src_vb->vidbuf.v4l2_buf.timestamp;
- dest_vb->vidbuf.v4l2_buf.sequence =
- src_vb->vidbuf.v4l2_buf.sequence;
- D("%s: timestamp=%ld:%ld,frame_id=0x%x", __func__,
- dest_vb->vidbuf.v4l2_buf.timestamp.tv_sec,
- dest_vb->vidbuf.v4l2_buf.timestamp.tv_usec,
- dest_vb->vidbuf.v4l2_buf.sequence);
- return 0;
-}
-
-static int msm_mctl_pp_path_to_inst_index(struct msm_cam_v4l2_device *pcam,
- int out_type)
-{
- int image_mode;
- switch (out_type) {
- case OUTPUT_TYPE_P:
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
- break;
- case OUTPUT_TYPE_V:
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
- break;
- case OUTPUT_TYPE_S:
- image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
- break;
- default:
- image_mode = -1;
- break;
- }
- if ((image_mode >= 0) && pcam->dev_inst_map[image_mode])
- return pcam->dev_inst_map[image_mode]->my_index;
- else
- return -EINVAL;
-}
-
static int msm_mctl_pp_path_to_img_mode(int path)
{
switch (path) {
@@ -418,6 +375,16 @@
return MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
case OUTPUT_TYPE_T:
return MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
+ case OUTPUT_TYPE_SAEC:
+ return MSM_V4L2_EXT_CAPTURE_MODE_AEC;
+ case OUTPUT_TYPE_SAWB:
+ return MSM_V4L2_EXT_CAPTURE_MODE_AWB;
+ case OUTPUT_TYPE_SAFC:
+ return MSM_V4L2_EXT_CAPTURE_MODE_AF;
+ case OUTPUT_TYPE_IHST:
+ return MSM_V4L2_EXT_CAPTURE_MODE_IHIST;
+ case OUTPUT_TYPE_CSTA:
+ return MSM_V4L2_EXT_CAPTURE_MODE_CSTA;
default:
return -EINVAL;
}
@@ -615,6 +582,7 @@
struct msm_free_buf buf;
unsigned long flags;
struct msm_cam_buf_handle buf_handle;
+ struct msm_cam_return_frame_info ret_frame;
if (copy_from_user(&frame, arg, sizeof(frame))) {
ERR_COPY_FROM_USER();
@@ -657,7 +625,11 @@
buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
}
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
- rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, dirty, 0);
+
+ ret_frame.dirty = dirty;
+ ret_frame.node_type = 0;
+ ret_frame.timestamp = frame.timestamp;
+ rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, &ret_frame);
return rc;
}
@@ -667,10 +639,10 @@
{
struct msm_pp_frame frame;
int msg_type, image_mode, rc = 0;
- int dirty = 0;
struct msm_free_buf buf;
unsigned long flags;
struct msm_cam_buf_handle buf_handle;
+ struct msm_cam_return_frame_info ret_frame;
D("%s enter\n", __func__);
@@ -698,6 +670,22 @@
msg_type = VFE_MSG_OUTPUT_T;
image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
break;
+ case OUTPUT_TYPE_SAEC:
+ msg_type = VFE_MSG_STATS_AEC;
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_AEC;
+ break;
+ case OUTPUT_TYPE_SAWB:
+ msg_type = VFE_MSG_STATS_AWB;
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_AWB;
+ break;
+ case OUTPUT_TYPE_SAFC:
+ msg_type = VFE_MSG_STATS_AF;
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_AF;
+ break;
+ case OUTPUT_TYPE_IHST:
+ msg_type = VFE_MSG_STATS_IHIST;
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_IHIST;
+ break;
default:
rc = -EFAULT;
goto err;
@@ -718,9 +706,12 @@
buf.ch_paddr[0] = frame.sp.phy_addr + frame.sp.y_off;
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+
+ ret_frame.dirty = 0;
+ ret_frame.node_type = frame.node_type;
+ ret_frame.timestamp = frame.timestamp;
D("%s Frame done id: %d\n", __func__, frame.frame_id);
- rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle,
- &buf, dirty, frame.node_type);
+ rc = msm_mctl_buf_done_pp(p_mctl, &buf_handle, &buf, &ret_frame);
return rc;
err:
spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
@@ -755,54 +746,3 @@
return rc;
}
-
-int msm_mctl_pp_get_vpe_buf_info(struct msm_mctl_pp_frame_info *zoom)
-{
- struct msm_cam_media_controller *p_mctl;
- struct msm_cam_v4l2_dev_inst *pcam_inst;
- int rc = 0, idx;
-
- if (!zoom || !zoom->p_mctl) {
- pr_err("%s Invalid input, not sending buffer to VPE ",
- __func__);
- return -EINVAL;
- }
- p_mctl = zoom->p_mctl;
- idx = msm_mctl_pp_path_to_inst_index(p_mctl->pcam_ptr,
- zoom->pp_frame_cmd.path);
- if (idx < 0) {
- pr_err("%s Invalid path, returning\n", __func__);
- return idx;
- }
- pcam_inst = p_mctl->pcam_ptr->dev_inst[idx];
- if (!pcam_inst) {
- pr_err("%s Invalid instance, returning\n", __func__);
- return -EINVAL;
- }
-
- rc = msm_mctl_pp_get_phy_addr(pcam_inst,
- zoom->pp_frame_cmd.src_buf_handle, &zoom->src_frame);
- if (rc) {
- pr_err("%s Error getting buffer address for src frame\n",
- __func__);
- return rc;
- }
-
- rc = msm_mctl_pp_get_phy_addr(pcam_inst,
- zoom->pp_frame_cmd.dest_buf_handle, &zoom->dest_frame);
- if (rc) {
- pr_err("%s Error getting buffer address for dest frame\n",
- __func__);
- return rc;
- }
-
- rc = msm_mctl_pp_copy_timestamp_and_frame_id(
- zoom->pp_frame_cmd.src_buf_handle,
- zoom->pp_frame_cmd.dest_buf_handle);
- if (rc < 0) {
- pr_err("%s Error copying timestamp info\n",
- __func__);
- return rc;
- }
- return rc;
-}
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 5990ca7..9fa9734 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -425,29 +425,37 @@
int rc = 0;
unsigned long flags;
unsigned long srcP0, srcP1, outP0, outP1;
- struct msm_mctl_pp_frame_info *frame = vpe_ctrl->pp_frame_info;
+ struct msm_mctl_pp_frame_info *frame_info = vpe_ctrl->pp_frame_info;
+
+ if (!frame_info) {
+ pr_err("%s Invalid frame", __func__);
+ return -EINVAL;
+ }
spin_lock_irqsave(&vpe_ctrl->lock, flags);
- if (frame->src_frame.num_planes > 1) {
- srcP0 = vpe_ctrl->pp_frame_info->src_frame.mp[0].phy_addr +
- vpe_ctrl->pp_frame_info->src_frame.mp[0].data_offset;
- srcP1 = vpe_ctrl->pp_frame_info->src_frame.mp[1].phy_addr +
- vpe_ctrl->pp_frame_info->src_frame.mp[1].data_offset;
- outP0 = vpe_ctrl->pp_frame_info->dest_frame.mp[0].phy_addr +
- vpe_ctrl->pp_frame_info->dest_frame.mp[0].data_offset;
- outP1 = vpe_ctrl->pp_frame_info->dest_frame.mp[1].phy_addr +
- vpe_ctrl->pp_frame_info->dest_frame.mp[1].data_offset;
+
+ if (frame_info->src_frame.frame.num_planes > 1) {
+ srcP0 = frame_info->src_frame.map[0].paddr +
+ frame_info->src_frame.map[0].data_offset;
+ srcP1 = frame_info->src_frame.map[1].paddr +
+ frame_info->src_frame.map[1].data_offset;
+ outP0 = frame_info->dest_frame.map[0].paddr +
+ frame_info->dest_frame.map[0].data_offset;
+ outP1 = frame_info->dest_frame.map[1].paddr +
+ frame_info->dest_frame.map[1].data_offset;
} else {
- srcP0 = vpe_ctrl->pp_frame_info->src_frame.sp.phy_addr +
- vpe_ctrl->pp_frame_info->src_frame.sp.y_off;
- srcP1 = vpe_ctrl->pp_frame_info->src_frame.sp.phy_addr +
- vpe_ctrl->pp_frame_info->src_frame.sp.cbcr_off;
- outP0 = vpe_ctrl->pp_frame_info->dest_frame.sp.phy_addr +
- vpe_ctrl->pp_frame_info->dest_frame.sp.y_off;
- outP1 = vpe_ctrl->pp_frame_info->dest_frame.sp.phy_addr +
- vpe_ctrl->pp_frame_info->dest_frame.sp.cbcr_off;
+ srcP0 = frame_info->src_frame.map[0].paddr;
+ srcP1 = frame_info->src_frame.map[0].paddr +
+ frame_info->src_frame.map[0].data_offset;
+ outP0 = frame_info->dest_frame.map[0].paddr;
+ outP1 = frame_info->dest_frame.map[0].paddr +
+ frame_info->dest_frame.map[0].data_offset;
}
+ D("%s VPE Configured with Src %x, %x Dest %x, %x",
+ __func__, (uint32_t)srcP0, (uint32_t)srcP1,
+ (uint32_t)outP0, (uint32_t)outP1);
+
msm_camera_io_w(srcP0, vpe_ctrl->vpebase + VPE_SRCP0_ADDR_OFFSET);
msm_camera_io_w(srcP1, vpe_ctrl->vpebase + VPE_SRCP1_ADDR_OFFSET);
msm_camera_io_w(outP0, vpe_ctrl->vpebase + VPE_OUTP0_ADDR_OFFSET);
@@ -482,7 +490,6 @@
v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_MCTL_PP_EVENT;
v4l2_evt.id = 0;
v4l2_event_queue(vpe_ctrl->subdev.devnode, &v4l2_evt);
-
spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
}
@@ -596,8 +603,8 @@
msm_vpe_cfg_update(
&vpe_ctrl->pp_frame_info->pp_frame_cmd.crop);
D("%s Sending frame idx %d id %d to VPE ", __func__,
- pp_frame_info->src_frame.buf_idx,
- pp_frame_info->src_frame.frame_id);
+ pp_frame_info->src_frame.frame.buf_idx,
+ pp_frame_info->src_frame.frame.frame_id);
rc = msm_send_frame_to_vpe();
return rc;
}
@@ -787,19 +794,35 @@
zoom->user_cmd = vpe_cmd->cmd_type;
zoom->p_mctl = v4l2_get_subdev_hostdata(&vpe_ctrl->subdev);
- D("%s: src=0x%x, dest=0x%x,cookie=0x%x,action=0x%x,path=0x%x",
- __func__, zoom->pp_frame_cmd.src_buf_handle,
- zoom->pp_frame_cmd.dest_buf_handle,
- zoom->pp_frame_cmd.cookie,
+ D("%s: cookie=0x%x,action=0x%x,path=0x%x",
+ __func__, zoom->pp_frame_cmd.cookie,
zoom->pp_frame_cmd.vpe_output_action,
zoom->pp_frame_cmd.path);
- rc = msm_mctl_pp_get_vpe_buf_info(zoom);
+
+ D("%s Mapping Source frame ", __func__);
+ zoom->src_frame.frame = zoom->pp_frame_cmd.src_frame;
+ rc = msm_mctl_map_user_frame(&zoom->src_frame,
+ zoom->p_mctl->client);
if (rc < 0) {
- pr_err("%s Error getting buffer info from mctl rc = %d",
+ pr_err("%s Error mapping source buffer rc = %d",
__func__, rc);
kfree(zoom);
break;
}
+
+ D("%s Mapping Destination frame ", __func__);
+ zoom->dest_frame.frame = zoom->pp_frame_cmd.dest_frame;
+ rc = msm_mctl_map_user_frame(&zoom->dest_frame,
+ zoom->p_mctl->client);
+ if (rc < 0) {
+ pr_err("%s Error mapping dest buffer rc = %d",
+ __func__, rc);
+ msm_mctl_unmap_user_frame(&zoom->src_frame,
+ zoom->p_mctl->client);
+ kfree(zoom);
+ break;
+ }
+
rc = msm_vpe_do_pp(zoom);
break;
}
@@ -876,6 +899,14 @@
return -EFAULT;
}
pp_frame_info = event_qcmd->command;
+
+ D("%s Unmapping source and destination buffers ",
+ __func__);
+ msm_mctl_unmap_user_frame(&pp_frame_info->src_frame,
+ pp_frame_info->p_mctl->client);
+ msm_mctl_unmap_user_frame(&pp_frame_info->dest_frame,
+ pp_frame_info->p_mctl->client);
+
pp_event_info.event = MCTL_PP_EVENT_CMD_ACK;
pp_event_info.ack.cmd = pp_frame_info->user_cmd;
pp_event_info.ack.status = 0;
@@ -884,10 +915,9 @@
pp_event_info.ack.cmd, pp_event_info.ack.status,
pp_event_info.ack.cookie);
if (copy_to_user((void __user *)v4l2_ioctl->ioctl_ptr,
- &pp_event_info,
- sizeof(struct msm_mctl_pp_event_info)))
- pr_err("%s EVENTPAYLOAD Copy to user failed ",
- __func__);
+ &pp_event_info, sizeof(struct msm_mctl_pp_event_info)))
+ pr_err("%s PAYLOAD Copy to user failed ", __func__);
+
kfree(pp_frame_info);
kfree(event_qcmd);
break;
@@ -942,12 +972,21 @@
struct v4l2_subdev_fh *fh)
{
struct vpe_ctrl_type *vpe_ctrl = v4l2_get_subdevdata(sd);
+ struct msm_mctl_pp_frame_info *frame_info = vpe_ctrl->pp_frame_info;
+
if (atomic_read(&vpe_ctrl->active) == 0) {
pr_err("%s already closed\n", __func__);
return -EINVAL;
}
D("%s E ", __func__);
+ if (frame_info) {
+ D("%s Unmap the pending item from the queue ", __func__);
+ msm_mctl_unmap_user_frame(&frame_info->src_frame,
+ frame_info->p_mctl->client);
+ msm_mctl_unmap_user_frame(&frame_info->dest_frame,
+ frame_info->p_mctl->client);
+ }
/* Drain the payload queue. */
msm_queue_drain(&vpe_ctrl->eventData_q, list_eventdata);
atomic_dec(&vpe_ctrl->active);
diff --git a/drivers/media/video/msm/sensors/Makefile b/drivers/media/video/msm/sensors/Makefile
index 5f3f6dd..cd228a1 100644
--- a/drivers/media/video/msm/sensors/Makefile
+++ b/drivers/media/video/msm/sensors/Makefile
@@ -3,12 +3,11 @@
EXTRA_CFLAGS += -Idrivers/media/video/msm/io
EXTRA_CFLAGS += -Idrivers/media/video/msm/eeprom
EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
-obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor.o
+obj-$(CONFIG_MSM_CAMERA_SENSOR) += msm_sensor_common.o msm_sensor.o msm_sensor_bayer.o msm_sensor_init.o
obj-$(CONFIG_OV5647) += ov5647_v4l2.o
obj-$(CONFIG_OV8825) += ov8825_v4l2.o
obj-$(CONFIG_IMX074) += imx074_v4l2.o
obj-$(CONFIG_S5K3L1YX) += s5k3l1yx.o
-obj-$(CONFIG_IMX091) += imx091.o
obj-$(CONFIG_OV2720) += ov2720.o
obj-$(CONFIG_MT9M114) += mt9m114_v4l2.o
obj-$(CONFIG_S5K4E1) += s5k4e1_v4l2.o
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index ddf0754..91d4797 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -168,44 +168,6 @@
},
};
-static struct msm_camera_csi_params imx074_csic_params = {
- .data_format = CSI_10BIT,
- .lane_cnt = 4,
- .lane_assign = 0xe4,
- .dpcm_scheme = 0,
- .settle_cnt = 0x14,
-};
-
-static struct msm_camera_csi_params *imx074_csic_params_array[] = {
- &imx074_csic_params,
- &imx074_csic_params,
-};
-
-static struct msm_camera_csid_vc_cfg imx074_cid_cfg[] = {
- {0, CSI_RAW10, CSI_DECODE_10BIT},
- {1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
- {2, CSI_RESERVED_DATA_0, CSI_DECODE_8BIT},
-};
-
-static struct msm_camera_csi2_params imx074_csi_params = {
- .csid_params = {
- .lane_cnt = 4,
- .lut_params = {
- .num_cid = ARRAY_SIZE(imx074_cid_cfg),
- .vc_cfg = imx074_cid_cfg,
- },
- },
- .csiphy_params = {
- .lane_cnt = 4,
- .settle_cnt = 0x1B,
- },
-};
-
-static struct msm_camera_csi2_params *imx074_csi_params_array[] = {
- &imx074_csi_params,
- &imx074_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t imx074_reg_addr = {
.x_output = 0x34C,
.y_output = 0x34E,
@@ -224,6 +186,13 @@
.vert_offset = 3,
};
+static enum msm_camera_vreg_name_t imx074_veg_seq[] = {
+ CAM_VDIG,
+ CAM_VIO,
+ CAM_VANA,
+ CAM_VAF,
+};
+
static const struct i2c_device_id imx074_i2c_id[] = {
{SENSOR_NAME, (kernel_ulong_t)&imx074_s_ctrl},
{ }
@@ -302,12 +271,12 @@
.msm_sensor_reg = &imx074_regs,
.sensor_i2c_client = &imx074_sensor_i2c_client,
.sensor_i2c_addr = 0x34,
+ .vreg_seq = imx074_veg_seq,
+ .num_vreg_seq = ARRAY_SIZE(imx074_veg_seq),
.sensor_output_reg_addr = &imx074_reg_addr,
.sensor_id_info = &imx074_id_info,
.sensor_exp_gain_info = &imx074_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csic_params = &imx074_csic_params_array[0],
- .csi_params = &imx074_csi_params_array[0],
.msm_sensor_mutex = &imx074_mut,
.sensor_i2c_driver = &imx074_i2c_driver,
.sensor_v4l2_subdev_info = imx074_subdev_info,
diff --git a/drivers/media/video/msm/sensors/imx091.c b/drivers/media/video/msm/sensors/imx091.c
deleted file mode 100644
index 7fda037..0000000
--- a/drivers/media/video/msm/sensors/imx091.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* Copyright (c) 2012, Code Aurora Forum. 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 and
- * only 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.
- *
- */
-#include "msm_sensor.h"
-#define SENSOR_NAME "imx091"
-#define PLATFORM_DRIVER_NAME "msm_camera_imx091"
-#define imx091_obj imx091_##obj
-
-DEFINE_MUTEX(imx091_mut);
-static struct msm_sensor_ctrl_t imx091_s_ctrl;
-
-static struct msm_camera_i2c_reg_conf imx091_start_settings[] = {
- {0x0100, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf imx091_stop_settings[] = {
- {0x0100, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf imx091_groupon_settings[] = {
- {0x0104, 0x01},
-};
-
-static struct msm_camera_i2c_reg_conf imx091_groupoff_settings[] = {
- {0x0104, 0x00},
-};
-
-static struct msm_camera_i2c_reg_conf imx091_prev_settings[] = {
- /* 30fps 1/2 * 1/2 */
- /* PLL setting */
- {0x0305, 0x02}, /* pre_pll_clk_div[7:0] */
- {0x0307, 0x2F}, /* pll_multiplier[7:0] */
- {0x30A4, 0x02},
- {0x303C, 0x4B},
- /* mode setting */
- {0x0340, 0x06}, /* frame_length_lines[15:8] */
- {0x0341, 0x5A}, /* frame_length_lines[7:0] */
- {0x0342, 0x12}, /* line_length_pck[15:8] */
- {0x0343, 0x0C}, /* line_length_pck[7:0] */
- {0x0344, 0x00}, /* x_addr_start[15:8] */
- {0x0345, 0x08}, /* x_addr_start[7:0] */
- {0x0346, 0x00}, /* y_addr_start[15:8] */
- {0x0347, 0x30}, /* y_addr_start[7:0] */
- {0x0348, 0x10}, /* x_addr_end[15:8] */
- {0x0349, 0x77}, /* x_addr_end[7:0] */
- {0x034A, 0x0C}, /* y_addr_end[15:8] */
- {0x034B, 0x5F}, /* y_addr_end[7:0] */
- {0x034C, 0x08}, /* x_output_size[15:8] */
- {0x034D, 0x38}, /* x_output_size[7:0] */
- {0x034E, 0x06}, /* y_output_size[15:8] */
- {0x034F, 0x18}, /* y_output_size[7:0] */
- {0x0381, 0x01}, /* x_even_inc[3:0] */
- {0x0383, 0x03}, /* x_odd_inc[3:0] */
- {0x0385, 0x01}, /* y_even_inc[7:0] */
- {0x0387, 0x03}, /* y_odd_inc[7:0] */
- {0x3040, 0x08},
- {0x3041, 0x97},
- {0x3048, 0x01},
- {0x3064, 0x12},
- {0x309B, 0x28},
- {0x309E, 0x00},
- {0x30D5, 0x09},
- {0x30D6, 0x01},
- {0x30D7, 0x01},
- {0x30D8, 0x64},
- {0x30D9, 0x89},
- {0x30DE, 0x02},
- {0x3102, 0x10},
- {0x3103, 0x44},
- {0x3104, 0x40},
- {0x3105, 0x00},
- {0x3106, 0x0D},
- {0x3107, 0x01},
- {0x310A, 0x0A},
- {0x315C, 0x99},
- {0x315D, 0x98},
- {0x316E, 0x9A},
- {0x316F, 0x99},
- {0x3318, 0x73},
-};
-
-static struct msm_camera_i2c_reg_conf imx091_snap_settings[] = {
- /* full size */
- /* PLL setting */
- {0x0305, 0x02}, /* pre_pll_clk_div[7:0] */
- {0x0307, 0x2B}, /* pll_multiplier[7:0] */
- {0x30A4, 0x02},
- {0x303C, 0x4B},
- /* mode setting */
- {0x0340, 0x0C}, /* frame_length_lines[15:8] */
- {0x0341, 0x8C}, /* frame_length_lines[7:0] */
- {0x0342, 0x12}, /* line_length_pck[15:8] */
- {0x0343, 0x0C}, /* line_length_pck[7:0] */
- {0x0344, 0x00}, /* x_addr_start[15:8] */
- {0x0345, 0x08}, /* x_addr_start[7:0] */
- {0x0346, 0x00}, /* y_addr_start[15:8] */
- {0x0347, 0x30}, /* y_addr_start[7:0] */
- {0x0348, 0x10}, /* x_addr_end[15:8] */
- {0x0349, 0x77}, /* x_addr_end[7:0] */
- {0x034A, 0x0C}, /* y_addr_end[15:8] */
- {0x034B, 0x5F}, /* y_addr_end[7:0] */
- {0x034C, 0x10}, /* x_output_size[15:8] */
- {0x034D, 0x70}, /* x_output_size[7:0] */
- {0x034E, 0x0C}, /* y_output_size[15:8] */
- {0x034F, 0x30}, /* y_output_size[7:0] */
- {0x0381, 0x01}, /* x_even_inc[3:0] */
- {0x0383, 0x01}, /* x_odd_inc[3:0] */
- {0x0385, 0x01}, /* y_even_inc[7:0] */
- {0x0387, 0x01}, /* y_odd_inc[7:0] */
- {0x3040, 0x08},
- {0x3041, 0x97},
- {0x3048, 0x00},
- {0x3064, 0x12},
- {0x309B, 0x20},
- {0x309E, 0x00},
- {0x30D5, 0x00},
- {0x30D6, 0x85},
- {0x30D7, 0x2A},
- {0x30D8, 0x64},
- {0x30D9, 0x89},
- {0x30DE, 0x00},
- {0x3102, 0x10},
- {0x3103, 0x44},
- {0x3104, 0x40},
- {0x3105, 0x00},
- {0x3106, 0x0D},
- {0x3107, 0x01},
- {0x310A, 0x0A},
- {0x315C, 0x99},
- {0x315D, 0x98},
- {0x316E, 0x9A},
- {0x316F, 0x99},
- {0x3318, 0x64},
-};
-
-static struct msm_camera_i2c_reg_conf imx091_recommend_settings[] = {
- /* global setting */
- {0x3087, 0x53},
- {0x309D, 0x94},
- {0x30A1, 0x08},
- {0x30C7, 0x00},
- {0x3115, 0x0E},
- {0x3118, 0x42},
- {0x311D, 0x34},
- {0x3121, 0x0D},
- {0x3212, 0xF2},
- {0x3213, 0x0F},
- {0x3215, 0x0F},
- {0x3217, 0x0B},
- {0x3219, 0x0B},
- {0x321B, 0x0D},
- {0x321D, 0x0D},
- /* black level setting */
- {0x3032, 0x40},
-};
-
-static struct v4l2_subdev_info imx091_subdev_info[] = {
- {
- .code = V4L2_MBUS_FMT_SBGGR10_1X10,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .fmt = 1,
- .order = 0,
- },
- /* more can be supported, to be added later */
-};
-
-static struct msm_camera_i2c_conf_array imx091_init_conf[] = {
- {&imx091_recommend_settings[0],
- ARRAY_SIZE(imx091_recommend_settings), 0, MSM_CAMERA_I2C_BYTE_DATA}
-};
-
-static struct msm_camera_i2c_conf_array imx091_confs[] = {
- {&imx091_snap_settings[0],
- ARRAY_SIZE(imx091_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
- {&imx091_prev_settings[0],
- ARRAY_SIZE(imx091_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
-};
-
-static struct msm_sensor_output_info_t imx091_dimensions[] = {
- {
- /* full size */
- .x_output = 0x1070, /* 4208 */
- .y_output = 0x0C30, /* 3120 */
- .line_length_pclk = 0x120C, /* 4620 */
- .frame_length_lines = 0x0C8C, /* 3212 */
- .vt_pixel_clk = 206400000,
- .op_pixel_clk = 206400000,
- .binning_factor = 1,
- },
- {
- /* 30 fps 1/2 * 1/2 */
- .x_output = 0x0838, /* 2104 */
- .y_output = 0x0618, /* 1560 */
- .line_length_pclk = 0x120C, /* 4620 */
- .frame_length_lines = 0x065A, /* 1626 */
- .vt_pixel_clk = 225600000,
- .op_pixel_clk = 225600000,
- .binning_factor = 1,
- },
-};
-
-static struct msm_camera_csid_vc_cfg imx091_cid_cfg[] = {
- {0, CSI_RAW10, CSI_DECODE_10BIT},
- {1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
- {2, CSI_RESERVED_DATA_0, CSI_DECODE_8BIT},
-};
-
-static struct msm_camera_csi2_params imx091_csi_params = {
- .csid_params = {
- .lane_cnt = 4,
- .lut_params = {
- .num_cid = ARRAY_SIZE(imx091_cid_cfg),
- .vc_cfg = imx091_cid_cfg,
- },
- },
- .csiphy_params = {
- .lane_cnt = 4,
- .settle_cnt = 0x12,
- },
-};
-
-static struct msm_camera_csi2_params *imx091_csi_params_array[] = {
- &imx091_csi_params,
- &imx091_csi_params,
-};
-
-static struct msm_sensor_output_reg_addr_t imx091_reg_addr = {
- .x_output = 0x034C,
- .y_output = 0x034E,
- .line_length_pclk = 0x0342,
- .frame_length_lines = 0x0340,
-};
-
-static struct msm_sensor_id_info_t imx091_id_info = {
- .sensor_id_reg_addr = 0x0000,
- .sensor_id = 0x0091,
-};
-
-static struct msm_sensor_exp_gain_info_t imx091_exp_gain_info = {
- .coarse_int_time_addr = 0x0202,
- .global_gain_addr = 0x0204,
- .vert_offset = 5,
-};
-
-static const struct i2c_device_id imx091_i2c_id[] = {
- {SENSOR_NAME, (kernel_ulong_t)&imx091_s_ctrl},
- { }
-};
-
-static struct i2c_driver imx091_i2c_driver = {
- .id_table = imx091_i2c_id,
- .probe = msm_sensor_i2c_probe,
- .driver = {
- .name = SENSOR_NAME,
- },
-};
-
-static struct msm_camera_i2c_client imx091_sensor_i2c_client = {
- .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
-};
-
-
-static int __init imx091_sensor_init_module(void)
-{
- return i2c_add_driver(&imx091_i2c_driver);
-}
-
-static struct v4l2_subdev_core_ops imx091_subdev_core_ops = {
- .ioctl = msm_sensor_subdev_ioctl,
- .s_power = msm_sensor_power,
-};
-
-static struct v4l2_subdev_video_ops imx091_subdev_video_ops = {
- .enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
-};
-
-static struct v4l2_subdev_ops imx091_subdev_ops = {
- .core = &imx091_subdev_core_ops,
- .video = &imx091_subdev_video_ops,
-};
-
-static struct msm_sensor_fn_t imx091_func_tbl = {
- .sensor_start_stream = msm_sensor_start_stream,
- .sensor_stop_stream = msm_sensor_stop_stream,
- .sensor_group_hold_on = msm_sensor_group_hold_on,
- .sensor_group_hold_off = msm_sensor_group_hold_off,
- .sensor_set_fps = msm_sensor_set_fps,
- .sensor_write_exp_gain = msm_sensor_write_exp_gain1,
- .sensor_write_snapshot_exp_gain = msm_sensor_write_exp_gain1,
- .sensor_setting = msm_sensor_setting,
- .sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
- .sensor_mode_init = msm_sensor_mode_init,
- .sensor_get_output_info = msm_sensor_get_output_info,
- .sensor_config = msm_sensor_config,
- .sensor_power_up = msm_sensor_power_up,
- .sensor_power_down = msm_sensor_power_down,
- .sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
- .sensor_get_csi_params = msm_sensor_get_csi_params,
-};
-
-static struct msm_sensor_reg_t imx091_regs = {
- .default_data_type = MSM_CAMERA_I2C_BYTE_DATA,
- .start_stream_conf = imx091_start_settings,
- .start_stream_conf_size = ARRAY_SIZE(imx091_start_settings),
- .stop_stream_conf = imx091_stop_settings,
- .stop_stream_conf_size = ARRAY_SIZE(imx091_stop_settings),
- .group_hold_on_conf = imx091_groupon_settings,
- .group_hold_on_conf_size = ARRAY_SIZE(imx091_groupon_settings),
- .group_hold_off_conf = imx091_groupoff_settings,
- .group_hold_off_conf_size = ARRAY_SIZE(imx091_groupoff_settings),
- .init_settings = &imx091_init_conf[0],
- .init_size = ARRAY_SIZE(imx091_init_conf),
- .mode_settings = &imx091_confs[0],
- .output_settings = &imx091_dimensions[0],
- .num_conf = ARRAY_SIZE(imx091_confs),
-};
-
-static struct msm_sensor_ctrl_t imx091_s_ctrl = {
- .msm_sensor_reg = &imx091_regs,
- .sensor_i2c_client = &imx091_sensor_i2c_client,
- .sensor_i2c_addr = 0x34,
- .sensor_output_reg_addr = &imx091_reg_addr,
- .sensor_id_info = &imx091_id_info,
- .sensor_exp_gain_info = &imx091_exp_gain_info,
- .cam_mode = MSM_SENSOR_MODE_INVALID,
- .csi_params = &imx091_csi_params_array[0],
- .msm_sensor_mutex = &imx091_mut,
- .sensor_i2c_driver = &imx091_i2c_driver,
- .sensor_v4l2_subdev_info = imx091_subdev_info,
- .sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx091_subdev_info),
- .sensor_v4l2_subdev_ops = &imx091_subdev_ops,
- .func_tbl = &imx091_func_tbl,
- .clk_rate = MSM_SENSOR_MCLK_24HZ,
-};
-
-module_init(imx091_sensor_init_module);
-MODULE_DESCRIPTION("SONY 12MP Bayer sensor driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/imx091.h b/drivers/media/video/msm/sensors/imx091.h
new file mode 100644
index 0000000..862b43a
--- /dev/null
+++ b/drivers/media/video/msm/sensors/imx091.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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 and
+ * only 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.
+ *
+ */
+#define IMX091_SENSOR_NAME "imx091"
+DEFINE_MSM_MUTEX(imx091_mut);
+
+static struct msm_sensor_ctrl_t imx091_s_ctrl;
+
+static struct v4l2_subdev_info imx091_subdev_info[] = {
+ {
+ .code = V4L2_MBUS_FMT_SBGGR10_1X10,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .fmt = 1,
+ .order = 0,
+ },
+ /* more can be supported, to be added later */
+};
+
+static struct msm_sensor_id_info_t imx091_id_info = {
+ .sensor_id_reg_addr = 0x0000,
+ .sensor_id = 0x0091,
+};
+
+static enum msm_camera_vreg_name_t imx091_veg_seq[] = {
+ CAM_VANA,
+ CAM_VAF,
+ CAM_VDIG,
+ CAM_VIO,
+};
+
+static struct msm_camera_power_seq_t imx091_power_seq[] = {
+ {REQUEST_GPIO, 0},
+ {REQUEST_VREG, 0},
+ {ENABLE_VREG, 0},
+ {ENABLE_GPIO, 0},
+ {CONFIG_CLK, 0},
+};
+
+static const struct i2c_device_id imx091_i2c_id[] = {
+ {IMX091_SENSOR_NAME, (kernel_ulong_t)&imx091_s_ctrl},
+ { }
+};
+
+static struct i2c_driver imx091_i2c_driver = {
+ .id_table = imx091_i2c_id,
+ .probe = msm_sensor_bayer_i2c_probe,
+ .driver = {
+ .name = IMX091_SENSOR_NAME,
+ },
+};
+
+static struct msm_camera_i2c_client imx091_sensor_i2c_client = {
+ .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+static struct v4l2_subdev_core_ops imx091_subdev_core_ops = {
+ .ioctl = msm_sensor_bayer_subdev_ioctl,
+ .s_power = msm_sensor_bayer_power,
+};
+
+static struct v4l2_subdev_video_ops imx091_subdev_video_ops = {
+ .enum_mbus_fmt = msm_sensor_bayer_v4l2_enum_fmt,
+};
+
+static struct v4l2_subdev_ops imx091_subdev_ops = {
+ .core = &imx091_subdev_core_ops,
+ .video = &imx091_subdev_video_ops,
+};
+
+static struct msm_sensor_fn_t imx091_func_tbl = {
+ .sensor_config = msm_sensor_bayer_config,
+ .sensor_power_up = msm_sensor_bayer_power_up,
+ .sensor_power_down = msm_sensor_bayer_power_down,
+ .sensor_get_csi_params = msm_sensor_bayer_get_csi_params,
+};
+
+static struct msm_sensor_ctrl_t imx091_s_ctrl = {
+ .sensor_i2c_client = &imx091_sensor_i2c_client,
+ .sensor_i2c_addr = 0x34,
+ .vreg_seq = imx091_veg_seq,
+ .num_vreg_seq = ARRAY_SIZE(imx091_veg_seq),
+ .power_seq = &imx091_power_seq[0],
+ .num_power_seq = ARRAY_SIZE(imx091_power_seq),
+ .sensor_id_info = &imx091_id_info,
+ .msm_sensor_mutex = &imx091_mut,
+ .sensor_v4l2_subdev_info = imx091_subdev_info,
+ .sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx091_subdev_info),
+ .sensor_v4l2_subdev_ops = &imx091_subdev_ops,
+ .func_tbl = &imx091_func_tbl,
+ .clk_rate = MSM_SENSOR_MCLK_24HZ,
+};
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index c6489c2..69584d5 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -11,24 +11,17 @@
*/
#include "msm_sensor.h"
+#include "msm_sensor_common.h"
#include "msm.h"
#include "msm_ispif.h"
#include "msm_camera_i2c_mux.h"
/*=============================================================*/
-int32_t msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t res)
+void msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl)
{
uint16_t cur_line = 0;
uint16_t exp_fl_lines = 0;
if (s_ctrl->sensor_exp_gain_info) {
- if (s_ctrl->prev_gain && s_ctrl->prev_line &&
- s_ctrl->func_tbl->sensor_write_exp_gain)
- s_ctrl->func_tbl->sensor_write_exp_gain(
- s_ctrl,
- s_ctrl->prev_gain,
- s_ctrl->prev_line);
-
msm_camera_i2c_read(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
&cur_line,
@@ -36,7 +29,7 @@
exp_fl_lines = cur_line +
s_ctrl->sensor_exp_gain_info->vert_offset;
if (exp_fl_lines > s_ctrl->msm_sensor_reg->
- output_settings[res].frame_length_lines)
+ output_settings[s_ctrl->curr_res].frame_length_lines)
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_output_reg_addr->
frame_length_lines,
@@ -44,26 +37,18 @@
MSM_CAMERA_I2C_WORD_DATA);
CDBG("%s cur_fl_lines %d, exp_fl_lines %d\n", __func__,
s_ctrl->msm_sensor_reg->
- output_settings[res].frame_length_lines,
+ output_settings[s_ctrl->curr_res].frame_length_lines,
exp_fl_lines);
}
- return 0;
+ return;
}
-int32_t msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t res)
+void msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl)
{
uint16_t cur_line = 0;
uint16_t exp_fl_lines = 0;
uint8_t int_time[3];
if (s_ctrl->sensor_exp_gain_info) {
- if (s_ctrl->prev_gain && s_ctrl->prev_line &&
- s_ctrl->func_tbl->sensor_write_exp_gain)
- s_ctrl->func_tbl->sensor_write_exp_gain(
- s_ctrl,
- s_ctrl->prev_gain,
- s_ctrl->prev_line);
-
msm_camera_i2c_read_seq(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
&int_time[0], 3);
@@ -73,7 +58,7 @@
exp_fl_lines = cur_line +
s_ctrl->sensor_exp_gain_info->vert_offset;
if (exp_fl_lines > s_ctrl->msm_sensor_reg->
- output_settings[res].frame_length_lines)
+ output_settings[s_ctrl->curr_res].frame_length_lines)
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
s_ctrl->sensor_output_reg_addr->
frame_length_lines,
@@ -83,10 +68,32 @@
__func__,
cur_line,
s_ctrl->msm_sensor_reg->
- output_settings[res].frame_length_lines,
+ output_settings[s_ctrl->curr_res].frame_length_lines,
exp_fl_lines);
}
- return 0;
+ return;
+}
+
+static void msm_sensor_delay_frames(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ long fps = 0;
+ uint32_t delay = 0;
+
+ if (s_ctrl->curr_res < MSM_SENSOR_INVALID_RES &&
+ s_ctrl->wait_num_frames > 0) {
+ fps = s_ctrl->msm_sensor_reg->
+ output_settings[s_ctrl->curr_res].vt_pixel_clk /
+ s_ctrl->curr_frame_length_lines /
+ s_ctrl->curr_line_length_pclk;
+ delay = (1000 * s_ctrl->wait_num_frames) / fps / Q10;
+ }
+ CDBG("%s fps = %ld, delay = %d, min_delay %d\n", __func__, fps,
+ delay, s_ctrl->min_delay);
+ if (delay > s_ctrl->min_delay)
+ msleep(delay);
+ else if (s_ctrl->min_delay)
+ msleep(s_ctrl->min_delay);
+ return;
}
int32_t msm_sensor_write_init_settings(struct msm_sensor_ctrl_t *s_ctrl)
@@ -113,9 +120,6 @@
if (rc < 0)
return rc;
- if (s_ctrl->func_tbl->sensor_adjust_frame_lines)
- rc = s_ctrl->func_tbl->sensor_adjust_frame_lines(s_ctrl, res);
-
return rc;
}
@@ -145,11 +149,18 @@
void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl)
{
+ if (s_ctrl->curr_res >= s_ctrl->msm_sensor_reg->num_conf)
+ return;
+
+ if (s_ctrl->func_tbl->sensor_adjust_frame_lines)
+ s_ctrl->func_tbl->sensor_adjust_frame_lines(s_ctrl);
+
msm_camera_i2c_write_tbl(
s_ctrl->sensor_i2c_client,
s_ctrl->msm_sensor_reg->start_stream_conf,
s_ctrl->msm_sensor_reg->start_stream_conf_size,
s_ctrl->msm_sensor_reg->default_data_type);
+ msm_sensor_delay_frames(s_ctrl);
}
void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
@@ -159,6 +170,7 @@
s_ctrl->msm_sensor_reg->stop_stream_conf,
s_ctrl->msm_sensor_reg->stop_stream_conf_size,
s_ctrl->msm_sensor_reg->default_data_type);
+ msm_sensor_delay_frames(s_ctrl);
}
void msm_sensor_group_hold_on(struct msm_sensor_ctrl_t *s_ctrl)
@@ -244,39 +256,21 @@
int update_type, int res)
{
int32_t rc = 0;
- static int csi_config;
- s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
- msleep(30);
if (update_type == MSM_SENSOR_REG_INIT) {
CDBG("Register INIT\n");
- s_ctrl->curr_csi_params = NULL;
msm_sensor_enable_debugfs(s_ctrl);
+ s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
msm_sensor_write_init_settings(s_ctrl);
- csi_config = 0;
} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
CDBG("PERIODIC : %d\n", res);
msm_sensor_write_conf_array(
s_ctrl->sensor_i2c_client,
s_ctrl->msm_sensor_reg->mode_settings, res);
msleep(30);
- if (!csi_config) {
- s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
- CDBG("CSI config in progress\n");
- v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
- NOTIFY_CSIC_CFG,
- s_ctrl->curr_csic_params);
- CDBG("CSI config is done\n");
- mb();
- msleep(30);
- csi_config = 1;
- }
v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
NOTIFY_PCLK_CHANGE,
&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
-
- s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
- msleep(50);
}
return rc;
}
@@ -284,38 +278,15 @@
int update_type, int res)
{
int32_t rc = 0;
- s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
- msleep(30);
+
if (update_type == MSM_SENSOR_REG_INIT) {
- s_ctrl->curr_csi_params = NULL;
- msm_sensor_enable_debugfs(s_ctrl);
+ s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
msm_sensor_write_init_settings(s_ctrl);
} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
msm_sensor_write_res_settings(s_ctrl, res);
- if (s_ctrl->curr_csi_params != s_ctrl->csi_params[res]) {
- s_ctrl->curr_csi_params = s_ctrl->csi_params[res];
- s_ctrl->curr_csi_params->csid_params.lane_assign =
- s_ctrl->sensordata->sensor_platform_info->
- csi_lane_params->csi_lane_assign;
- s_ctrl->curr_csi_params->csiphy_params.lane_mask =
- s_ctrl->sensordata->sensor_platform_info->
- csi_lane_params->csi_lane_mask;
- v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
- NOTIFY_CSID_CFG,
- &s_ctrl->curr_csi_params->csid_params);
- mb();
- v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
- NOTIFY_CSIPHY_CFG,
- &s_ctrl->curr_csi_params->csiphy_params);
- mb();
- msleep(20);
- }
-
v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
output_settings[res].op_pixel_clk);
- s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
- msleep(30);
}
return rc;
}
@@ -385,21 +356,10 @@
return rc;
}
-int32_t msm_sensor_release(struct msm_sensor_ctrl_t *s_ctrl)
+static int32_t msm_sensor_release(struct msm_sensor_ctrl_t *s_ctrl)
{
- long fps = 0;
- uint32_t delay = 0;
CDBG("%s called\n", __func__);
s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
- if (s_ctrl->curr_res != MSM_SENSOR_INVALID_RES) {
- fps = s_ctrl->msm_sensor_reg->
- output_settings[s_ctrl->curr_res].vt_pixel_clk /
- s_ctrl->curr_frame_length_lines /
- s_ctrl->curr_line_length_pclk;
- delay = 1000 / fps;
- CDBG("%s fps = %ld, delay = %d\n", __func__, fps, delay);
- msleep(delay);
- }
return 0;
}
@@ -418,7 +378,6 @@
case VIDIOC_MSM_SENSOR_CSID_INFO: {
struct msm_sensor_csi_info *csi_info =
(struct msm_sensor_csi_info *)arg;
- s_ctrl->csid_version = csi_info->csid_version;
s_ctrl->is_csic = csi_info->is_csic;
return 0;
}
@@ -430,14 +389,20 @@
int32_t msm_sensor_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
struct csi_lane_params_t *sensor_output_info)
{
- sensor_output_info->csi_lane_assign = s_ctrl->sensordata->
- sensor_platform_info->csi_lane_params->csi_lane_assign;
- sensor_output_info->csi_lane_mask = s_ctrl->sensordata->
- sensor_platform_info->csi_lane_params->csi_lane_mask;
+ uint8_t index;
+ struct msm_camera_csi_lane_params *csi_lane_params =
+ s_ctrl->sensordata->sensor_platform_info->csi_lane_params;
+ if (csi_lane_params) {
+ sensor_output_info->csi_lane_assign = csi_lane_params->
+ csi_lane_assign;
+ sensor_output_info->csi_lane_mask = csi_lane_params->
+ csi_lane_mask;
+ }
sensor_output_info->csi_if = s_ctrl->sensordata->csi_if;
- sensor_output_info->csid_core = s_ctrl->sensordata->
- pdata[0].csid_core;
- sensor_output_info->csid_version = s_ctrl->csid_version;
+ for (index = 0; index < sensor_output_info->csi_if; index++)
+ sensor_output_info->csid_core[index] = s_ctrl->sensordata->
+ pdata[index].csid_core;
+
return 0;
}
@@ -450,9 +415,9 @@
sizeof(struct sensor_cfg_data)))
return -EFAULT;
mutex_lock(s_ctrl->msm_sensor_mutex);
- CDBG("msm_sensor_config: cfgtype = %d\n",
- cdata.cfgtype);
- switch (cdata.cfgtype) {
+ CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
+ s_ctrl->sensordata->sensor_name, cdata.cfgtype);
+ switch (cdata.cfgtype) {
case CFG_SET_FPS:
case CFG_SET_PICT_FPS:
if (s_ctrl->func_tbl->
@@ -478,8 +443,6 @@
s_ctrl,
cdata.cfg.exp_gain.gain,
cdata.cfg.exp_gain.line);
- s_ctrl->prev_gain = cdata.cfg.exp_gain.gain;
- s_ctrl->prev_line = cdata.cfg.exp_gain.line;
break;
case CFG_SET_PICT_EXP_GAIN:
@@ -573,6 +536,22 @@
rc = -EFAULT;
break;
+ case CFG_POWER_UP:
+ pr_err("%s calling power up\n", __func__);
+ if (s_ctrl->func_tbl->sensor_power_up)
+ rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+ else
+ rc = -EFAULT;
+ break;
+
+ case CFG_POWER_DOWN:
+ if (s_ctrl->func_tbl->sensor_power_down)
+ rc = s_ctrl->func_tbl->sensor_power_down(
+ s_ctrl);
+ else
+ rc = -EFAULT;
+ break;
+
default:
rc = -EFAULT;
break;
@@ -1404,6 +1383,8 @@
rc = msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
s_ctrl->sensordata->sensor_platform_info->cam_vreg,
s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
s_ctrl->reg_ptr, 1);
if (rc < 0) {
pr_err("%s: regulator on failed\n", __func__);
@@ -1413,6 +1394,8 @@
rc = msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
s_ctrl->sensordata->sensor_platform_info->cam_vreg,
s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
s_ctrl->reg_ptr, 1);
if (rc < 0) {
pr_err("%s: enable regulator failed\n", __func__);
@@ -1435,7 +1418,14 @@
goto enable_clk_failed;
}
- usleep_range(1000, 2000);
+ if (!s_ctrl->power_seq_delay)
+ usleep_range(1000, 2000);
+ else if (s_ctrl->power_seq_delay < 20)
+ usleep_range((s_ctrl->power_seq_delay * 1000),
+ ((s_ctrl->power_seq_delay * 1000) + 1000));
+ else
+ msleep(s_ctrl->power_seq_delay);
+
if (data->sensor_platform_info->ext_power_ctrl != NULL)
data->sensor_platform_info->ext_power_ctrl(1);
@@ -1451,6 +1441,7 @@
goto cci_init_failed;
}
}
+ s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
return rc;
cci_init_failed:
@@ -1464,12 +1455,16 @@
msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
s_ctrl->sensordata->sensor_platform_info->cam_vreg,
s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
s_ctrl->reg_ptr, 0);
enable_vreg_failed:
msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
s_ctrl->sensordata->sensor_platform_info->cam_vreg,
s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
s_ctrl->reg_ptr, 0);
config_vreg_failed:
msm_camera_request_gpio_table(data, 0);
@@ -1500,13 +1495,18 @@
msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
s_ctrl->sensordata->sensor_platform_info->cam_vreg,
s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
s_ctrl->reg_ptr, 0);
msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
s_ctrl->sensordata->sensor_platform_info->cam_vreg,
s_ctrl->sensordata->sensor_platform_info->num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
s_ctrl->reg_ptr, 0);
msm_camera_request_gpio_table(data, 0);
kfree(s_ctrl->reg_ptr);
+ s_ctrl->curr_res = MSM_SENSOR_INVALID_RES;
return 0;
}
@@ -1524,7 +1524,7 @@
return rc;
}
- CDBG("%s msm_sensor id: %x, exp id: %x\n", __func__, chipid,
+ CDBG("%s: read id: %x expected id %x:\n", __func__, chipid,
s_ctrl->sensor_id_info->sensor_id);
if (chipid != s_ctrl->sensor_id_info->sensor_id) {
pr_err("msm_sensor_match_id chip id doesnot match\n");
@@ -1533,11 +1533,6 @@
return rc;
}
-struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct msm_sensor_ctrl_t, sensor_v4l2_subdev);
-}
-
int32_t msm_sensor_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -1583,6 +1578,10 @@
if (rc < 0)
goto probe_fail;
+ if (!s_ctrl->wait_num_frames)
+ s_ctrl->wait_num_frames = 1 * Q10;
+
+ pr_err("%s %s probe succeeded\n", __func__, client->name);
snprintf(s_ctrl->sensor_v4l2_subdev.name,
sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index 64d19e6..8e66251 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -26,183 +26,11 @@
#include <linux/of_device.h>
#include <linux/gpio.h>
#include <mach/camera.h>
-#include <mach/gpio.h>
#include <media/msm_camera.h>
#include <media/v4l2-subdev.h>
#include "msm_camera_i2c.h"
#include "msm_camera_eeprom.h"
-#define Q8 0x00000100
-#define Q10 0x00000400
-
-#define MSM_SENSOR_MCLK_8HZ 8000000
-#define MSM_SENSOR_MCLK_16HZ 16000000
-#define MSM_SENSOR_MCLK_24HZ 24000000
-
-struct gpio_tlmm_cfg {
- uint32_t gpio;
- uint32_t dir;
- uint32_t pull;
- uint32_t drvstr;
-};
-
-enum msm_sensor_reg_update {
- /* Sensor egisters that need to be updated during initialization */
- MSM_SENSOR_REG_INIT,
- /* Sensor egisters that needs periodic I2C writes */
- MSM_SENSOR_UPDATE_PERIODIC,
- /* All the sensor Registers will be updated */
- MSM_SENSOR_UPDATE_ALL,
- /* Not valid update */
- MSM_SENSOR_UPDATE_INVALID
-};
-
-enum msm_sensor_cam_mode_t {
- MSM_SENSOR_MODE_2D_RIGHT,
- MSM_SENSOR_MODE_2D_LEFT,
- MSM_SENSOR_MODE_3D,
- MSM_SENSOR_MODE_INVALID
-};
-
-struct msm_sensor_output_reg_addr_t {
- uint16_t x_output;
- uint16_t y_output;
- uint16_t line_length_pclk;
- uint16_t frame_length_lines;
-};
-
-struct msm_sensor_id_info_t {
- uint16_t sensor_id_reg_addr;
- uint16_t sensor_id;
-};
-
-struct msm_sensor_exp_gain_info_t {
- uint16_t coarse_int_time_addr;
- uint16_t global_gain_addr;
- uint16_t vert_offset;
-};
-
-struct msm_sensor_reg_t {
- enum msm_camera_i2c_data_type default_data_type;
- struct msm_camera_i2c_reg_conf *start_stream_conf;
- uint8_t start_stream_conf_size;
- struct msm_camera_i2c_reg_conf *stop_stream_conf;
- uint8_t stop_stream_conf_size;
- struct msm_camera_i2c_reg_conf *group_hold_on_conf;
- uint8_t group_hold_on_conf_size;
- struct msm_camera_i2c_reg_conf *group_hold_off_conf;
- uint8_t group_hold_off_conf_size;
- struct msm_camera_i2c_conf_array *init_settings;
- uint8_t init_size;
- struct msm_camera_i2c_conf_array *mode_settings;
- struct msm_camera_i2c_conf_array *no_effect_settings;
- struct msm_sensor_output_info_t *output_settings;
- uint8_t num_conf;
-};
-
-struct v4l2_subdev_info {
- enum v4l2_mbus_pixelcode code;
- enum v4l2_colorspace colorspace;
- uint16_t fmt;
- uint16_t order;
-};
-
-struct msm_sensor_ctrl_t;
-
-struct msm_sensor_v4l2_ctrl_info_t {
- uint32_t ctrl_id;
- int16_t min;
- int16_t max;
- int16_t step;
- struct msm_camera_i2c_enum_conf_array *enum_cfg_settings;
- int (*s_v4l2_ctrl) (struct msm_sensor_ctrl_t *,
- struct msm_sensor_v4l2_ctrl_info_t *, int);
-};
-
-struct msm_sensor_fn_t {
- void (*sensor_start_stream) (struct msm_sensor_ctrl_t *);
- void (*sensor_stop_stream) (struct msm_sensor_ctrl_t *);
- void (*sensor_group_hold_on) (struct msm_sensor_ctrl_t *);
- void (*sensor_group_hold_off) (struct msm_sensor_ctrl_t *);
-
- int32_t (*sensor_set_fps) (struct msm_sensor_ctrl_t *,
- struct fps_cfg *);
- int32_t (*sensor_write_exp_gain) (struct msm_sensor_ctrl_t *,
- uint16_t, uint32_t);
- int32_t (*sensor_write_snapshot_exp_gain) (struct msm_sensor_ctrl_t *,
- uint16_t, uint32_t);
- int32_t (*sensor_setting) (struct msm_sensor_ctrl_t *,
- int update_type, int rt);
- int32_t (*sensor_csi_setting) (struct msm_sensor_ctrl_t *,
- int update_type, int rt);
- int32_t (*sensor_set_sensor_mode)
- (struct msm_sensor_ctrl_t *, int, int);
- int32_t (*sensor_mode_init) (struct msm_sensor_ctrl_t *,
- int, struct sensor_init_cfg *);
- int32_t (*sensor_get_output_info) (struct msm_sensor_ctrl_t *,
- struct sensor_output_info_t *);
- int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
- int (*sensor_power_down)
- (struct msm_sensor_ctrl_t *);
- int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
- int32_t (*sensor_match_id)(struct msm_sensor_ctrl_t *s_ctrl);
- int (*sensor_adjust_frame_lines)
- (struct msm_sensor_ctrl_t *s_ctrl, uint16_t res);
- int32_t (*sensor_get_csi_params)(struct msm_sensor_ctrl_t *,
- struct csi_lane_params_t *);
-};
-
-struct msm_sensor_csi_info {
- uint32_t csid_version;
- uint8_t is_csic;
-};
-
-enum msm_sensor_state {
- MSM_SENSOR_POWER_UP,
- MSM_SENSOR_POWER_DOWN,
-};
-
-struct msm_sensor_ctrl_t {
- struct msm_camera_sensor_info *sensordata;
- struct i2c_client *msm_sensor_client;
- struct i2c_driver *sensor_i2c_driver;
- struct msm_camera_i2c_client *sensor_i2c_client;
- struct platform_device *pdev;
- uint16_t sensor_i2c_addr;
-
- struct msm_sensor_output_reg_addr_t *sensor_output_reg_addr;
- struct msm_sensor_id_info_t *sensor_id_info;
- struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info;
- struct msm_sensor_reg_t *msm_sensor_reg;
- struct msm_sensor_v4l2_ctrl_info_t *msm_sensor_v4l2_ctrl_info;
- uint16_t num_v4l2_ctrl;
- uint32_t csid_version;
- uint8_t is_csic;
-
- uint16_t curr_line_length_pclk;
- uint16_t curr_frame_length_lines;
- uint16_t prev_gain;
- uint16_t prev_line;
-
- uint32_t fps_divider;
- enum msm_sensor_resolution_t curr_res;
- enum msm_sensor_cam_mode_t cam_mode;
-
- struct mutex *msm_sensor_mutex;
- struct msm_camera_csi2_params *curr_csi_params;
- struct msm_camera_csi2_params **csi_params;
- struct msm_camera_csi_params **csic_params;
- struct msm_camera_csi_params *curr_csic_params;
-
- struct v4l2_subdev sensor_v4l2_subdev;
- struct v4l2_subdev_info *sensor_v4l2_subdev_info;
- uint8_t sensor_v4l2_subdev_info_size;
- struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
- struct msm_sensor_fn_t *func_tbl;
- struct regulator **reg_ptr;
- struct clk *cam_clk;
- long clk_rate;
- enum msm_sensor_state sensor_state;
-};
+#include "msm_sensor_common.h"
void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl);
void msm_sensor_stop_stream(struct msm_sensor_ctrl_t *s_ctrl);
@@ -256,11 +84,9 @@
int32_t msm_sensor_write_output_settings(struct msm_sensor_ctrl_t *s_ctrl,
uint16_t res);
-int32_t msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t res);
+void msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl);
-int32_t msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl,
- uint16_t res);
+void msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl);
int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
int update_type, int res);
@@ -276,12 +102,11 @@
int32_t msm_sensor_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
struct csi_lane_params_t *sensor_output_info);
+struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
int32_t msm_sensor_free_sensor_data(struct msm_sensor_ctrl_t *s_ctrl);
-struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
-
#define VIDIOC_MSM_SENSOR_CFG \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 10, void __user *)
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 4, void __user *)
#define VIDIOC_MSM_SENSOR_RELEASE \
_IO('V', BASE_VIDIOC_PRIVATE + 11)
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.c b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
new file mode 100644
index 0000000..4c380c7
--- /dev/null
+++ b/drivers/media/video/msm/sensors/msm_sensor_bayer.c
@@ -0,0 +1,906 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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 and
+ * only 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.
+ */
+
+#include "msm_sensor_bayer.h"
+#include "msm.h"
+#include "msm_ispif.h"
+#include "msm_camera_i2c_mux.h"
+/*=============================================================*/
+
+long msm_sensor_bayer_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+ void __user *argp = (void __user *)arg;
+ switch (cmd) {
+ case VIDIOC_MSM_SENSOR_CFG:
+ return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
+ case VIDIOC_MSM_SENSOR_RELEASE:
+ return 0;
+ case VIDIOC_MSM_SENSOR_CSID_INFO: {
+ struct msm_sensor_csi_info *csi_info =
+ (struct msm_sensor_csi_info *)arg;
+ s_ctrl->is_csic = csi_info->is_csic;
+ return 0;
+ }
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+int32_t msm_sensor_bayer_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
+ struct csi_lane_params_t *sensor_output_info)
+{
+ uint8_t index;
+ struct msm_camera_csi_lane_params *csi_lane_params =
+ s_ctrl->sensordata->sensor_platform_info->csi_lane_params;
+ if (csi_lane_params) {
+ sensor_output_info->csi_lane_assign = csi_lane_params->
+ csi_lane_assign;
+ sensor_output_info->csi_lane_mask = csi_lane_params->
+ csi_lane_mask;
+ }
+ sensor_output_info->csi_if = s_ctrl->sensordata->csi_if;
+ for (index = 0; index < sensor_output_info->csi_if; index++)
+ sensor_output_info->csid_core[index] = s_ctrl->sensordata->
+ pdata[index].csid_core;
+
+ return 0;
+}
+
+int32_t msm_sensor_bayer_config(struct msm_sensor_ctrl_t *s_ctrl,
+ void __user *argp)
+{
+ struct sensor_cfg_data cdata;
+ long rc = 0;
+ if (copy_from_user(&cdata,
+ (void *)argp,
+ sizeof(struct sensor_cfg_data)))
+ return -EFAULT;
+ mutex_lock(s_ctrl->msm_sensor_mutex);
+ CDBG("%s:%d %s cfgtype = %d\n", __func__, __LINE__,
+ s_ctrl->sensordata->sensor_name, cdata.cfgtype);
+ switch (cdata.cfgtype) {
+ case CFG_WRITE_I2C_ARRAY: {
+ struct msm_camera_i2c_reg_setting conf_array;
+ struct msm_camera_i2c_reg_array *regs = NULL;
+
+ if (copy_from_user(&conf_array,
+ (void *)cdata.cfg.setting,
+ sizeof(struct msm_camera_i2c_reg_setting))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ regs = kzalloc(conf_array.size * sizeof(
+ struct msm_camera_i2c_reg_array),
+ GFP_KERNEL);
+ if (!regs) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ if (copy_from_user(regs, (void *)conf_array.reg_setting,
+ conf_array.size * sizeof(
+ struct msm_camera_i2c_reg_array))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ kfree(regs);
+ rc = -EFAULT;
+ break;
+ }
+
+ conf_array.reg_setting = regs;
+ rc = msm_camera_i2c_write_bayer_table(s_ctrl->sensor_i2c_client,
+ &conf_array);
+ kfree(regs);
+ break;
+ }
+ case CFG_READ_I2C_ARRAY: {
+ struct msm_camera_i2c_reg_setting conf_array;
+ struct msm_camera_i2c_reg_array *regs;
+ int index;
+
+ if (copy_from_user(&conf_array,
+ (void *)cdata.cfg.setting,
+ sizeof(struct msm_camera_i2c_reg_setting))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ regs = kzalloc(conf_array.size * sizeof(
+ struct msm_camera_i2c_reg_array),
+ GFP_KERNEL);
+ if (!regs) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ kfree(regs);
+ break;
+ }
+
+ if (copy_from_user(regs, (void *)conf_array.reg_setting,
+ conf_array.size * sizeof(
+ struct msm_camera_i2c_reg_array))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ kfree(regs);
+ rc = -EFAULT;
+ break;
+ }
+
+ s_ctrl->sensor_i2c_client->addr_type = conf_array.addr_type;
+ for (index = 0; index < conf_array.size; index++) {
+ msm_camera_i2c_read(s_ctrl->sensor_i2c_client,
+ regs[index].reg_addr,
+ ®s[index].reg_data,
+ conf_array.data_type
+ );
+ }
+
+ if (copy_to_user(conf_array.reg_setting,
+ regs,
+ conf_array.size * sizeof(
+ struct msm_camera_i2c_reg_array))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ kfree(regs);
+ rc = -EFAULT;
+ break;
+ }
+ s_ctrl->sensor_i2c_client->addr_type = conf_array.addr_type;
+ kfree(regs);
+ break;
+ }
+ case CFG_PCLK_CHANGE: {
+ uint32_t pclk = cdata.cfg.pclk;
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_PCLK_CHANGE, &pclk);
+ break;
+ }
+ case CFG_GPIO_OP: {
+ struct msm_cam_gpio_operation gop;
+ if (copy_from_user(&gop,
+ (void *)cdata.cfg.setting,
+ sizeof(struct msm_cam_gpio_operation))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ }
+ switch (gop.op_type) {
+ case GPIO_GET_VALUE:
+ gop.value = gpio_get_value(gop.address);
+ if (copy_from_user((void *)cdata.cfg.setting,
+ &gop,
+ sizeof(struct msm_cam_gpio_operation))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+ break;
+ case GPIO_SET_VALUE:
+ gpio_set_value(gop.address, gop.value);
+ break;
+ case GPIO_SET_DIRECTION_INPUT:
+ gpio_direction_input(gop.address);
+ break;
+ case GPIO_SET_DIRECTION_OUTPUT:
+ gpio_direction_output(gop.address, gop.value);
+ break;
+ case GPIO_REQUEST:
+ gpio_request(gop.address, gop.tag);
+ break;
+ case GPIO_FREE:
+ gpio_free(gop.address);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+ case CFG_GET_CSI_PARAMS:
+ if (s_ctrl->func_tbl->sensor_get_csi_params == NULL) {
+ rc = -EFAULT;
+ break;
+ }
+ rc = s_ctrl->func_tbl->sensor_get_csi_params(
+ s_ctrl,
+ &cdata.cfg.csi_lane_params);
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+
+ case CFG_POWER_UP:
+ if (s_ctrl->func_tbl->sensor_power_up)
+ rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+ else
+ rc = -EFAULT;
+ break;
+
+ case CFG_POWER_DOWN:
+ if (s_ctrl->func_tbl->sensor_power_down)
+ rc = s_ctrl->func_tbl->sensor_power_down(
+ s_ctrl);
+ else
+ rc = -EFAULT;
+ break;
+
+ case CFG_CONFIG_VREG_ARRAY: {
+ struct msm_camera_vreg_setting vreg_setting;
+ struct camera_vreg_t *cam_vreg = NULL;
+
+ if (copy_from_user(&vreg_setting,
+ (void *)cdata.cfg.setting,
+ sizeof(struct msm_camera_vreg_setting))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ cam_vreg = kzalloc(vreg_setting.num_vreg * sizeof(
+ struct camera_vreg_t),
+ GFP_KERNEL);
+ if (!cam_vreg) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ if (copy_from_user(cam_vreg, (void *)vreg_setting.cam_vreg,
+ vreg_setting.num_vreg * sizeof(
+ struct camera_vreg_t))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ kfree(cam_vreg);
+ rc = -EFAULT;
+ break;
+ }
+ rc = msm_camera_config_vreg(
+ &s_ctrl->sensor_i2c_client->client->dev,
+ cam_vreg,
+ vreg_setting.num_vreg,
+ NULL,
+ 0,
+ s_ctrl->reg_ptr,
+ vreg_setting.enable);
+ if (rc < 0) {
+ kfree(cam_vreg);
+ pr_err("%s: regulator on failed\n", __func__);
+ break;
+ }
+
+ rc = msm_camera_enable_vreg(
+ &s_ctrl->sensor_i2c_client->client->dev,
+ cam_vreg,
+ vreg_setting.num_vreg,
+ NULL,
+ 0,
+ s_ctrl->reg_ptr,
+ vreg_setting.enable);
+ if (rc < 0) {
+ kfree(cam_vreg);
+ pr_err("%s: enable regulator failed\n", __func__);
+ break;
+ }
+ kfree(cam_vreg);
+ break;
+ }
+ case CFG_CONFIG_CLK_ARRAY: {
+ struct msm_cam_clk_setting clk_setting;
+ struct msm_cam_clk_info *clk_info = NULL;
+
+ if (copy_from_user(&clk_setting,
+ (void *)cdata.cfg.setting,
+ sizeof(struct msm_camera_vreg_setting))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ clk_info = kzalloc(clk_setting.num_clk_info * sizeof(
+ struct msm_cam_clk_info),
+ GFP_KERNEL);
+ if (!clk_info) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ break;
+ }
+
+ if (copy_from_user(clk_info, (void *)clk_setting.clk_info,
+ clk_setting.num_clk_info * sizeof(
+ struct msm_cam_clk_info))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ kfree(clk_info);
+ rc = -EFAULT;
+ break;
+ }
+ rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
+ clk_info, &s_ctrl->cam_clk,
+ clk_setting.num_clk_info,
+ clk_setting.enable);
+ kfree(clk_info);
+ break;
+ }
+ case CFG_GET_EEPROM_DATA: {
+ if (copy_to_user((void *)cdata.cfg.eeprom_data.eeprom_data,
+ &s_ctrl->eeprom_data, s_ctrl->eeprom_data.length)) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ }
+ cdata.cfg.eeprom_data.index = s_ctrl->eeprom_data.length;
+ break;
+ }
+ default:
+ rc = -EFAULT;
+ break;
+ }
+
+ mutex_unlock(s_ctrl->msm_sensor_mutex);
+
+ return rc;
+}
+
+static struct msm_cam_clk_info cam_clk_info[] = {
+ {"cam_clk", MSM_SENSOR_MCLK_24HZ},
+};
+
+int32_t msm_sensor_bayer_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+ struct v4l2_subdev *i2c_mux_sd =
+ dev_get_drvdata(&i2c_conf->mux_dev->dev);
+ v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+ VIDIOC_MSM_I2C_MUX_INIT, NULL);
+ v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+ VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
+ return 0;
+}
+
+int32_t msm_sensor_bayer_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+ struct v4l2_subdev *i2c_mux_sd =
+ dev_get_drvdata(&i2c_conf->mux_dev->dev);
+ v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+ VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
+ return 0;
+}
+
+static struct msm_camera_power_seq_t sensor_power_seq[] = {
+ {REQUEST_GPIO, 0},
+ {REQUEST_VREG, 0},
+ {ENABLE_VREG, 0},
+ {ENABLE_GPIO, 0},
+ {CONFIG_CLK, 0},
+ {CONFIG_EXT_POWER_CTRL, 0},
+ {CONFIG_I2C_MUX, 0},
+};
+
+int32_t msm_sensor_bayer_power_up(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t rc = 0, size = 0, index = 0;
+ struct msm_camera_sensor_info *data = s_ctrl->sensordata;
+ struct msm_camera_power_seq_t *power_seq = NULL;
+ CDBG("%s: %d\n", __func__, __LINE__);
+ if (s_ctrl->power_seq) {
+ power_seq = s_ctrl->power_seq;
+ size = s_ctrl->num_power_seq;
+ } else {
+ power_seq = &sensor_power_seq[0];
+ size = ARRAY_SIZE(sensor_power_seq);
+ }
+
+ s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
+ * data->sensor_platform_info->num_vreg, GFP_KERNEL);
+ if (!s_ctrl->reg_ptr) {
+ pr_err("%s: could not allocate mem for regulators\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ for (index = 0; index < size; index++) {
+ switch (power_seq[index].power_config) {
+ case REQUEST_GPIO:
+ rc = msm_camera_request_gpio_table(data, 1);
+ if (rc < 0) {
+ pr_err("%s: request gpio failed\n", __func__);
+ goto ERROR;
+ }
+ if (power_seq[index].delay)
+ usleep_range(power_seq[index].delay * 1000,
+ (power_seq[index].delay * 1000) + 1000);
+ break;
+ case REQUEST_VREG:
+ rc = msm_camera_config_vreg(
+ &s_ctrl->sensor_i2c_client->client->dev,
+ s_ctrl->sensordata->sensor_platform_info->
+ cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->
+ num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
+ s_ctrl->reg_ptr, 1);
+ if (rc < 0) {
+ pr_err("%s: regulator on failed\n", __func__);
+ goto ERROR;
+ }
+ if (power_seq[index].delay)
+ usleep_range(power_seq[index].delay * 1000,
+ (power_seq[index].delay * 1000) + 1000);
+ break;
+ case ENABLE_VREG:
+ rc = msm_camera_enable_vreg(
+ &s_ctrl->sensor_i2c_client->client->dev,
+ s_ctrl->sensordata->sensor_platform_info->
+ cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->
+ num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
+ s_ctrl->reg_ptr, 1);
+ if (rc < 0) {
+ pr_err("%s: enable regulator failed\n",
+ __func__);
+ goto ERROR;
+ }
+ if (power_seq[index].delay)
+ usleep_range(power_seq[index].delay * 1000,
+ (power_seq[index].delay * 1000) + 1000);
+ break;
+ case ENABLE_GPIO:
+ rc = msm_camera_config_gpio_table(data, 1);
+ if (rc < 0) {
+ pr_err("%s: config gpio failed\n", __func__);
+ goto ERROR;
+ }
+ if (power_seq[index].delay)
+ usleep_range(power_seq[index].delay * 1000,
+ (power_seq[index].delay * 1000) + 1000);
+ break;
+ case CONFIG_CLK:
+ if (s_ctrl->clk_rate != 0)
+ cam_clk_info->clk_rate = s_ctrl->clk_rate;
+
+ rc = msm_cam_clk_enable(
+ &s_ctrl->sensor_i2c_client->client->dev,
+ cam_clk_info, &s_ctrl->cam_clk,
+ ARRAY_SIZE(cam_clk_info), 1);
+ if (rc < 0) {
+ pr_err("%s: clk enable failed\n", __func__);
+ goto ERROR;
+ }
+ if (power_seq[index].delay)
+ usleep_range(power_seq[index].delay * 1000,
+ (power_seq[index].delay * 1000) + 1000);
+ break;
+ case CONFIG_EXT_POWER_CTRL:
+ if (data->sensor_platform_info->ext_power_ctrl != NULL)
+ data->sensor_platform_info->ext_power_ctrl(1);
+ if (power_seq[index].delay)
+ usleep_range(power_seq[index].delay * 1000,
+ (power_seq[index].delay * 1000) + 1000);
+ break;
+ case CONFIG_I2C_MUX:
+ if (data->sensor_platform_info->i2c_conf &&
+ data->sensor_platform_info->i2c_conf->
+ use_i2c_mux)
+ msm_sensor_bayer_enable_i2c_mux(
+ data->sensor_platform_info->i2c_conf);
+ if (power_seq[index].delay)
+ usleep_range(power_seq[index].delay * 1000,
+ (power_seq[index].delay * 1000) + 1000);
+ break;
+ default:
+ pr_err("%s error power config %d\n", __func__,
+ power_seq[index].power_config);
+ rc = -EINVAL;
+ break;
+ }
+ }
+
+ return rc;
+
+ERROR:
+ for (index--; index >= 0; index--) {
+ switch (power_seq[index].power_config) {
+ case CONFIG_I2C_MUX:
+ if (data->sensor_platform_info->i2c_conf &&
+ data->sensor_platform_info->i2c_conf->
+ use_i2c_mux)
+ msm_sensor_bayer_disable_i2c_mux(
+ data->sensor_platform_info->i2c_conf);
+ break;
+ case CONFIG_EXT_POWER_CTRL:
+ if (data->sensor_platform_info->ext_power_ctrl != NULL)
+ data->sensor_platform_info->ext_power_ctrl(0);
+ break;
+ case CONFIG_CLK:
+ msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->
+ dev, cam_clk_info, &s_ctrl->cam_clk,
+ ARRAY_SIZE(cam_clk_info), 0);
+ break;
+ case ENABLE_GPIO:
+ msm_camera_config_gpio_table(data, 0);
+ break;
+ case ENABLE_VREG:
+ msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->
+ client->dev,
+ s_ctrl->sensordata->sensor_platform_info->
+ cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->
+ num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
+ s_ctrl->reg_ptr, 0);
+ break;
+ case REQUEST_VREG:
+ msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->
+ client->dev,
+ s_ctrl->sensordata->sensor_platform_info->
+ cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->
+ num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
+ s_ctrl->reg_ptr, 0);
+ break;
+ case REQUEST_GPIO:
+ msm_camera_request_gpio_table(data, 0);
+ break;
+ default:
+ pr_err("%s error power config %d\n", __func__,
+ power_seq[index].power_config);
+ break;
+ }
+ }
+ kfree(s_ctrl->reg_ptr);
+ return rc;
+}
+
+int32_t msm_sensor_bayer_power_down(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t size = 0, index = 0;
+ struct msm_camera_sensor_info *data = s_ctrl->sensordata;
+ struct msm_camera_power_seq_t *power_seq = NULL;
+ CDBG("%s\n", __func__);
+
+ if (s_ctrl->power_seq) {
+ power_seq = s_ctrl->power_seq;
+ size = s_ctrl->num_power_seq;
+ } else {
+ power_seq = &sensor_power_seq[0];
+ size = ARRAY_SIZE(sensor_power_seq);
+ }
+
+ for (index = (size - 1); index >= 0; index--) {
+ switch (power_seq[index].power_config) {
+ case CONFIG_I2C_MUX:
+ if (data->sensor_platform_info->i2c_conf &&
+ data->sensor_platform_info->i2c_conf->
+ use_i2c_mux)
+ msm_sensor_bayer_disable_i2c_mux(
+ data->sensor_platform_info->i2c_conf);
+ break;
+ case CONFIG_EXT_POWER_CTRL:
+ if (data->sensor_platform_info->ext_power_ctrl != NULL)
+ data->sensor_platform_info->ext_power_ctrl(0);
+ break;
+ case CONFIG_CLK:
+ msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->
+ dev, cam_clk_info, &s_ctrl->cam_clk,
+ ARRAY_SIZE(cam_clk_info), 0);
+ break;
+ case ENABLE_GPIO:
+ msm_camera_config_gpio_table(data, 0);
+ break;
+ case ENABLE_VREG:
+ msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->
+ client->dev,
+ s_ctrl->sensordata->sensor_platform_info->
+ cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->
+ num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
+ s_ctrl->reg_ptr, 0);
+ break;
+ case REQUEST_VREG:
+ msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->
+ client->dev,
+ s_ctrl->sensordata->sensor_platform_info->
+ cam_vreg,
+ s_ctrl->sensordata->sensor_platform_info->
+ num_vreg,
+ s_ctrl->vreg_seq,
+ s_ctrl->num_vreg_seq,
+ s_ctrl->reg_ptr, 0);
+ break;
+ case REQUEST_GPIO:
+ msm_camera_request_gpio_table(data, 0);
+ break;
+ default:
+ pr_err("%s error power config %d\n", __func__,
+ power_seq[index].power_config);
+ break;
+ }
+ }
+ kfree(s_ctrl->reg_ptr);
+ return 0;
+}
+
+int32_t msm_sensor_bayer_match_id(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ int32_t rc = 0;
+ uint16_t chipid = 0;
+ rc = msm_camera_i2c_read(
+ s_ctrl->sensor_i2c_client,
+ s_ctrl->sensor_id_info->sensor_id_reg_addr, &chipid,
+ MSM_CAMERA_I2C_WORD_DATA);
+ if (rc < 0) {
+ pr_err("%s: %s: read id failed\n", __func__,
+ s_ctrl->sensordata->sensor_name);
+ return rc;
+ }
+
+ CDBG("%s: read id: %x expected id %x:\n", __func__, chipid,
+ s_ctrl->sensor_id_info->sensor_id);
+ if (chipid != s_ctrl->sensor_id_info->sensor_id) {
+ pr_err("msm_sensor_match_id chip id doesnot match\n");
+ return -ENODEV;
+ }
+ return rc;
+}
+
+static int32_t msm_sensor_bayer_eeprom_read(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ uint32_t reg_addr = 0;
+ uint8_t *data = s_ctrl->eeprom_data.data;
+ uint32_t num_byte = 0;
+ int rc = 0;
+ uint32_t i2c_addr;
+ struct msm_camera_sensor_info *sensor_info = s_ctrl->sensordata;
+ i2c_addr = sensor_info->eeprom_info->eeprom_i2c_slave_addr;
+ num_byte = s_ctrl->eeprom_data.length = sensor_info->eeprom_info->
+ eeprom_read_length;
+ reg_addr = sensor_info->eeprom_info->eeprom_reg_addr;
+
+ data = kzalloc(num_byte * sizeof(uint8_t), GFP_KERNEL);
+ if (!data) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ rc = -EFAULT;
+ return rc;
+ }
+
+ s_ctrl->sensor_i2c_client->client->addr = i2c_addr;
+ CDBG("eeprom read: i2c addr is %x num byte %d reg addr %x\n",
+ i2c_addr, num_byte, reg_addr);
+ rc = msm_camera_i2c_read_seq(s_ctrl->sensor_i2c_client, reg_addr, data,
+ num_byte);
+ s_ctrl->sensor_i2c_client->client->addr = s_ctrl->sensor_i2c_addr;
+ return rc;
+}
+
+int32_t msm_sensor_bayer_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc = 0;
+ struct msm_sensor_ctrl_t *s_ctrl;
+ CDBG("%s %s_i2c_probe called\n", __func__, client->name);
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("%s %s i2c_check_functionality failed\n",
+ __func__, client->name);
+ rc = -EFAULT;
+ return rc;
+ }
+
+ s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
+ if (s_ctrl->sensor_i2c_client != NULL) {
+ s_ctrl->sensor_i2c_client->client = client;
+ if (s_ctrl->sensor_i2c_addr != 0)
+ s_ctrl->sensor_i2c_client->client->addr =
+ s_ctrl->sensor_i2c_addr;
+ } else {
+ pr_err("%s %s sensor_i2c_client NULL\n",
+ __func__, client->name);
+ rc = -EFAULT;
+ return rc;
+ }
+
+ s_ctrl->sensordata = client->dev.platform_data;
+ if (s_ctrl->sensordata == NULL) {
+ pr_err("%s %s NULL sensor data\n", __func__, client->name);
+ return -EFAULT;
+ }
+
+ rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+ if (rc < 0) {
+ pr_err("%s %s power up failed\n", __func__, client->name);
+ return rc;
+ }
+
+ if (s_ctrl->func_tbl->sensor_match_id)
+ rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
+ else
+ rc = msm_sensor_bayer_match_id(s_ctrl);
+ if (rc < 0)
+ goto probe_fail;
+
+ if (!s_ctrl->wait_num_frames)
+ s_ctrl->wait_num_frames = 1;
+
+ pr_err("%s %s probe succeeded\n", __func__, client->name);
+ snprintf(s_ctrl->sensor_v4l2_subdev.name,
+ sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
+ v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
+ s_ctrl->sensor_v4l2_subdev_ops);
+ s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
+ s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
+ s_ctrl->sensor_v4l2_subdev.entity.name =
+ s_ctrl->sensor_v4l2_subdev.name;
+ msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
+ s_ctrl->sensor_v4l2_subdev.entity.revision =
+ s_ctrl->sensor_v4l2_subdev.devnode->num;
+ msm_sensor_bayer_eeprom_read(s_ctrl);
+ goto power_down;
+probe_fail:
+ pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
+power_down:
+ if (rc > 0)
+ rc = 0;
+ s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+ return rc;
+}
+
+int32_t msm_sensor_delay_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc = 0;
+ struct msm_sensor_ctrl_t *s_ctrl;
+ CDBG("%s %s_delay_i2c_probe called\n", __func__, client->name);
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("%s %s i2c_check_functionality failed\n",
+ __func__, client->name);
+ rc = -EFAULT;
+ return rc;
+ }
+
+ s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
+ if (s_ctrl->sensor_i2c_client != NULL) {
+ s_ctrl->sensor_i2c_client->client = client;
+ if (s_ctrl->sensor_i2c_addr != 0)
+ s_ctrl->sensor_i2c_client->client->addr =
+ s_ctrl->sensor_i2c_addr;
+ } else {
+ pr_err("%s %s sensor_i2c_client NULL\n",
+ __func__, client->name);
+ rc = -EFAULT;
+ return rc;
+ }
+
+ s_ctrl->sensordata = client->dev.platform_data;
+ if (s_ctrl->sensordata == NULL) {
+ pr_err("%s %s NULL sensor data\n", __func__, client->name);
+ return -EFAULT;
+ }
+
+ if (!s_ctrl->wait_num_frames)
+ s_ctrl->wait_num_frames = 1;
+
+ pr_err("%s %s probe succeeded\n", __func__, client->name);
+ snprintf(s_ctrl->sensor_v4l2_subdev.name,
+ sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
+ v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
+ s_ctrl->sensor_v4l2_subdev_ops);
+ s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
+ s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
+ s_ctrl->sensor_v4l2_subdev.entity.name =
+ s_ctrl->sensor_v4l2_subdev.name;
+ msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
+ s_ctrl->sensor_v4l2_subdev.entity.revision =
+ s_ctrl->sensor_v4l2_subdev.devnode->num;
+ if (rc > 0)
+ rc = 0;
+ return rc;
+}
+
+int32_t msm_sensor_bayer_power(struct v4l2_subdev *sd, int on)
+{
+ int rc = 0;
+ struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+ mutex_lock(s_ctrl->msm_sensor_mutex);
+ if (!on)
+ rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+ mutex_unlock(s_ctrl->msm_sensor_mutex);
+ return rc;
+}
+
+int32_t msm_sensor_bayer_v4l2_enum_fmt(struct v4l2_subdev *sd,
+ unsigned int index, enum v4l2_mbus_pixelcode *code)
+{
+ struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+
+ if ((unsigned int)index >= s_ctrl->sensor_v4l2_subdev_info_size)
+ return -EINVAL;
+
+ *code = s_ctrl->sensor_v4l2_subdev_info[index].code;
+ return 0;
+}
+
+int32_t msm_sensor_bayer_v4l2_s_ctrl(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int rc = -1, i = 0;
+ struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+ struct msm_sensor_v4l2_ctrl_info_t *v4l2_ctrl =
+ s_ctrl->msm_sensor_v4l2_ctrl_info;
+
+ CDBG("%s\n", __func__);
+ CDBG("%d\n", ctrl->id);
+ if (v4l2_ctrl == NULL)
+ return rc;
+ for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+ if (v4l2_ctrl[i].ctrl_id == ctrl->id) {
+ if (v4l2_ctrl[i].s_v4l2_ctrl != NULL) {
+ CDBG("\n calling msm_sensor_s_ctrl_by_enum\n");
+ rc = v4l2_ctrl[i].s_v4l2_ctrl(
+ s_ctrl,
+ &s_ctrl->msm_sensor_v4l2_ctrl_info[i],
+ ctrl->value);
+ }
+ break;
+ }
+ }
+
+ return rc;
+}
+
+int32_t msm_sensor_bayer_v4l2_query_ctrl(
+ struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
+{
+ int rc = -1, i = 0;
+ struct msm_sensor_ctrl_t *s_ctrl =
+ (struct msm_sensor_ctrl_t *) sd->dev_priv;
+
+ CDBG("%s\n", __func__);
+ CDBG("%s id: %d\n", __func__, qctrl->id);
+
+ if (s_ctrl->msm_sensor_v4l2_ctrl_info == NULL)
+ return rc;
+
+ for (i = 0; i < s_ctrl->num_v4l2_ctrl; i++) {
+ if (s_ctrl->msm_sensor_v4l2_ctrl_info[i].ctrl_id == qctrl->id) {
+ qctrl->minimum =
+ s_ctrl->msm_sensor_v4l2_ctrl_info[i].min;
+ qctrl->maximum =
+ s_ctrl->msm_sensor_v4l2_ctrl_info[i].max;
+ qctrl->flags = 1;
+ rc = 0;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+int msm_sensor_bayer_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+ struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value)
+{
+ int rc = 0;
+ CDBG("%s enter\n", __func__);
+ rc = msm_sensor_write_enum_conf_array(
+ s_ctrl->sensor_i2c_client,
+ ctrl_info->enum_cfg_settings, value);
+ return rc;
+}
+
diff --git a/drivers/media/video/msm/sensors/msm_sensor_bayer.h b/drivers/media/video/msm/sensors/msm_sensor_bayer.h
new file mode 100644
index 0000000..d12244b
--- /dev/null
+++ b/drivers/media/video/msm/sensors/msm_sensor_bayer.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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 and
+ * only 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.
+ */
+
+#ifndef MSM_SENSOR_BAYER_H
+#define MSM_SENSOR_BAYER_H
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <mach/camera.h>
+#include <mach/gpio.h>
+#include <media/msm_camera.h>
+#include <media/v4l2-subdev.h>
+#include "msm_camera_i2c.h"
+#include "msm_camera_eeprom.h"
+#include "msm_sensor_common.h"
+
+struct sensor_driver_t {
+ struct platform_driver *platform_pdriver;
+ int32_t (*platform_probe)(struct platform_device *pdev);
+};
+
+int32_t msm_sensor_bayer_config(struct msm_sensor_ctrl_t *s_ctrl,
+ void __user *argp);
+int32_t msm_sensor_bayer_power_up(struct msm_sensor_ctrl_t *s_ctrl);
+int32_t msm_sensor_bayer_power_down(struct msm_sensor_ctrl_t *s_ctrl);
+
+int32_t msm_sensor_bayer_match_id(struct msm_sensor_ctrl_t *s_ctrl);
+int msm_sensor_bayer_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+int32_t msm_sensor_delay_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+int32_t msm_sensor_bayer_power(struct v4l2_subdev *sd, int on);
+
+int32_t msm_sensor_bayer_v4l2_s_ctrl(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl);
+
+int32_t msm_sensor_bayer_v4l2_query_ctrl(
+ struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl);
+
+int msm_sensor_bayer_s_ctrl_by_enum(struct msm_sensor_ctrl_t *s_ctrl,
+ struct msm_sensor_v4l2_ctrl_info_t *ctrl_info, int value);
+
+int msm_sensor_bayer_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+ enum v4l2_mbus_pixelcode *code);
+
+long msm_sensor_bayer_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg);
+
+int32_t msm_sensor_bayer_get_csi_params(struct msm_sensor_ctrl_t *s_ctrl,
+ struct csi_lane_params_t *sensor_output_info);
+
+#define VIDIOC_MSM_SENSOR_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 4, void __user *)
+
+#define VIDIOC_MSM_SENSOR_RELEASE \
+ _IO('V', BASE_VIDIOC_PRIVATE + 11)
+
+#define VIDIOC_MSM_SENSOR_CSID_INFO\
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 12, struct msm_sensor_csi_info *)
+#endif
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.c b/drivers/media/video/msm/sensors/msm_sensor_common.c
new file mode 100644
index 0000000..9dac632
--- /dev/null
+++ b/drivers/media/video/msm/sensors/msm_sensor_common.c
@@ -0,0 +1,18 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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 and
+ * only 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.
+ */
+
+#include "msm_sensor_common.h"
+
+struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct msm_sensor_ctrl_t, sensor_v4l2_subdev);
+}
diff --git a/drivers/media/video/msm/sensors/msm_sensor_common.h b/drivers/media/video/msm/sensors/msm_sensor_common.h
new file mode 100644
index 0000000..3b135e1
--- /dev/null
+++ b/drivers/media/video/msm/sensors/msm_sensor_common.h
@@ -0,0 +1,219 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. 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 and
+ * only 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.
+ */
+
+#ifndef MSM_SENSOR_COMMON_H
+#define MSM_SENSOR_COMMON_H
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/gpio.h>
+#include <mach/camera.h>
+#include <media/msm_camera.h>
+#include <media/v4l2-subdev.h>
+#include "msm_camera_i2c.h"
+#include "msm_camera_eeprom.h"
+#define Q8 0x00000100
+#define Q10 0x00000400
+
+#define MSM_SENSOR_MCLK_8HZ 8000000
+#define MSM_SENSOR_MCLK_16HZ 16000000
+#define MSM_SENSOR_MCLK_24HZ 24000000
+
+#define DEFINE_MSM_MUTEX(mutexname) \
+ static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+
+struct gpio_tlmm_cfg {
+ uint32_t gpio;
+ uint32_t dir;
+ uint32_t pull;
+ uint32_t drvstr;
+};
+
+enum msm_sensor_reg_update {
+ /* Sensor egisters that need to be updated during initialization */
+ MSM_SENSOR_REG_INIT,
+ /* Sensor egisters that needs periodic I2C writes */
+ MSM_SENSOR_UPDATE_PERIODIC,
+ /* All the sensor Registers will be updated */
+ MSM_SENSOR_UPDATE_ALL,
+ /* Not valid update */
+ MSM_SENSOR_UPDATE_INVALID
+};
+
+enum msm_sensor_cam_mode_t {
+ MSM_SENSOR_MODE_2D_RIGHT,
+ MSM_SENSOR_MODE_2D_LEFT,
+ MSM_SENSOR_MODE_3D,
+ MSM_SENSOR_MODE_INVALID
+};
+
+enum msm_camera_power_config_t {
+ REQUEST_GPIO,
+ ENABLE_GPIO,
+ REQUEST_VREG,
+ ENABLE_VREG,
+ CONFIG_CLK,
+ CONFIG_EXT_POWER_CTRL,
+ CONFIG_I2C_MUX,
+};
+
+struct msm_camera_power_seq_t {
+ enum msm_camera_power_config_t power_config;
+ uint32_t delay;
+};
+
+struct msm_sensor_id_info_t {
+ uint16_t sensor_id_reg_addr;
+ uint16_t sensor_id;
+};
+
+struct msm_sensor_reg_t {
+ enum msm_camera_i2c_data_type default_data_type;
+ struct msm_camera_i2c_reg_conf *start_stream_conf;
+ uint8_t start_stream_conf_size;
+ struct msm_camera_i2c_reg_conf *stop_stream_conf;
+ uint8_t stop_stream_conf_size;
+ struct msm_camera_i2c_reg_conf *group_hold_on_conf;
+ uint8_t group_hold_on_conf_size;
+ struct msm_camera_i2c_reg_conf *group_hold_off_conf;
+ uint8_t group_hold_off_conf_size;
+ struct msm_camera_i2c_conf_array *init_settings;
+ uint8_t init_size;
+ struct msm_camera_i2c_conf_array *mode_settings;
+ struct msm_camera_i2c_conf_array *no_effect_settings;
+ struct msm_sensor_output_info_t *output_settings;
+ uint8_t num_conf;
+};
+
+struct v4l2_subdev_info {
+ enum v4l2_mbus_pixelcode code;
+ enum v4l2_colorspace colorspace;
+ uint16_t fmt;
+ uint16_t order;
+};
+
+struct msm_sensor_ctrl_t;
+
+struct msm_sensor_v4l2_ctrl_info_t {
+ uint32_t ctrl_id;
+ int16_t min;
+ int16_t max;
+ int16_t step;
+ struct msm_camera_i2c_enum_conf_array *enum_cfg_settings;
+ int (*s_v4l2_ctrl) (struct msm_sensor_ctrl_t *,
+ struct msm_sensor_v4l2_ctrl_info_t *, int);
+};
+
+struct msm_sensor_fn_t {
+ void (*sensor_start_stream) (struct msm_sensor_ctrl_t *);
+ void (*sensor_stop_stream) (struct msm_sensor_ctrl_t *);
+ void (*sensor_group_hold_on) (struct msm_sensor_ctrl_t *);
+ void (*sensor_group_hold_off) (struct msm_sensor_ctrl_t *);
+
+ int32_t (*sensor_set_fps) (struct msm_sensor_ctrl_t *,
+ struct fps_cfg *);
+ int32_t (*sensor_write_exp_gain) (struct msm_sensor_ctrl_t *,
+ uint16_t, uint32_t);
+ int32_t (*sensor_write_snapshot_exp_gain) (struct msm_sensor_ctrl_t *,
+ uint16_t, uint32_t);
+ int32_t (*sensor_setting) (struct msm_sensor_ctrl_t *,
+ int update_type, int rt);
+ int32_t (*sensor_csi_setting) (struct msm_sensor_ctrl_t *,
+ int update_type, int rt);
+ int32_t (*sensor_set_sensor_mode)
+ (struct msm_sensor_ctrl_t *, int, int);
+ int32_t (*sensor_mode_init) (struct msm_sensor_ctrl_t *,
+ int, struct sensor_init_cfg *);
+ int32_t (*sensor_get_output_info) (struct msm_sensor_ctrl_t *,
+ struct sensor_output_info_t *);
+ int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
+ int (*sensor_power_down)
+ (struct msm_sensor_ctrl_t *);
+ int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
+ int32_t (*sensor_match_id)(struct msm_sensor_ctrl_t *s_ctrl);
+ void (*sensor_adjust_frame_lines) (struct msm_sensor_ctrl_t *s_ctrl);
+ int32_t (*sensor_get_csi_params)(struct msm_sensor_ctrl_t *,
+ struct csi_lane_params_t *);
+};
+
+struct msm_sensor_csi_info {
+ uint8_t is_csic;
+};
+
+enum msm_sensor_state {
+ MSM_SENSOR_POWER_UP,
+ MSM_SENSOR_POWER_DOWN,
+};
+
+struct msm_sensor_eeprom_data {
+ uint8_t *data;
+ uint32_t length;
+};
+
+struct msm_sensor_ctrl_t {
+ struct msm_camera_sensor_info *sensordata;
+ struct i2c_client *msm_sensor_client;
+ struct i2c_driver *sensor_i2c_driver;
+ struct platform_device *pdev;
+ struct msm_camera_i2c_client *sensor_i2c_client;
+ uint16_t sensor_i2c_addr;
+ enum msm_camera_vreg_name_t *vreg_seq;
+ int num_vreg_seq;
+ struct msm_camera_power_seq_t *power_seq;
+ int num_power_seq;
+
+ struct msm_sensor_output_reg_addr_t *sensor_output_reg_addr;
+ struct msm_sensor_id_info_t *sensor_id_info;
+ struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info;
+ struct msm_sensor_reg_t *msm_sensor_reg;
+ struct msm_sensor_v4l2_ctrl_info_t *msm_sensor_v4l2_ctrl_info;
+ uint16_t num_v4l2_ctrl;
+ uint8_t is_csic;
+
+ uint16_t curr_line_length_pclk;
+ uint16_t curr_frame_length_lines;
+
+ uint32_t fps_divider;
+ enum msm_sensor_resolution_t curr_res;
+ enum msm_sensor_cam_mode_t cam_mode;
+
+ struct mutex *msm_sensor_mutex;
+
+ struct v4l2_subdev sensor_v4l2_subdev;
+ struct v4l2_subdev_info *sensor_v4l2_subdev_info;
+ uint8_t sensor_v4l2_subdev_info_size;
+ struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
+ struct msm_sensor_fn_t *func_tbl;
+ struct regulator **reg_ptr;
+ struct clk *cam_clk;
+ long clk_rate;
+ enum msm_sensor_state sensor_state;
+ /* Number of frames to delay after start / stop stream in Q10 format.
+ Initialize to -1 for this value to be ignored */
+ int16_t wait_num_frames;
+ /* minimum delay after stop / stop stream in ms */
+ uint16_t min_delay;
+ /* delay (in ms) after power up sequence */
+ uint16_t power_seq_delay;
+ struct msm_sensor_eeprom_data eeprom_data;
+};
+
+struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
+
+#endif
diff --git a/drivers/media/video/msm/sensors/msm_sensor_init.c b/drivers/media/video/msm/sensors/msm_sensor_init.c
new file mode 100644
index 0000000..41c00eb
--- /dev/null
+++ b/drivers/media/video/msm/sensors/msm_sensor_init.c
@@ -0,0 +1,35 @@
+/* Copyright (c) 2012, Code Aurora Forum. 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 and
+ * only 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.
+ *
+ */
+
+#include "msm_sensor.h"
+#include "msm.h"
+#include "msm_sensor_bayer.h"
+#include "imx091.h"
+
+static struct i2c_driver *sensor_i2c_driver[] = {
+ /* back camera */
+ &imx091_i2c_driver,
+ /* front camera */
+};
+
+static int __init msm_sensor_init_module(void)
+{
+ int index = 0;
+ for (index = 0; index < ARRAY_SIZE(sensor_i2c_driver); index++)
+ i2c_add_driver(sensor_i2c_driver[index]);
+ return 0;
+}
+
+module_init(msm_sensor_init_module);
+MODULE_DESCRIPTION("Sensor driver probe");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/sensors/mt9e013_v4l2.c b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
index 69a5498..a38cb57 100644
--- a/drivers/media/video/msm/sensors/mt9e013_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
@@ -325,22 +325,6 @@
},
};
-static struct msm_camera_csi_params mt9e013_csi_params = {
- .data_format = CSI_10BIT,
- .lane_cnt = 2,
- .lane_assign = 0xe4,
- .dpcm_scheme = 0,
- .settle_cnt = 0x18,
-};
-
-static struct msm_camera_csi_params *mt9e013_csi_params_array[] = {
- &mt9e013_csi_params,
- &mt9e013_csi_params,
- &mt9e013_csi_params,
- &mt9e013_csi_params,
- &mt9e013_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t mt9e013_reg_addr = {
.x_output = 0x34C,
.y_output = 0x34E,
@@ -472,7 +456,6 @@
.sensor_config = msm_sensor_config,
.sensor_power_up = msm_sensor_power_up,
.sensor_power_down = msm_sensor_power_down,
- .sensor_get_csi_params = msm_sensor_get_csi_params,
};
static struct msm_sensor_reg_t mt9e013_regs = {
@@ -497,7 +480,6 @@
.sensor_id_info = &mt9e013_id_info,
.sensor_exp_gain_info = &mt9e013_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csic_params = &mt9e013_csi_params_array[0],
.msm_sensor_mutex = &mt9e013_mut,
.sensor_i2c_driver = &mt9e013_i2c_driver,
.sensor_v4l2_subdev_info = mt9e013_subdev_info,
diff --git a/drivers/media/video/msm/sensors/mt9m114_v4l2.c b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
index 806bcc2..cba9538 100644
--- a/drivers/media/video/msm/sensors/mt9m114_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
@@ -1184,30 +1184,6 @@
},
};
-static struct msm_camera_csid_vc_cfg mt9m114_cid_cfg[] = {
- {0, CSI_YUV422_8, CSI_DECODE_8BIT},
- {1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
-};
-
-static struct msm_camera_csi2_params mt9m114_csi_params = {
- .csid_params = {
- .lane_cnt = 1,
- .lut_params = {
- .num_cid = 2,
- .vc_cfg = mt9m114_cid_cfg,
- },
- },
- .csiphy_params = {
- .lane_cnt = 1,
- .settle_cnt = 0x14,
- },
-};
-
-static struct msm_camera_csi2_params *mt9m114_csi_params_array[] = {
- &mt9m114_csi_params,
- &mt9m114_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t mt9m114_reg_addr = {
.x_output = 0xC868,
.y_output = 0xC86A,
@@ -1215,6 +1191,12 @@
.frame_length_lines = 0xC86A,
};
+static enum msm_camera_vreg_name_t mt9m114_veg_seq[] = {
+ CAM_VIO,
+ CAM_VDIG,
+ CAM_VANA,
+};
+
static struct msm_sensor_id_info_t mt9m114_id_info = {
.sensor_id_reg_addr = 0x0,
.sensor_id = 0x2481,
@@ -1288,10 +1270,13 @@
.num_v4l2_ctrl = ARRAY_SIZE(mt9m114_v4l2_ctrl_info),
.sensor_i2c_client = &mt9m114_sensor_i2c_client,
.sensor_i2c_addr = 0x90,
+ .vreg_seq = mt9m114_veg_seq,
+ .num_vreg_seq = ARRAY_SIZE(mt9m114_veg_seq),
.sensor_output_reg_addr = &mt9m114_reg_addr,
.sensor_id_info = &mt9m114_id_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csi_params = &mt9m114_csi_params_array[0],
+ .min_delay = 30,
+ .power_seq_delay = 60,
.msm_sensor_mutex = &mt9m114_mut,
.sensor_i2c_driver = &mt9m114_i2c_driver,
.sensor_v4l2_subdev_info = mt9m114_subdev_info,
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index e08cd0a..1423063 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -658,34 +658,6 @@
},
};
-static struct msm_camera_csid_vc_cfg ov2720_cid_cfg[] = {
- {0, CSI_RAW10, CSI_DECODE_10BIT},
- {1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
-};
-
-static struct msm_camera_csi2_params ov2720_csi_params = {
- .csid_params = {
- .lane_cnt = 2,
- .lut_params = {
- .num_cid = 2,
- .vc_cfg = ov2720_cid_cfg,
- },
- },
- .csiphy_params = {
- .lane_cnt = 2,
- .settle_cnt = 0x1B,
- },
-};
-
-static struct msm_camera_csi2_params *ov2720_csi_params_array[] = {
- &ov2720_csi_params,
- &ov2720_csi_params,
- &ov2720_csi_params,
- &ov2720_csi_params,
- &ov2720_csi_params,
- &ov2720_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t ov2720_reg_addr = {
.x_output = 0x3808,
.y_output = 0x380a,
@@ -704,6 +676,12 @@
.vert_offset = 6,
};
+static enum msm_camera_vreg_name_t ov2720_veg_seq[] = {
+ CAM_VIO,
+ CAM_VANA,
+ CAM_VDIG,
+};
+
static int32_t ov2720_write_exp_gain(struct msm_sensor_ctrl_t *s_ctrl,
uint16_t gain, uint32_t line)
{
@@ -849,11 +827,12 @@
.msm_sensor_reg = &ov2720_regs,
.sensor_i2c_client = &ov2720_sensor_i2c_client,
.sensor_i2c_addr = 0x6C,
+ .vreg_seq = ov2720_veg_seq,
+ .num_vreg_seq = ARRAY_SIZE(ov2720_veg_seq),
.sensor_output_reg_addr = &ov2720_reg_addr,
.sensor_id_info = &ov2720_id_info,
.sensor_exp_gain_info = &ov2720_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csi_params = &ov2720_csi_params_array[0],
.msm_sensor_mutex = &ov2720_mut,
.sensor_i2c_driver = &ov2720_i2c_driver,
.sensor_v4l2_subdev_info = ov2720_subdev_info,
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index d192563..021c6f5 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -343,14 +343,6 @@
ARRAY_SIZE(ov5647_zsl_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
};
-static struct msm_camera_csi_params ov5647_csi_params = {
- .data_format = CSI_8BIT,
- .lane_cnt = 2,
- .lane_assign = 0xe4,
- .dpcm_scheme = 0,
- .settle_cnt = 10,
-};
-
static struct v4l2_subdev_info ov5647_subdev_info[] = {
{
.code = V4L2_MBUS_FMT_SBGGR10_1X10,
@@ -417,14 +409,6 @@
.frame_length_lines = 0x380E,
};
-static struct msm_camera_csi_params *ov5647_csi_params_array[] = {
- &ov5647_csi_params, /* Snapshot */
- &ov5647_csi_params, /* Preview */
- &ov5647_csi_params, /* 60fps */
- &ov5647_csi_params, /* 90fps */
- &ov5647_csi_params, /* ZSL */
-};
-
static struct msm_sensor_id_info_t ov5647_id_info = {
.sensor_id_reg_addr = 0x300a,
.sensor_id = 0x5647,
@@ -733,13 +717,15 @@
static int32_t vfe_clk = 266667000;
-int32_t ov5647_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
- int update_type, int res)
+static void ov5647_stop_stream(struct msm_sensor_ctrl_t *s_ctrl)
{
- int32_t rc = 0;
- static int csi_config;
- s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
- if (csi_config == 0 || res == 0)
+ msm_camera_i2c_write_tbl(
+ s_ctrl->sensor_i2c_client,
+ s_ctrl->msm_sensor_reg->stop_stream_conf,
+ s_ctrl->msm_sensor_reg->stop_stream_conf_size,
+ s_ctrl->msm_sensor_reg->default_data_type);
+
+ if (s_ctrl->curr_res == MSM_SENSOR_RES_FULL)
msleep(66);
else
msleep(266);
@@ -748,37 +734,31 @@
s_ctrl->sensor_i2c_client,
0x4800, 0x25,
MSM_CAMERA_I2C_BYTE_DATA);
+}
+
+int32_t ov5647_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
+ int update_type, int res)
+{
+ int32_t rc = 0;
if (update_type == MSM_SENSOR_REG_INIT) {
CDBG("Register INIT\n");
- s_ctrl->curr_csi_params = NULL;
+ s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
msm_camera_i2c_write(
s_ctrl->sensor_i2c_client,
0x103, 0x1,
MSM_CAMERA_I2C_BYTE_DATA);
msm_sensor_enable_debugfs(s_ctrl);
msm_sensor_write_init_settings(s_ctrl);
- csi_config = 0;
} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
CDBG("PERIODIC : %d\n", res);
msm_sensor_write_conf_array(
s_ctrl->sensor_i2c_client,
s_ctrl->msm_sensor_reg->mode_settings, res);
msleep(30);
- if (!csi_config) {
- s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
- CDBG("CSI config in progress\n");
- v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
- NOTIFY_CSIC_CFG,
- s_ctrl->curr_csic_params);
- CDBG("CSI config is done\n");
- mb();
- msleep(30);
- csi_config = 1;
msm_camera_i2c_write(
s_ctrl->sensor_i2c_client,
0x100, 0x1,
MSM_CAMERA_I2C_BYTE_DATA);
- }
msm_camera_i2c_write(
s_ctrl->sensor_i2c_client,
0x4800, 0x4,
@@ -788,14 +768,12 @@
v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
NOTIFY_PCLK_CHANGE,
&vfe_clk);
- s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
- msleep(50);
}
return rc;
}
static struct msm_sensor_fn_t ov5647_func_tbl = {
.sensor_start_stream = msm_sensor_start_stream,
- .sensor_stop_stream = msm_sensor_stop_stream,
+ .sensor_stop_stream = ov5647_stop_stream,
.sensor_group_hold_on = msm_sensor_group_hold_on,
.sensor_group_hold_off = msm_sensor_group_hold_off,
.sensor_set_fps = msm_sensor_set_fps,
@@ -808,7 +786,6 @@
.sensor_config = msm_sensor_config,
.sensor_power_up = ov5647_sensor_power_up,
.sensor_power_down = ov5647_sensor_power_down,
- .sensor_get_csi_params = msm_sensor_get_csi_params,
};
static struct msm_sensor_reg_t ov5647_regs = {
@@ -837,7 +814,6 @@
.sensor_id_info = &ov5647_id_info,
.sensor_exp_gain_info = &ov5647_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csic_params = &ov5647_csi_params_array[0],
.msm_sensor_mutex = &ov5647_mut,
.sensor_i2c_driver = &ov5647_i2c_driver,
.sensor_v4l2_subdev_info = ov5647_subdev_info,
diff --git a/drivers/media/video/msm/sensors/ov7692_v4l2.c b/drivers/media/video/msm/sensors/ov7692_v4l2.c
index 71d436e..e0d4b53f 100644
--- a/drivers/media/video/msm/sensors/ov7692_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov7692_v4l2.c
@@ -821,18 +821,6 @@
};
-static struct msm_camera_csi_params ov7692_csi_params = {
- .data_format = CSI_8BIT,
- .lane_cnt = 1,
- .lane_assign = 0xe4,
- .dpcm_scheme = 0,
- .settle_cnt = 0x14,
-};
-
-static struct msm_camera_csi_params *ov7692_csi_params_array[] = {
- &ov7692_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t ov7692_reg_addr = {
.x_output = 0xCC,
.y_output = 0xCE,
@@ -899,7 +887,6 @@
.sensor_config = msm_sensor_config,
.sensor_power_up = msm_sensor_power_up,
.sensor_power_down = msm_sensor_power_down,
- .sensor_get_csi_params = msm_sensor_get_csi_params,
};
static struct msm_sensor_reg_t ov7692_regs = {
@@ -925,7 +912,6 @@
.sensor_output_reg_addr = &ov7692_reg_addr,
.sensor_id_info = &ov7692_id_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csic_params = &ov7692_csi_params_array[0],
.msm_sensor_mutex = &ov7692_mut,
.sensor_i2c_driver = &ov7692_i2c_driver,
.sensor_v4l2_subdev_info = ov7692_subdev_info,
diff --git a/drivers/media/video/msm/sensors/ov8825_v4l2.c b/drivers/media/video/msm/sensors/ov8825_v4l2.c
index 1ae3dfd..092ee72 100644
--- a/drivers/media/video/msm/sensors/ov8825_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov8825_v4l2.c
@@ -510,19 +510,6 @@
},
};
-static struct msm_camera_csi_params ov8825_csi_params = {
- .data_format = CSI_10BIT,
- .lane_cnt = 2,
- .lane_assign = 0xe4,
- .dpcm_scheme = 0,
- .settle_cnt = 14,
-};
-
-static struct msm_camera_csi_params *ov8825_csi_params_array[] = {
- &ov8825_csi_params,
- &ov8825_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t ov8825_reg_addr = {
.x_output = 0x3808,
.y_output = 0x380a,
@@ -868,13 +855,10 @@
int update_type, int res)
{
int32_t rc = 0;
- static int csi_config;
- s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
- msleep(30);
if (update_type == MSM_SENSOR_REG_INIT) {
CDBG("Register INIT\n");
- s_ctrl->curr_csi_params = NULL;
+ s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
msm_sensor_enable_debugfs(s_ctrl);
msm_sensor_write_init_settings(s_ctrl);
CDBG("Update OTP\n");
@@ -885,30 +869,15 @@
usleep_range(10000, 11000);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x0,
MSM_CAMERA_I2C_BYTE_DATA);
- csi_config = 0;
} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
CDBG("PERIODIC : %d\n", res);
msm_sensor_write_conf_array(
s_ctrl->sensor_i2c_client,
s_ctrl->msm_sensor_reg->mode_settings, res);
msleep(30);
- if (!csi_config) {
- s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
- CDBG("CSI config in progress\n");
- v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
- NOTIFY_CSIC_CFG,
- s_ctrl->curr_csic_params);
- CDBG("CSI config is done\n");
- mb();
- msleep(30);
- csi_config = 1;
- }
v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
NOTIFY_PCLK_CHANGE,
&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
-
- s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
- msleep(50);
}
return rc;
}
@@ -955,7 +924,6 @@
.sensor_id_info = &ov8825_id_info,
.sensor_exp_gain_info = &ov8825_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csic_params = &ov8825_csi_params_array[0],
.msm_sensor_mutex = &ov8825_mut,
.sensor_i2c_driver = &ov8825_i2c_driver,
.sensor_v4l2_subdev_info = ov8825_subdev_info,
diff --git a/drivers/media/video/msm/sensors/ov9726_v4l2.c b/drivers/media/video/msm/sensors/ov9726_v4l2.c
index 27a8b38..50c13c6 100644
--- a/drivers/media/video/msm/sensors/ov9726_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov9726_v4l2.c
@@ -155,18 +155,6 @@
},
};
-static struct msm_camera_csi_params ov9726_csi_params = {
- .data_format = CSI_10BIT,
- .lane_cnt = 1,
- .lane_assign = 0xe4,
- .dpcm_scheme = 0,
- .settle_cnt = 7,
-};
-
-static struct msm_camera_csi_params *ov9726_csi_params_array[] = {
- &ov9726_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t ov9726_reg_addr = {
.x_output = 0x034c,
.y_output = 0x034e,
@@ -236,7 +224,6 @@
.sensor_config = msm_sensor_config,
.sensor_power_up = msm_sensor_power_up,
.sensor_power_down = msm_sensor_power_down,
- .sensor_get_csi_params = msm_sensor_get_csi_params,
};
static struct msm_sensor_reg_t ov9726_regs = {
@@ -265,7 +252,6 @@
.sensor_id_info = &ov9726_id_info,
.sensor_exp_gain_info = &ov9726_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csic_params = &ov9726_csi_params_array[0],
.msm_sensor_mutex = &ov9726_mut,
.sensor_i2c_driver = &ov9726_i2c_driver,
.sensor_v4l2_subdev_info = ov9726_subdev_info,
diff --git a/drivers/media/video/msm/sensors/s5k3l1yx.c b/drivers/media/video/msm/sensors/s5k3l1yx.c
index 64b004e..fda59db 100644
--- a/drivers/media/video/msm/sensors/s5k3l1yx.c
+++ b/drivers/media/video/msm/sensors/s5k3l1yx.c
@@ -536,53 +536,6 @@
},
};
-static struct msm_camera_csid_vc_cfg s5k3l1yx_cid_cfg[] = {
- {0, CSI_RAW10, CSI_DECODE_10BIT},
- {1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
-};
-
-static struct msm_camera_csi2_params s5k3l1yx_csi_params = {
- .csid_params = {
- .lane_cnt = 4,
- .lut_params = {
- .num_cid = ARRAY_SIZE(s5k3l1yx_cid_cfg),
- .vc_cfg = s5k3l1yx_cid_cfg,
- },
- },
- .csiphy_params = {
- .lane_cnt = 4,
- .settle_cnt = 0x1B,
- },
-};
-
-static struct msm_camera_csid_vc_cfg s5k3l1yx_cid_dpcm_cfg[] = {
- {0, CSI_RAW8, CSI_DECODE_DPCM_10_8_10},
-};
-
-static struct msm_camera_csi2_params s5k3l1yx_csi_dpcm_params = {
- .csid_params = {
- .lane_assign = 0xe4,
- .lane_cnt = 4,
- .lut_params = {
- .num_cid = ARRAY_SIZE(s5k3l1yx_cid_dpcm_cfg),
- .vc_cfg = s5k3l1yx_cid_dpcm_cfg,
- },
- },
- .csiphy_params = {
- .lane_cnt = 4,
- .settle_cnt = 0x1B,
- },
-};
-
-static struct msm_camera_csi2_params *s5k3l1yx_csi_params_array[] = {
- &s5k3l1yx_csi_params,
- &s5k3l1yx_csi_params,
- &s5k3l1yx_csi_params,
- &s5k3l1yx_csi_params,
- &s5k3l1yx_csi_params,
- &s5k3l1yx_csi_dpcm_params,
-};
-
static struct msm_sensor_output_reg_addr_t s5k3l1yx_reg_addr = {
.x_output = 0x34C,
.y_output = 0x34E,
@@ -590,6 +543,13 @@
.frame_length_lines = 0x340,
};
+static enum msm_camera_vreg_name_t s5k3l1yx_veg_seq[] = {
+ CAM_VDIG,
+ CAM_VANA,
+ CAM_VIO,
+ CAM_VAF,
+};
+
static struct msm_sensor_id_info_t s5k3l1yx_id_info = {
.sensor_id_reg_addr = 0x0,
.sensor_id = 0x3121,
@@ -717,11 +677,12 @@
.msm_sensor_reg = &s5k3l1yx_regs,
.sensor_i2c_client = &s5k3l1yx_sensor_i2c_client,
.sensor_i2c_addr = 0x6E,
+ .vreg_seq = s5k3l1yx_veg_seq,
+ .num_vreg_seq = ARRAY_SIZE(s5k3l1yx_veg_seq),
.sensor_output_reg_addr = &s5k3l1yx_reg_addr,
.sensor_id_info = &s5k3l1yx_id_info,
.sensor_exp_gain_info = &s5k3l1yx_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csi_params = &s5k3l1yx_csi_params_array[0],
.msm_sensor_mutex = &s5k3l1yx_mut,
.sensor_i2c_driver = &s5k3l1yx_i2c_driver,
.sensor_v4l2_subdev_info = s5k3l1yx_subdev_info,
diff --git a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
index e90390e..8cdadd8 100644
--- a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
+++ b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
@@ -211,19 +211,6 @@
},
};
-static struct msm_camera_csi_params s5k4e1_csi_params = {
- .data_format = CSI_10BIT,
- .lane_cnt = 1,
- .lane_assign = 0xe4,
- .dpcm_scheme = 0,
- .settle_cnt = 24,
-};
-
-static struct msm_camera_csi_params *s5k4e1_csi_params_array[] = {
- &s5k4e1_csi_params,
- &s5k4e1_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t s5k4e1_reg_addr = {
.x_output = 0x034C,
.y_output = 0x034E,
@@ -487,7 +474,6 @@
.sensor_config = msm_sensor_config,
.sensor_power_up = msm_sensor_power_up,
.sensor_power_down = msm_sensor_power_down,
- .sensor_get_csi_params = msm_sensor_get_csi_params,
};
static struct msm_sensor_reg_t s5k4e1_regs = {
@@ -516,7 +502,6 @@
.sensor_id_info = &s5k4e1_id_info,
.sensor_exp_gain_info = &s5k4e1_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csic_params = &s5k4e1_csi_params_array[0],
.msm_sensor_mutex = &s5k4e1_mut,
.sensor_i2c_driver = &s5k4e1_i2c_driver,
.sensor_v4l2_subdev_info = s5k4e1_subdev_info,
diff --git a/drivers/media/video/msm/sensors/vx6953.c b/drivers/media/video/msm/sensors/vx6953.c
index b43782c..ddc6cee 100644
--- a/drivers/media/video/msm/sensors/vx6953.c
+++ b/drivers/media/video/msm/sensors/vx6953.c
@@ -848,19 +848,6 @@
},
};
-static struct msm_camera_csi_params vx6953_csi_params = {
- .data_format = CSI_8BIT,
- .lane_cnt = 1,
- .lane_assign = 0xe4,
- .dpcm_scheme = 0,
- .settle_cnt = 7,
-};
-
-static struct msm_camera_csi_params *vx6953_csi_params_array[] = {
- &vx6953_csi_params,
- &vx6953_csi_params,
-};
-
static struct msm_sensor_output_reg_addr_t vx6953_reg_addr = {
.x_output = 0x034C,
.y_output = 0x034E,
@@ -1880,13 +1867,6 @@
vx6953_s_ctrl.msm_sensor_reg->
default_data_type);
-
- vx6953_s_ctrl.curr_csic_params =
- vx6953_s_ctrl.csic_params[0];
- v4l2_subdev_notify(&vx6953_s_ctrl.sensor_v4l2_subdev,
- NOTIFY_CSIC_CFG,
- vx6953_s_ctrl.curr_csic_params);
-
msleep(vx6953_stm5m0edof_delay_msecs_stdby);
if (rt == RES_PREVIEW) {
CDBG("%s write mode_tbl for preview\n",
@@ -2042,7 +2022,6 @@
.sensor_id_info = &vx6953_id_info,
.sensor_exp_gain_info = &vx6953_exp_gain_info,
.cam_mode = MSM_SENSOR_MODE_INVALID,
- .csic_params = &vx6953_csi_params_array[0],
.msm_sensor_mutex = &vx6953_mut,
.sensor_i2c_driver = &vx6953_i2c_driver,
.sensor_v4l2_subdev_info = vx6953_subdev_info,
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 0919799..f8c102f 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -288,7 +288,7 @@
/* send control command to config and wait for results*/
static int msm_server_control(struct msm_cam_server_dev *server_dev,
- struct msm_ctrl_cmd *out)
+ uint32_t id, struct msm_ctrl_cmd *out)
{
int rc = 0;
void *value;
@@ -326,7 +326,7 @@
server_dev->server_queue[out->queue_idx].evt_id =
server_dev->server_evt_id;
v4l2_evt.type = V4L2_EVENT_PRIVATE_START + MSM_CAM_RESP_V4L2;
- v4l2_evt.id = 0;
+ v4l2_evt.id = id;
v4l2_evt.u.data[0] = out->queue_idx;
/* setup event object to transfer the command; */
isp_event->resptype = MSM_CAM_RESP_V4L2;
@@ -409,6 +409,49 @@
return rc;
}
+int msm_server_private_general(struct msm_cam_v4l2_device *pcam,
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr)
+{
+ struct msm_ctrl_cmd ctrlcmd;
+ void *temp_data;
+ int rc;
+ temp_data = kzalloc(ioctl_ptr->len, GFP_KERNEL);
+ if (!temp_data) {
+ pr_err("%s could not allocate memory\n", __func__);
+ rc = -ENOMEM;
+ goto end;
+ }
+ if (copy_from_user((void *)temp_data,
+ (void __user *)ioctl_ptr->ioctl_ptr,
+ ioctl_ptr->len)) {
+ ERR_COPY_FROM_USER();
+ rc = -EFAULT;
+ goto copy_from_user_failed;
+ }
+
+ mutex_lock(&pcam->vid_lock);
+ ctrlcmd.type = MSM_V4L2_PRIVATE_CMD;
+ ctrlcmd.length = ioctl_ptr->len;
+ ctrlcmd.value = temp_data;
+ ctrlcmd.timeout_ms = 1000;
+ ctrlcmd.status = ioctl_ptr->id;
+ ctrlcmd.vnode_id = pcam->vnode_id;
+ ctrlcmd.queue_idx = pcam->server_queue_idx;
+ ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
+ /* send command to config thread in usersspace, and get return value */
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
+ if (rc < 0)
+ pr_err("%s: send event failed\n", __func__);
+ mutex_unlock(&pcam->vid_lock);
+
+ kfree(temp_data);
+ return rc;
+copy_from_user_failed:
+ kfree(temp_data);
+end:
+return rc;
+}
+
int msm_server_get_crop(struct msm_cam_v4l2_device *pcam,
int idx, struct v4l2_crop *crop)
{
@@ -428,7 +471,7 @@
pcam->server_queue_idx];
/* send command to config thread in userspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
D("%s: rc = %d\n", __func__, rc);
return rc;
@@ -452,7 +495,7 @@
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[idx];
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
return rc;
}
@@ -474,7 +517,7 @@
pcam->server_queue_idx];
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
return rc;
}
@@ -520,7 +563,7 @@
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
if (rc >= 0) {
pcam->dev_inst[idx]->vid_fmt = *pfmt;
@@ -586,7 +629,7 @@
ctrlcmd.queue_idx = pcam->server_queue_idx;
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
if (rc >= 0) {
pcam->dev_inst[idx]->vid_fmt = *pfmt;
pcam->dev_inst[idx]->sensor_pxlcode
@@ -617,7 +660,7 @@
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
return rc;
}
@@ -638,7 +681,7 @@
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
return rc;
}
@@ -696,7 +739,7 @@
ctrlcmd.queue_idx = pcam->server_queue_idx;
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
D("%s: msm_server_control rc=%d\n", __func__, rc);
if (rc == 0) {
if (tmp_cmd.value && tmp_cmd.length > 0 &&
@@ -750,7 +793,7 @@
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
return rc;
}
@@ -780,7 +823,7 @@
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
/* send command to config thread in usersspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
ctrl->value = ((struct v4l2_control *)ctrlcmd.value)->value;
@@ -807,7 +850,7 @@
ctrlcmd.config_ident = g_server_dev.config_info.config_dev_id[0];
/* send command to config thread in userspace, and get return value */
- rc = msm_server_control(&g_server_dev, &ctrlcmd);
+ rc = msm_server_control(&g_server_dev, 0, &ctrlcmd);
D("%s: rc = %d\n", __func__, rc);
if (rc >= 0)
@@ -1539,6 +1582,11 @@
interface = PIX_0;
}
break;
+ case NOTIFY_AXI_RDI_SOF_COUNT: {
+ struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
+ interface = msg->rdi_interface;
+ }
+ break;
case NOTIFY_VFE_MSG_STATS:
case NOTIFY_VFE_MSG_COMP_STATS:
case NOTIFY_VFE_CAMIF_ERROR:
@@ -1578,16 +1626,14 @@
switch (notification) {
case NOTIFY_ISP_MSG_EVT:
case NOTIFY_VFE_MSG_OUT:
- case NOTIFY_VFE_SOF_COUNT:
+ case NOTIFY_VFE_PIX_SOF_COUNT:
case NOTIFY_VFE_MSG_STATS:
case NOTIFY_VFE_MSG_COMP_STATS:
case NOTIFY_VFE_BUF_EVT:
p_mctl = msm_cam_server_get_mctl(mctl_handle);
- if (p_mctl->isp_sdev &&
- p_mctl->isp_sdev->isp_notify
- && p_mctl->isp_sdev->sd)
- rc = p_mctl->isp_sdev->isp_notify(
- p_mctl->isp_sdev->sd, notification, arg);
+ if (p_mctl->isp_notify && p_mctl->vfe_sdev)
+ rc = p_mctl->isp_notify(p_mctl,
+ p_mctl->vfe_sdev, notification, arg);
break;
case NOTIFY_VFE_IRQ:{
struct msm_vfe_cfg_cmd cfg_cmd;
@@ -1602,30 +1648,21 @@
case NOTIFY_AXI_IRQ:
rc = v4l2_subdev_call(sd, core, ioctl, VIDIOC_MSM_AXI_IRQ, arg);
break;
+ case NOTIFY_AXI_RDI_SOF_COUNT:
+ p_mctl = msm_cam_server_get_mctl(mctl_handle);
+ if (p_mctl->axi_sdev)
+ rc = v4l2_subdev_call(p_mctl->axi_sdev, core, ioctl,
+ VIDIOC_MSM_AXI_RDI_COUNT_UPDATE, arg);
+ break;
case NOTIFY_PCLK_CHANGE:
p_mctl = v4l2_get_subdev_hostdata(sd);
if (p_mctl->axi_sdev)
rc = v4l2_subdev_call(p_mctl->axi_sdev, video,
s_crystal_freq, *(uint32_t *)arg, 0);
else
- rc = v4l2_subdev_call(p_mctl->isp_sdev->sd, video,
+ rc = v4l2_subdev_call(p_mctl->vfe_sdev, video,
s_crystal_freq, *(uint32_t *)arg, 0);
break;
- case NOTIFY_CSIPHY_CFG:
- p_mctl = v4l2_get_subdev_hostdata(sd);
- rc = v4l2_subdev_call(p_mctl->csiphy_sdev,
- core, ioctl, VIDIOC_MSM_CSIPHY_CFG, arg);
- break;
- case NOTIFY_CSID_CFG:
- p_mctl = v4l2_get_subdev_hostdata(sd);
- rc = v4l2_subdev_call(p_mctl->csid_sdev,
- core, ioctl, VIDIOC_MSM_CSID_CFG, arg);
- break;
- case NOTIFY_CSIC_CFG:
- p_mctl = v4l2_get_subdev_hostdata(sd);
- rc = v4l2_subdev_call(p_mctl->csic_sdev,
- core, ioctl, VIDIOC_MSM_CSIC_CFG, arg);
- break;
case NOTIFY_GESTURE_EVT:
rc = v4l2_subdev_call(g_server_dev.gesture_device,
core, ioctl, VIDIOC_MSM_GESTURE_EVT, arg);
@@ -2112,7 +2149,6 @@
}
cam_hw_idx = MSM_CAM_HW_VFE0 + index;
g_server_dev.vfe_device[index] = sd;
- g_server_dev.isp_subdev[index]->sd = sd;
if (g_server_dev.irqr_device) {
g_server_dev.subdev_table[cam_hw_idx] = sd;
err = msm_cam_server_fill_sdev_irqnum(cam_hw_idx,
@@ -2595,21 +2631,10 @@
return rc;
}
-static struct msm_isp_ops *find_isp_op(struct v4l2_subdev *sdev)
-{
- int i;
- for (i = 0; i < g_server_dev.config_info.num_config_nodes; i++) {
- if (g_server_dev.isp_subdev[i]->sd == sdev)
- return g_server_dev.isp_subdev[i];
- }
- return NULL;
-}
-
static int msm_set_mctl_subdev(struct msm_cam_media_controller *pmctl,
struct msm_mctl_set_sdev_data *set_data)
{
int rc = 0;
- struct v4l2_subdev *vfe_sdev = NULL;
struct v4l2_subdev *temp_sdev = NULL;
switch (set_data->sdev_type) {
case CSIPHY_DEV:
@@ -2633,11 +2658,9 @@
temp_sdev = pmctl->ispif_sdev;
break;
case VFE_DEV:
- vfe_sdev = msm_cam_find_subdev_node
+ pmctl->vfe_sdev = msm_cam_find_subdev_node
(&g_server_dev.vfe_device[0], set_data->revision);
- temp_sdev = vfe_sdev;
- pmctl->isp_sdev = find_isp_op(vfe_sdev);
- pmctl->isp_sdev->sd = vfe_sdev;
+ temp_sdev = pmctl->vfe_sdev;
break;
case AXI_DEV:
pmctl->axi_sdev = msm_cam_find_subdev_node
@@ -2678,7 +2701,7 @@
pmctl->ispif_sdev = NULL;
break;
case VFE_DEV:
- pmctl->isp_sdev = NULL;
+ pmctl->vfe_sdev = NULL;
break;
case AXI_DEV:
pmctl->axi_sdev = NULL;
@@ -3001,12 +3024,6 @@
put logic here later to know how many configs to create*/
g_server_dev.config_info.num_config_nodes = 2;
- rc = msm_isp_init_module(g_server_dev.config_info.num_config_nodes);
- if (rc < 0) {
- pr_err("Failed to initialize isp\n");
- return rc;
- }
-
if (!msm_class) {
rc = alloc_chrdev_region(&msm_devno, 0,
g_server_dev.config_info.num_config_nodes+1, "msm_camera");
@@ -3042,13 +3059,11 @@
}
}
- msm_isp_register(&g_server_dev);
return rc;
}
static int __exit msm_camera_exit(struct platform_device *pdev)
{
- msm_isp_unregister(&g_server_dev);
return 0;
}
diff --git a/drivers/media/video/msm/server/msm_cam_server.h b/drivers/media/video/msm/server/msm_cam_server.h
index 229e9c9..42900f3 100644
--- a/drivers/media/video/msm/server/msm_cam_server.h
+++ b/drivers/media/video/msm/server/msm_cam_server.h
@@ -37,6 +37,8 @@
int32_t msm_find_free_queue(void);
int msm_server_proc_ctrl_cmd(struct msm_cam_v4l2_device *pcam,
struct msm_camera_v4l2_ioctl_t *ioctl_ptr, int is_set_cmd);
+int msm_server_private_general(struct msm_cam_v4l2_device *pcam,
+ struct msm_camera_v4l2_ioctl_t *ioctl_ptr);
int msm_server_s_ctrl(struct msm_cam_v4l2_device *pcam,
struct v4l2_control *ctrl);
int msm_server_g_ctrl(struct msm_cam_v4l2_device *pcam,
@@ -65,5 +67,5 @@
int msm_cam_server_update_irqmap(
struct msm_cam_server_irqmap_entry *entry);
int msm_cam_server_config_interface_map(u32 extendedmode,
- uint32_t mctl_handle);
+ uint32_t mctl_handle);
#endif /* _MSM_CAM_SERVER_H */
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index c8d22d4..84a36b9 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -412,36 +412,116 @@
}
}
-static void axi_disable_irq(struct axi_ctrl_t *axi_ctrl)
+static void axi_enable_irq(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t irq_mask, irq_mask1;
+ uint16_t vfe_operation_mode =
+ share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+ irq_mask1 =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+
+ irq_mask1 |= VFE_IMASK_WHILE_STOPPING_1;
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
+ irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
+ irq_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
+
+ msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+
+ if (vfe_operation_mode) {
+ irq_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ irq_mask |= 0x00000021;
+ if (share_ctrl->stats_comp)
+ irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
+ else
+ irq_mask |= 0x000FE000;
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ atomic_set(&share_ctrl->vstate, 1);
+ }
+ atomic_set(&share_ctrl->handle_common_irq, 1);
+}
+
+static void axi_disable_irq(struct vfe_share_ctrl_t *share_ctrl)
{
/* disable all interrupts. */
- msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
- axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
- msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
- axi_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
- /* clear all pending interrupts*/
- msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
- axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
- msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
- axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
- /* Ensure the write order while writing
- to the command register using the barrier */
- msm_camera_io_w_mb(1,
- axi_ctrl->share_ctrl->vfebase + VFE_IRQ_CMD);
+ uint32_t irq_mask, irq_mask1;
+ uint16_t vfe_operation_mode =
+ share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ irq_mask1 =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+ irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK);
+ msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+ msm_camera_io_w(VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+ }
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ irq_mask1 =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+ irq_mask1 &= ~(VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK);
+ msm_camera_io_w(irq_mask1, share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+ msm_camera_io_w(VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+ }
+ if (vfe_operation_mode) {
+ atomic_set(&share_ctrl->vstate, 0);
+ irq_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ irq_mask &= ~(0x00000021);
+ if (share_ctrl->stats_comp)
+ irq_mask &= ~(VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK);
+ else
+ irq_mask &= ~0x000FE000;
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ }
+
+ if (share_ctrl->axi_ref_cnt == 1) {
+ atomic_set(&share_ctrl->handle_common_irq, 0);
+ msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+ share_ctrl->vfebase + VFE_IRQ_MASK_0);
+ msm_camera_io_w(VFE_DISABLE_ALL_IRQS,
+ share_ctrl->vfebase + VFE_IRQ_MASK_1);
+
+ /* clear all pending interrupts*/
+ msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_0);
+ msm_camera_io_w(VFE_CLEAR_ALL_IRQS,
+ share_ctrl->vfebase + VFE_IRQ_CLEAR_1);
+ /* Ensure the write order while writing
+ *to the command register using the barrier */
+ msm_camera_io_w_mb(1,
+ share_ctrl->vfebase + VFE_IRQ_CMD);
+ }
}
static void vfe32_stop(struct vfe32_ctrl_type *vfe32_ctrl)
{
- atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
/* in either continuous or snapshot mode, stop command can be issued
* at any time. stop camif immediately. */
- msm_camera_io_w(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+ msm_camera_io_w(CAMIF_COMMAND_STOP_IMMEDIATELY,
vfe32_ctrl->share_ctrl->vfebase + VFE_CAMIF_COMMAND);
vfe32_ctrl->share_ctrl->operation_mode &=
~(vfe32_ctrl->share_ctrl->current_mode);
+ vfe32_ctrl->share_ctrl->current_mode = 0;
}
static void vfe32_subdev_notify(int id, int path, uint32_t inst_handle,
@@ -560,6 +640,16 @@
}
msm_camera_io_w(bus_cmd, axi_ctrl->share_ctrl->vfebase +
V32_AXI_BUS_CMD_OFF);
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_PIXEL_IF_CFG);
+ if (msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+ V32_GET_HW_VERSION_OFF) ==
+ VFE33_HW_NUMBER) {
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
+ }
return 0;
}
@@ -585,6 +675,8 @@
axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
atomic_set(&axi_ctrl->share_ctrl->vstate, 0);
+ atomic_set(&axi_ctrl->share_ctrl->handle_common_irq, 0);
+ atomic_set(&axi_ctrl->share_ctrl->pix0_update_ack_pending, 0);
atomic_set(&axi_ctrl->share_ctrl->rdi0_update_ack_pending, 0);
atomic_set(&axi_ctrl->share_ctrl->rdi1_update_ack_pending, 0);
atomic_set(&axi_ctrl->share_ctrl->rdi2_update_ack_pending, 0);
@@ -593,40 +685,14 @@
axi_ctrl->share_ctrl->operation_mode = 0;
axi_ctrl->share_ctrl->current_mode = 0;
axi_ctrl->share_ctrl->outpath.output_mode = 0;
+ axi_ctrl->share_ctrl->comp_output_mode = 0;
axi_ctrl->share_ctrl->vfe_capture_count = 0;
/* this is unsigned 32 bit integer. */
axi_ctrl->share_ctrl->vfeFrameId = 0;
-}
-
-static void vfe32_reset_internal_variables(
- struct vfe32_ctrl_type *vfe32_ctrl)
-{
- /* Stats control variables. */
- memset(&(vfe32_ctrl->afbfStatsControl), 0,
- sizeof(struct vfe_stats_control));
-
- memset(&(vfe32_ctrl->awbStatsControl), 0,
- sizeof(struct vfe_stats_control));
-
- memset(&(vfe32_ctrl->aecbgStatsControl), 0,
- sizeof(struct vfe_stats_control));
-
- memset(&(vfe32_ctrl->bhistStatsControl), 0,
- sizeof(struct vfe_stats_control));
-
- memset(&(vfe32_ctrl->ihistStatsControl), 0,
- sizeof(struct vfe_stats_control));
-
- memset(&(vfe32_ctrl->rsStatsControl), 0,
- sizeof(struct vfe_stats_control));
-
- memset(&(vfe32_ctrl->csStatsControl), 0,
- sizeof(struct vfe_stats_control));
-
- vfe32_ctrl->frame_skip_cnt = 31;
- vfe32_ctrl->frame_skip_pattern = 0xffffffff;
- vfe32_ctrl->snapshot_frame_cnt = 0;
+ axi_ctrl->share_ctrl->rdi0FrameId = 0;
+ axi_ctrl->share_ctrl->rdi1FrameId = 0;
+ axi_ctrl->share_ctrl->rdi2FrameId = 0;
}
static void vfe32_program_dmi_cfg(
@@ -685,6 +751,147 @@
vfe32_program_dmi_cfg(NO_MEM_SELECTED, vfe32_ctrl);
}
+static void vfe32_set_default_reg_values(
+ struct vfe32_ctrl_type *vfe32_ctrl)
+{
+ msm_camera_io_w(0x800080,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
+ msm_camera_io_w(0x800080,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
+ /* What value should we program CGC_OVERRIDE to? */
+ msm_camera_io_w(0xFFFFF,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+ /* default frame drop period and pattern */
+ msm_camera_io_w(0x1f,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
+ msm_camera_io_w(0x1f,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
+ msm_camera_io_w(0xFFFFFFFF,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
+ msm_camera_io_w(0xFFFFFFFF,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_FRAMEDROP_ENC_CBCR_PATTERN);
+ msm_camera_io_w(0x1f,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
+ msm_camera_io_w(0x1f,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
+ msm_camera_io_w(0xFFFFFFFF,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
+ msm_camera_io_w(0xFFFFFFFF,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
+ msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MIN);
+ msm_camera_io_w(0xFFFFFF,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MAX);
+
+ /* stats UB config */
+ CDBG("%s: Use bayer stats = %d\n", __func__,
+ vfe32_use_bayer_stats(vfe32_ctrl));
+ if (!vfe32_use_bayer_stats(vfe32_ctrl)) {
+ msm_camera_io_w(0x3980007,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_AEC_BG_UB_CFG);
+ msm_camera_io_w(0x3A00007,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_AF_BF_UB_CFG);
+ msm_camera_io_w(0x3A8000F,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_AWB_UB_CFG);
+ msm_camera_io_w(0x3B80007,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_RS_UB_CFG);
+ msm_camera_io_w(0x3C0001F,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_CS_UB_CFG);
+ msm_camera_io_w(0x3E0001F,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_HIST_UB_CFG);
+ } else {
+ msm_camera_io_w(0x350001F,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_HIST_UB_CFG);
+ msm_camera_io_w(0x370002F,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_AEC_BG_UB_CFG);
+ msm_camera_io_w(0x3A0002F,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_AF_BF_UB_CFG);
+ msm_camera_io_w(0x3D00007,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_RS_UB_CFG);
+ msm_camera_io_w(0x3D8001F,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_CS_UB_CFG);
+ msm_camera_io_w(0x3F80007,
+ vfe32_ctrl->share_ctrl->vfebase +
+ VFE_BUS_STATS_SKIN_BHIST_UB_CFG);
+ }
+ vfe32_reset_dmi_tables(vfe32_ctrl);
+}
+
+static void vfe32_reset_internal_variables(
+ struct vfe32_ctrl_type *vfe32_ctrl)
+{
+ /* Stats control variables. */
+ memset(&(vfe32_ctrl->afbfStatsControl), 0,
+ sizeof(struct vfe_stats_control));
+
+ memset(&(vfe32_ctrl->awbStatsControl), 0,
+ sizeof(struct vfe_stats_control));
+
+ memset(&(vfe32_ctrl->aecbgStatsControl), 0,
+ sizeof(struct vfe_stats_control));
+
+ memset(&(vfe32_ctrl->bhistStatsControl), 0,
+ sizeof(struct vfe_stats_control));
+
+ memset(&(vfe32_ctrl->ihistStatsControl), 0,
+ sizeof(struct vfe_stats_control));
+
+ memset(&(vfe32_ctrl->rsStatsControl), 0,
+ sizeof(struct vfe_stats_control));
+
+ memset(&(vfe32_ctrl->csStatsControl), 0,
+ sizeof(struct vfe_stats_control));
+
+ vfe32_ctrl->frame_skip_cnt = 31;
+ vfe32_ctrl->frame_skip_pattern = 0xffffffff;
+ vfe32_ctrl->snapshot_frame_cnt = 0;
+ vfe32_set_default_reg_values(vfe32_ctrl);
+}
+
+
+static int vfe32_reset(struct vfe32_ctrl_type *vfe32_ctrl)
+{
+ uint32_t irq_mask1, irq_mask;
+ atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
+ msm_camera_io_w(VFE_MODULE_RESET_CMD,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
+ msm_camera_io_w(0,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_RESET);
+
+ irq_mask =
+ msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+ irq_mask &= ~(0x000FE021|VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK);
+
+ msm_camera_io_w(irq_mask, vfe32_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ /* enable reset_ack interrupt. */
+ irq_mask1 = msm_camera_io_r(
+ vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+ irq_mask1 |= VFE_IMASK_WHILE_STOPPING_1;
+ msm_camera_io_w(irq_mask1,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
+ msm_camera_io_w_mb(VFE_ONLY_RESET_CMD,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+
+ return wait_for_completion_interruptible(
+ &vfe32_ctrl->share_ctrl->reset_complete);
+}
+
static int axi_reset(struct axi_ctrl_t *axi_ctrl)
{
axi_reset_internal_variables(axi_ctrl);
@@ -729,7 +936,6 @@
{
uint32_t *p = cmd;
- vfe32_ctrl->share_ctrl->operation_mode = *p;
vfe32_ctrl->share_ctrl->stats_comp = *(++p);
vfe32_ctrl->hfr_mode = *(++p);
@@ -738,19 +944,6 @@
msm_camera_io_w(*(++p),
vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
msm_camera_io_w(*(++p),
- vfe32_ctrl->share_ctrl->vfebase + VFE_PIXEL_IF_CFG);
- if (msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
- V32_GET_HW_VERSION_OFF) ==
- VFE33_HW_NUMBER) {
- msm_camera_io_w(*(++p),
- vfe32_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
- msm_camera_io_w(*(++p),
- vfe32_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
- } else {
- ++p;
- ++p;
- }
- msm_camera_io_w(*(++p),
vfe32_ctrl->share_ctrl->vfebase + VFE_REALIGN_BUF);
msm_camera_io_w(*(++p),
vfe32_ctrl->share_ctrl->vfebase + VFE_CHROMA_UP);
@@ -1063,70 +1256,17 @@
static void vfe32_start_common(struct vfe32_ctrl_type *vfe32_ctrl)
{
- uint32_t irq_mask = 0x00E00021, irq_mask1, reg_update;
uint16_t vfe_operation_mode =
vfe32_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
VFE_OUTPUTS_RDI1);
- vfe32_ctrl->share_ctrl->start_ack_pending = TRUE;
CDBG("VFE opertaion mode = 0x%x, output mode = 0x%x\n",
vfe32_ctrl->share_ctrl->current_mode,
vfe32_ctrl->share_ctrl->outpath.output_mode);
- if (vfe32_ctrl->share_ctrl->stats_comp)
- irq_mask |= VFE_IRQ_STATUS0_STATS_COMPOSIT_MASK;
- else
- irq_mask |= 0x000FE000;
- irq_mask |=
- msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
- msm_camera_io_w(irq_mask,
- vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_0);
- msm_camera_io_w(VFE_IMASK_WHILE_STOPPING_1,
- vfe32_ctrl->share_ctrl->vfebase + VFE_IRQ_MASK_1);
- irq_mask1 =
- msm_camera_io_r(vfe32_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
- reg_update =
- msm_camera_io_r_mb(vfe32_ctrl->share_ctrl->vfebase +
- VFE_REG_UPDATE_CMD);
-
- if (vfe32_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
- irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
- msm_camera_io_w(irq_mask1, vfe32_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
- if (!atomic_cmpxchg(
- &vfe32_ctrl->share_ctrl->rdi0_update_ack_pending,
- 0, 1)) {
- msm_camera_io_w_mb(reg_update|0x2,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_REG_UPDATE_CMD);
- }
- }
- if (vfe32_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
- irq_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
- msm_camera_io_w(irq_mask1, vfe32_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_1);
- if (!atomic_cmpxchg(
- &vfe32_ctrl->share_ctrl->rdi1_update_ack_pending,
- 0, 1)) {
- msm_camera_io_w_mb(reg_update|0x4,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_REG_UPDATE_CMD);
- }
- msm_camera_io_w_mb(reg_update|0x4, vfe32_ctrl->share_ctrl->
- vfebase + VFE_REG_UPDATE_CMD);
- }
if (vfe_operation_mode) {
- msm_camera_io_w_mb(reg_update|0x1, vfe32_ctrl->share_ctrl->
- vfebase + VFE_REG_UPDATE_CMD);
msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
VFE_CAMIF_COMMAND);
}
- vfe32_ctrl->share_ctrl->operation_mode |=
- vfe32_ctrl->share_ctrl->current_mode;
- /* Ensure the write order while writing
- to the command register using the barrier */
- atomic_set(&vfe32_ctrl->share_ctrl->vstate, 1);
}
static int vfe32_start_recording(
@@ -1176,6 +1316,7 @@
struct msm_cam_media_controller *pmctl,
struct vfe32_ctrl_type *vfe32_ctrl)
{
+ vfe32_ctrl->share_ctrl->start_ack_pending = TRUE;
vfe32_start_common(vfe32_ctrl);
msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase + 0x18C);
@@ -1570,7 +1711,8 @@
case VFE_CMD_RESET:
pr_info("vfe32_proc_general: cmdID = %s\n",
vfe32_general_cmd[cmd->id]);
- vfe32_reset_internal_variables(vfe32_ctrl);
+ vfe32_ctrl->share_ctrl->vfe_reset_flag = true;
+ vfe32_reset(vfe32_ctrl);
break;
case VFE_CMD_START:
pr_info("vfe32_proc_general: cmdID = %s\n",
@@ -3026,221 +3168,479 @@
}
+void axi_stop_pix(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t operation_mode =
+ share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+ uint32_t irq_comp_mask, irq_mask;
+ uint32_t reg_update = 0x1;
+
+ irq_comp_mask =
+ msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_COMP_MASK);
+ irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ switch (share_ctrl->cmd_type) {
+ case AXI_CMD_PREVIEW: {
+ switch (operation_mode) {
+ case VFE_OUTPUTS_PREVIEW:
+ case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
+ if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch1]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1);
+ share_ctrl->outpath.output_mode |=
+ VFE32_OUTPUT_MODE_PRIMARY;
+ } else if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch1]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch2]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1 |
+ 0x1 << share_ctrl->outpath.out0.ch2);
+ share_ctrl->outpath.output_mode |=
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+ }
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ break;
+ default:
+ if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch1]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1);
+ share_ctrl->outpath.output_mode |=
+ VFE32_OUTPUT_MODE_SECONDARY;
+ } else if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch1]);
+ msm_camera_io_w(0, share_ctrl->vfebase
+ + vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch2]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1 |
+ 0x1 << share_ctrl->outpath.out1.ch2);
+ share_ctrl->outpath.output_mode |=
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+ }
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ break;
+ }
+ }
+ break;
+ default:
+ if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch1]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ share_ctrl->outpath.output_mode |=
+ VFE32_OUTPUT_MODE_PRIMARY;
+ } else if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch1]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out0.ch2]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out0.ch0 |
+ 0x1 << share_ctrl->outpath.out0.ch1 |
+ 0x1 << share_ctrl->outpath.out0.ch2);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
+ share_ctrl->outpath.output_mode |=
+ VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS;
+ }
+
+ if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->
+ outpath.out1.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ share_ctrl->outpath.output_mode |=
+ VFE32_OUTPUT_MODE_SECONDARY;
+ } else if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch1]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out1.ch2]);
+ irq_comp_mask &= ~(
+ 0x1 << share_ctrl->outpath.out1.ch0 |
+ 0x1 << share_ctrl->outpath.out1.ch1 |
+ 0x1 << share_ctrl->outpath.out1.ch2);
+ irq_mask &= ~VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
+ share_ctrl->outpath.output_mode |=
+ VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS;
+ }
+ break;
+ }
+
+ msm_camera_io_w_mb(reg_update,
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ msm_camera_io_w(irq_comp_mask,
+ share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+}
+
+void axi_stop_rdi0(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t reg_update = 0x2;
+ uint32_t irq_mask;
+ irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out2.ch0]);
+ irq_mask &= ~(0x1 << (share_ctrl->outpath.out2.ch0 +
+ VFE_WM_OFFSET));
+ }
+ msm_camera_io_w_mb(reg_update,
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+}
+
+void axi_stop_rdi1(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t reg_update = 0x4;
+ uint32_t irq_mask;
+ irq_mask = msm_camera_io_r(share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ msm_camera_io_w(1, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[share_ctrl->outpath.out3.ch0]);
+ irq_mask &= ~(0x1 << (share_ctrl->outpath.out3.ch0 +
+ VFE_WM_OFFSET));
+ }
+
+ msm_camera_io_w_mb(reg_update,
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ msm_camera_io_w(irq_mask, share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
+}
+
+void axi_stop_process(struct vfe_share_ctrl_t *share_ctrl)
+{
+ uint32_t operation_mode =
+ share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
+ VFE_OUTPUTS_RDI1);
+
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ axi_stop_rdi0(share_ctrl);
+ share_ctrl->comp_output_mode &= ~VFE32_OUTPUT_MODE_TERTIARY1;
+ }
+ if (share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ axi_stop_rdi1(share_ctrl);
+ share_ctrl->comp_output_mode &= ~VFE32_OUTPUT_MODE_TERTIARY2;
+ }
+ if (operation_mode) {
+ axi_stop_pix(share_ctrl);
+ share_ctrl->comp_output_mode &=
+ ~(share_ctrl->outpath.output_mode);
+ }
+}
+
static void vfe32_process_reg_update_irq(
struct vfe32_ctrl_type *vfe32_ctrl)
{
unsigned long flags;
+ struct vfe_share_ctrl_t *share_ctrl = vfe32_ctrl->share_ctrl;
- if (vfe32_ctrl->share_ctrl->recording_state ==
- VFE_STATE_START_REQUESTED) {
- if (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
- msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch1]);
- } else if (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
- msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out1.ch1]);
- }
- vfe32_ctrl->share_ctrl->recording_state = VFE_STATE_STARTED;
- msm_camera_io_w_mb(1,
- vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- CDBG("start video triggered .\n");
- } else if (vfe32_ctrl->share_ctrl->recording_state ==
- VFE_STATE_STOP_REQUESTED) {
- if (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch1]);
- } else if (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out1.ch1]);
- }
- CDBG("stop video triggered .\n");
- }
-
- spin_lock_irqsave(&vfe32_ctrl->share_ctrl->start_ack_lock, flags);
- if (vfe32_ctrl->share_ctrl->start_ack_pending == TRUE) {
- vfe32_ctrl->share_ctrl->start_ack_pending = FALSE;
- spin_unlock_irqrestore(
- &vfe32_ctrl->share_ctrl->start_ack_lock, flags);
+ if (atomic_cmpxchg(
+ &share_ctrl->pix0_update_ack_pending, 2, 0) == 2) {
+ axi_stop_pix(share_ctrl);
+ msm_camera_io_w_mb(
+ CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+ share_ctrl->vfebase + VFE_CAMIF_COMMAND);
+ axi_disable_irq(share_ctrl);
vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_START_ACK);
- } else {
- spin_unlock_irqrestore(
- &vfe32_ctrl->share_ctrl->start_ack_lock, flags);
- if (vfe32_ctrl->share_ctrl->recording_state ==
- VFE_STATE_STOP_REQUESTED) {
- vfe32_ctrl->share_ctrl->recording_state =
- VFE_STATE_STOPPED;
- /* request a reg update and send STOP_REC_ACK
- * when we process the next reg update irq.
- */
+ share_ctrl->vfeFrameId,
+ MSG_ID_PIX0_UPDATE_ACK);
+ share_ctrl->comp_output_mode &=
+ ~(share_ctrl->outpath.output_mode);
+ share_ctrl->current_mode &=
+ (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
+ } else {
+ if (share_ctrl->recording_state == VFE_STATE_START_REQUESTED) {
+ if (share_ctrl->operation_mode &
+ VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch1]);
+ } else if (share_ctrl->operation_mode &
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out1.ch1]);
+ }
+ share_ctrl->recording_state = VFE_STATE_STARTED;
msm_camera_io_w_mb(1,
- vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- } else if (vfe32_ctrl->share_ctrl->recording_state ==
- VFE_STATE_STOPPED) {
- vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId,
- MSG_ID_STOP_REC_ACK);
- vfe32_ctrl->share_ctrl->recording_state =
- VFE_STATE_IDLE;
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ CDBG("start video triggered .\n");
+ } else if (share_ctrl->recording_state ==
+ VFE_STATE_STOP_REQUESTED) {
+ if (share_ctrl->operation_mode &
+ VFE_OUTPUTS_VIDEO_AND_PREVIEW) {
+ msm_camera_io_w(0,
+ share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(0,
+ share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch1]);
+ } else if (share_ctrl->operation_mode &
+ VFE_OUTPUTS_PREVIEW_AND_VIDEO) {
+ msm_camera_io_w(0,
+ share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out1.ch0]);
+ msm_camera_io_w(0,
+ share_ctrl->vfebase + vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out1.ch1]);
+ }
+ CDBG("stop video triggered .\n");
}
- spin_lock_irqsave(
- &vfe32_ctrl->share_ctrl->update_ack_lock, flags);
- if (vfe32_ctrl->share_ctrl->update_ack_pending == TRUE) {
- vfe32_ctrl->share_ctrl->update_ack_pending = FALSE;
- spin_unlock_irqrestore(
- &vfe32_ctrl->share_ctrl->update_ack_lock,
- flags);
+
+ if (atomic_cmpxchg(
+ &share_ctrl->pix0_update_ack_pending, 1, 0) == 1) {
+ share_ctrl->comp_output_mode |=
+ (share_ctrl->outpath.output_mode
+ & ~(VFE32_OUTPUT_MODE_TERTIARY1|
+ VFE32_OUTPUT_MODE_TERTIARY2));
vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId,
- MSG_ID_UPDATE_ACK);
+ share_ctrl->vfeFrameId, MSG_ID_PIX0_UPDATE_ACK);
+ share_ctrl->current_mode &=
+ (VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI0);
} else {
- spin_unlock_irqrestore(
- &vfe32_ctrl->share_ctrl->update_ack_lock,
- flags);
+ if (share_ctrl->recording_state ==
+ VFE_STATE_STOP_REQUESTED) {
+ share_ctrl->recording_state = VFE_STATE_STOPPED;
+ /* request a reg update and send STOP_REC_ACK
+ * when we process the next reg update irq.
+ */
+ msm_camera_io_w_mb(1, share_ctrl->vfebase +
+ VFE_REG_UPDATE_CMD);
+ } else if (share_ctrl->recording_state ==
+ VFE_STATE_STOPPED) {
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ share_ctrl->vfeFrameId,
+ MSG_ID_STOP_REC_ACK);
+ share_ctrl->recording_state = VFE_STATE_IDLE;
+ }
+ spin_lock_irqsave(
+ &share_ctrl->update_ack_lock,
+ flags);
+ if (share_ctrl->update_ack_pending == TRUE) {
+ share_ctrl->update_ack_pending = FALSE;
+ spin_unlock_irqrestore(
+ &share_ctrl->update_ack_lock, flags);
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ share_ctrl->vfeFrameId,
+ MSG_ID_UPDATE_ACK);
+ } else {
+ spin_unlock_irqrestore(
+ &share_ctrl->update_ack_lock, flags);
+ }
}
- }
- switch (vfe32_ctrl->share_ctrl->liveshot_state) {
- case VFE_STATE_START_REQUESTED:
- CDBG("%s enabling liveshot output\n", __func__);
- if (vfe32_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(1, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch1]);
+ switch (share_ctrl->liveshot_state) {
+ case VFE_STATE_START_REQUESTED:
+ CDBG("%s enabling liveshot output\n", __func__);
+ if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(1, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(1, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch1]);
- vfe32_ctrl->share_ctrl->liveshot_state =
- VFE_STATE_STARTED;
+ share_ctrl->liveshot_state =
+ VFE_STATE_STARTED;
+ }
+ break;
+ case VFE_STATE_STARTED:
+ share_ctrl->vfe_capture_count--;
+ if (!share_ctrl->vfe_capture_count &&
+ (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY)) {
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch1]);
+ }
+ break;
+ case VFE_STATE_STOP_REQUESTED:
+ if (share_ctrl->comp_output_mode &
+ VFE32_OUTPUT_MODE_PRIMARY) {
+ /* Stop requested, stop write masters, and
+ * trigger REG_UPDATE. Send STOP_LS_ACK in
+ * next reg update. */
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch0]);
+ msm_camera_io_w(0, share_ctrl->vfebase +
+ vfe32_AXI_WM_CFG[
+ share_ctrl->outpath.out0.ch1]);
+
+ share_ctrl->liveshot_state = VFE_STATE_STOPPED;
+ msm_camera_io_w_mb(1, share_ctrl->vfebase +
+ VFE_REG_UPDATE_CMD);
+ }
+ break;
+ case VFE_STATE_STOPPED:
+ CDBG("%s Sending STOP_LS ACK\n", __func__);
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ share_ctrl->vfeFrameId, MSG_ID_STOP_LS_ACK);
+ share_ctrl->liveshot_state = VFE_STATE_IDLE;
+ break;
+ default:
+ break;
}
- break;
- case VFE_STATE_STARTED:
- vfe32_ctrl->share_ctrl->vfe_capture_count--;
- if (!vfe32_ctrl->share_ctrl->vfe_capture_count &&
- (vfe32_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY)) {
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch1]);
- }
- break;
- case VFE_STATE_STOP_REQUESTED:
- if (vfe32_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY) {
- /* Stop requested, stop write masters, and
- * trigger REG_UPDATE. Send STOP_LS_ACK in
- * next reg update. */
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch1]);
- vfe32_ctrl->share_ctrl->liveshot_state =
- VFE_STATE_STOPPED;
- msm_camera_io_w_mb(1, vfe32_ctrl->share_ctrl->vfebase +
- VFE_REG_UPDATE_CMD);
- }
- break;
- case VFE_STATE_STOPPED:
- CDBG("%s Sending STOP_LS ACK\n", __func__);
- vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_STOP_LS_ACK);
- vfe32_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE;
- break;
- default:
- break;
- }
-
- if ((vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_THUMB_AND_MAIN) ||
- (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_MAIN_AND_THUMB) ||
- (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_THUMB_AND_JPEG) ||
- (vfe32_ctrl->share_ctrl->operation_mode &
- VFE_OUTPUTS_JPEG_AND_THUMB)) {
- /* in snapshot mode */
- /* later we need to add check for live snapshot mode. */
- if (vfe32_ctrl->frame_skip_pattern & (0x1 <<
- (vfe32_ctrl->snapshot_frame_cnt %
- vfe32_ctrl->frame_skip_cnt))) {
- vfe32_ctrl->share_ctrl->vfe_capture_count--;
- /* if last frame to be captured: */
- if (vfe32_ctrl->share_ctrl->vfe_capture_count == 0) {
- /* stop the bus output:write master enable = 0*/
- if (vfe32_ctrl->share_ctrl->outpath.output_mode
- & VFE32_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(0,
- vfe32_ctrl->share_ctrl->vfebase+
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0,
- vfe32_ctrl->share_ctrl->vfebase+
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out0.ch1]);
- }
- if (vfe32_ctrl->share_ctrl->outpath.output_mode&
+ if ((share_ctrl->operation_mode & VFE_OUTPUTS_THUMB_AND_MAIN) ||
+ (share_ctrl->operation_mode &
+ VFE_OUTPUTS_MAIN_AND_THUMB) ||
+ (share_ctrl->operation_mode &
+ VFE_OUTPUTS_THUMB_AND_JPEG) ||
+ (share_ctrl->operation_mode &
+ VFE_OUTPUTS_JPEG_AND_THUMB)) {
+ /* in snapshot mode */
+ /* later we need to add check for live snapshot mode. */
+ if (vfe32_ctrl->frame_skip_pattern & (0x1 <<
+ (vfe32_ctrl->snapshot_frame_cnt %
+ vfe32_ctrl->frame_skip_cnt))) {
+ share_ctrl->vfe_capture_count--;
+ /* if last frame to be captured: */
+ if (share_ctrl->vfe_capture_count == 0) {
+ /* stop the bus output: */
+ if (share_ctrl->comp_output_mode
+ & VFE32_OUTPUT_MODE_PRIMARY) {
+ msm_camera_io_w(0,
+ share_ctrl->vfebase+
+ vfe32_AXI_WM_CFG[
+ share_ctrl->
+ outpath.out0.ch0]);
+ msm_camera_io_w(0,
+ share_ctrl->vfebase+
+ vfe32_AXI_WM_CFG[
+ share_ctrl->
+ outpath.out0.ch1]);
+ }
+ if (share_ctrl->comp_output_mode &
VFE32_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(0,
- vfe32_ctrl->share_ctrl->vfebase+
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(0,
- vfe32_ctrl->share_ctrl->vfebase+
- vfe32_AXI_WM_CFG[vfe32_ctrl->
- share_ctrl->outpath.out1.ch1]);
- }
- msm_camera_io_w_mb
- (CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_CAMIF_COMMAND);
- vfe32_ctrl->snapshot_frame_cnt = -1;
- vfe32_ctrl->frame_skip_cnt = 31;
- vfe32_ctrl->frame_skip_pattern = 0xffffffff;
- } /*if snapshot count is 0*/
- } /*if frame is not being dropped*/
- vfe32_ctrl->snapshot_frame_cnt++;
- /* then do reg_update. */
- msm_camera_io_w(1,
- vfe32_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- } /* if snapshot mode. */
+ msm_camera_io_w(0,
+ share_ctrl->vfebase+
+ vfe32_AXI_WM_CFG[
+ share_ctrl->
+ outpath.out1.ch0]);
+ msm_camera_io_w(0,
+ share_ctrl->vfebase+
+ vfe32_AXI_WM_CFG[
+ share_ctrl->
+ outpath.out1.ch1]);
+ }
+ msm_camera_io_w_mb
+ (CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+ share_ctrl->vfebase +
+ VFE_CAMIF_COMMAND);
+ vfe32_ctrl->snapshot_frame_cnt = -1;
+ vfe32_ctrl->frame_skip_cnt = 31;
+ vfe32_ctrl->frame_skip_pattern =
+ 0xffffffff;
+ } /*if snapshot count is 0*/
+ } /*if frame is not being dropped*/
+ vfe32_ctrl->snapshot_frame_cnt++;
+ /* then do reg_update. */
+ msm_camera_io_w(1,
+ share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
+ } /* if snapshot mode. */
+ }
}
static void vfe32_process_rdi0_reg_update_irq(
struct vfe32_ctrl_type *vfe32_ctrl)
{
if (atomic_cmpxchg(
- &vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 1, 0)) {
+ &vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 2, 0) == 2) {
+ axi_stop_rdi0(vfe32_ctrl->share_ctrl);
+ axi_disable_irq(vfe32_ctrl->share_ctrl);
vfe32_send_isp_msg(&vfe32_ctrl->subdev,
vfe32_ctrl->share_ctrl->vfeFrameId,
MSG_ID_RDI0_UPDATE_ACK);
+ vfe32_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE32_OUTPUT_MODE_TERTIARY1;
+ vfe32_ctrl->share_ctrl->current_mode &=
+ ~(VFE_OUTPUTS_RDI0);
+ }
+
+ if (atomic_cmpxchg(
+ &vfe32_ctrl->share_ctrl->rdi0_update_ack_pending, 1, 0) == 1) {
+ vfe32_ctrl->share_ctrl->comp_output_mode |=
+ VFE32_OUTPUT_MODE_TERTIARY1;
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ vfe32_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_RDI0_UPDATE_ACK);
+ vfe32_ctrl->share_ctrl->current_mode &=
+ ~(VFE_OUTPUTS_RDI0);
}
}
@@ -3248,90 +3648,28 @@
struct vfe32_ctrl_type *vfe32_ctrl)
{
if (atomic_cmpxchg(
- &vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0)) {
+ &vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 2, 0) == 2) {
+ axi_stop_rdi1(vfe32_ctrl->share_ctrl);
+ axi_disable_irq(vfe32_ctrl->share_ctrl);
vfe32_send_isp_msg(&vfe32_ctrl->subdev,
vfe32_ctrl->share_ctrl->vfeFrameId,
MSG_ID_RDI1_UPDATE_ACK);
+ vfe32_ctrl->share_ctrl->comp_output_mode &=
+ ~VFE32_OUTPUT_MODE_TERTIARY2;
+ vfe32_ctrl->share_ctrl->current_mode &=
+ ~(VFE_OUTPUTS_RDI1);
}
-}
-static void vfe32_set_default_reg_values(
- struct vfe32_ctrl_type *vfe32_ctrl)
-{
- msm_camera_io_w(0x800080,
- vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_0);
- msm_camera_io_w(0x800080,
- vfe32_ctrl->share_ctrl->vfebase + VFE_DEMUX_GAIN_1);
- /* What value should we program CGC_OVERRIDE to? */
- msm_camera_io_w(0xFFFFF,
- vfe32_ctrl->share_ctrl->vfebase + VFE_CGC_OVERRIDE);
-
- /* default frame drop period and pattern */
- msm_camera_io_w(0x1f,
- vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
- msm_camera_io_w(0x1f,
- vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
- msm_camera_io_w(0xFFFFFFFF,
- vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
- msm_camera_io_w(0xFFFFFFFF,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_FRAMEDROP_ENC_CBCR_PATTERN);
- msm_camera_io_w(0x1f,
- vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y);
- msm_camera_io_w(0x1f,
- vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR);
- msm_camera_io_w(0xFFFFFFFF,
- vfe32_ctrl->share_ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
- msm_camera_io_w(0xFFFFFFFF,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
- msm_camera_io_w(0, vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MIN);
- msm_camera_io_w(0xFFFFFF,
- vfe32_ctrl->share_ctrl->vfebase + VFE_CLAMP_MAX);
-
- /* stats UB config */
- CDBG("%s: Use bayer stats = %d\n", __func__,
- vfe32_use_bayer_stats(vfe32_ctrl));
- if (!vfe32_use_bayer_stats(vfe32_ctrl)) {
- msm_camera_io_w(0x3980007,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AEC_BG_UB_CFG);
- msm_camera_io_w(0x3A00007,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AF_BF_UB_CFG);
- msm_camera_io_w(0x3A8000F,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AWB_UB_CFG);
- msm_camera_io_w(0x3B80007,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_RS_UB_CFG);
- msm_camera_io_w(0x3C0001F,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_CS_UB_CFG);
- msm_camera_io_w(0x3E0001F,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_HIST_UB_CFG);
- } else {
- msm_camera_io_w(0x350001F,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_HIST_UB_CFG);
- msm_camera_io_w(0x370002F,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AEC_BG_UB_CFG);
- msm_camera_io_w(0x3A0002F,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_AF_BF_UB_CFG);
- msm_camera_io_w(0x3D00007,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_RS_UB_CFG);
- msm_camera_io_w(0x3D8001F,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_CS_UB_CFG);
- msm_camera_io_w(0x3F80007,
- vfe32_ctrl->share_ctrl->vfebase +
- VFE_BUS_STATS_SKIN_BHIST_UB_CFG);
+ if (atomic_cmpxchg(
+ &vfe32_ctrl->share_ctrl->rdi1_update_ack_pending, 1, 0) == 1) {
+ vfe32_ctrl->share_ctrl->comp_output_mode |=
+ VFE32_OUTPUT_MODE_TERTIARY2;
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ vfe32_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_RDI1_UPDATE_ACK);
+ vfe32_ctrl->share_ctrl->current_mode &=
+ ~(VFE_OUTPUTS_RDI1);
}
- vfe32_reset_dmi_tables(vfe32_ctrl);
}
static void vfe32_process_reset_irq(
@@ -3340,23 +3678,33 @@
unsigned long flags;
atomic_set(&vfe32_ctrl->share_ctrl->vstate, 0);
+ atomic_set(&vfe32_ctrl->share_ctrl->handle_common_irq, 0);
spin_lock_irqsave(&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
if (vfe32_ctrl->share_ctrl->stop_ack_pending) {
vfe32_ctrl->share_ctrl->stop_ack_pending = FALSE;
spin_unlock_irqrestore(
&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
- vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId, MSG_ID_STOP_ACK);
+ if (vfe32_ctrl->share_ctrl->sync_abort)
+ complete(&vfe32_ctrl->share_ctrl->reset_complete);
+ else
+ vfe32_send_isp_msg(&vfe32_ctrl->subdev,
+ vfe32_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_STOP_ACK);
} else {
spin_unlock_irqrestore(
&vfe32_ctrl->share_ctrl->stop_flag_lock, flags);
/* this is from reset command. */
- vfe32_set_default_reg_values(vfe32_ctrl);
-
- /* reload all write masters. (frame & line)*/
- msm_camera_io_w(0x7FFF,
- vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+ vfe32_reset_internal_variables(vfe32_ctrl);
+ if (vfe32_ctrl->share_ctrl->vfe_reset_flag) {
+ vfe32_ctrl->share_ctrl->vfe_reset_flag = false;
+ msm_camera_io_w(0x7F80,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+ } else {
+ /* reload all write masters. (frame & line)*/
+ msm_camera_io_w(0x7FFF,
+ vfe32_ctrl->share_ctrl->vfebase + VFE_BUS_CMD);
+ }
complete(&vfe32_ctrl->share_ctrl->reset_complete);
}
}
@@ -3367,9 +3715,6 @@
if (vfe32_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_RAW) {
if (vfe32_ctrl->share_ctrl->start_ack_pending) {
- vfe32_send_isp_msg(&vfe32_ctrl->subdev,
- vfe32_ctrl->share_ctrl->vfeFrameId,
- MSG_ID_START_ACK);
vfe32_ctrl->share_ctrl->start_ack_pending = FALSE;
}
vfe32_ctrl->share_ctrl->vfe_capture_count--;
@@ -3411,6 +3756,12 @@
struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
{
uint32_t reg_value;
+ if (errStatus & VFE32_IMASK_VIOLATION) {
+ pr_err("vfe32_irq: violation interrupt\n");
+ reg_value = msm_camera_io_r(
+ axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
+ pr_err("%s: violationStatus = 0x%x\n", __func__, reg_value);
+ }
if (errStatus & VFE32_IMASK_CAMIF_ERROR) {
pr_err("vfe32_irq: camif errors\n");
@@ -3441,12 +3792,31 @@
if (errStatus & VFE32_IMASK_REALIGN_BUF_CR_OVFL)
pr_err("vfe32_irq: realign bug CR overflow\n");
- if (errStatus & VFE32_IMASK_VIOLATION) {
- pr_err("vfe32_irq: violation interrupt\n");
- reg_value = msm_camera_io_r(
- axi_ctrl->share_ctrl->vfebase + VFE_VIOLATION_STATUS);
- pr_err("%s: violationStatus = 0x%x\n", __func__, reg_value);
- }
+ if (errStatus & VFE32_IMASK_STATS_AE_BG_BUS_OVFL)
+ pr_err("vfe32_irq: ae/bg stats bus overflow\n");
+
+ if (errStatus & VFE32_IMASK_STATS_AF_BF_BUS_OVFL)
+ pr_err("vfe32_irq: af/bf stats bus overflow\n");
+
+ if (errStatus & VFE32_IMASK_STATS_AWB_BUS_OVFL)
+ pr_err("vfe32_irq: awb stats bus overflow\n");
+
+ if (errStatus & VFE32_IMASK_STATS_RS_BUS_OVFL)
+ pr_err("vfe32_irq: rs stats bus overflow\n");
+
+ if (errStatus & VFE32_IMASK_STATS_CS_BUS_OVFL)
+ pr_err("vfe32_irq: cs stats bus overflow\n");
+
+ if (errStatus & VFE32_IMASK_STATS_IHIST_BUS_OVFL)
+ pr_err("vfe32_irq: ihist stats bus overflow\n");
+
+ if (errStatus & VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
+ pr_err("vfe32_irq: skin/bhist stats bus overflow\n");
+}
+
+static void vfe32_process_common_error_irq(
+ struct axi_ctrl_t *axi_ctrl, uint32_t errStatus)
+{
if (errStatus & VFE32_IMASK_IMG_MAST_0_BUS_OVFL)
pr_err("vfe32_irq: image master 0 bus overflow\n");
@@ -3469,31 +3839,11 @@
if (errStatus & VFE32_IMASK_IMG_MAST_6_BUS_OVFL)
pr_err("vfe32_irq: image master 6 bus overflow\n");
- if (errStatus & VFE32_IMASK_STATS_AE_BG_BUS_OVFL)
- pr_err("vfe32_irq: ae/bg stats bus overflow\n");
-
- if (errStatus & VFE32_IMASK_STATS_AF_BF_BUS_OVFL)
- pr_err("vfe32_irq: af/bf stats bus overflow\n");
-
- if (errStatus & VFE32_IMASK_STATS_AWB_BUS_OVFL)
- pr_err("vfe32_irq: awb stats bus overflow\n");
-
- if (errStatus & VFE32_IMASK_STATS_RS_BUS_OVFL)
- pr_err("vfe32_irq: rs stats bus overflow\n");
-
- if (errStatus & VFE32_IMASK_STATS_CS_BUS_OVFL)
- pr_err("vfe32_irq: cs stats bus overflow\n");
-
- if (errStatus & VFE32_IMASK_STATS_IHIST_BUS_OVFL)
- pr_err("vfe32_irq: ihist stats bus overflow\n");
-
- if (errStatus & VFE32_IMASK_STATS_SKIN_BHIST_BUS_OVFL)
- pr_err("vfe32_irq: skin/bhist stats bus overflow\n");
-
if (errStatus & VFE32_IMASK_AXI_ERROR)
pr_err("vfe32_irq: axi error\n");
}
+
static void vfe_send_outmsg(
struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
uint32_t ch0_paddr, uint32_t ch1_paddr,
@@ -3506,7 +3856,17 @@
msg.buf.ch_paddr[0] = ch0_paddr;
msg.buf.ch_paddr[1] = ch1_paddr;
msg.buf.ch_paddr[2] = ch2_paddr;
- msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
+ switch (msgid) {
+ case MSG_ID_OUTPUT_TERTIARY1:
+ msg.frameCounter = axi_ctrl->share_ctrl->rdi0FrameId;
+ break;
+ case MSG_ID_OUTPUT_TERTIARY2:
+ msg.frameCounter = axi_ctrl->share_ctrl->rdi1FrameId;
+ break;
+ default:
+ msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;
+ break;
+ }
v4l2_subdev_notify(&axi_ctrl->subdev,
NOTIFY_VFE_MSG_OUT,
@@ -3532,15 +3892,15 @@
free buffer.
*/
out_bool = (
- (axi_ctrl->share_ctrl->operation_mode ==
+ (axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_THUMB_AND_MAIN ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_MAIN_AND_THUMB ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_THUMB_AND_JPEG ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_JPEG_AND_THUMB ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_RAW ||
axi_ctrl->share_ctrl->liveshot_state ==
VFE_STATE_STARTED ||
@@ -3587,15 +3947,15 @@
axi_ctrl->share_ctrl->outpath.out0.ch2,
free_buf->ch_paddr[2]);
}
- if (axi_ctrl->share_ctrl->operation_mode ==
+ if (axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_THUMB_AND_MAIN ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_MAIN_AND_THUMB ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_THUMB_AND_JPEG ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_JPEG_AND_THUMB ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_RAW ||
axi_ctrl->share_ctrl->liveshot_state ==
VFE_STATE_STOPPED)
@@ -3623,13 +3983,13 @@
free_buf = vfe32_check_free_buffer(VFE_MSG_OUTPUT_IRQ,
VFE_MSG_OUTPUT_SECONDARY, axi_ctrl);
- out_bool = ((axi_ctrl->share_ctrl->operation_mode ==
+ out_bool = ((axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_THUMB_AND_MAIN ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_MAIN_AND_THUMB ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_RAW ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_JPEG_AND_THUMB) &&
(axi_ctrl->share_ctrl->vfe_capture_count <= 1)) ||
free_buf;
@@ -3669,13 +4029,13 @@
axi_ctrl->share_ctrl->outpath.out1.ch2,
free_buf->ch_paddr[2]);
}
- if (axi_ctrl->share_ctrl->operation_mode ==
+ if (axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_THUMB_AND_MAIN ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_MAIN_AND_THUMB ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_RAW ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_JPEG_AND_THUMB)
axi_ctrl->share_ctrl->outpath.out1.capture_cnt--;
@@ -4389,19 +4749,29 @@
NOTIFY_VFE_IRQ,
(void *)VFE_IMASK_WHILE_STOPPING_1);
- if (atomic_read(&axi_ctrl->share_ctrl->handle_axi_irq))
+ if (atomic_read(&axi_ctrl->share_ctrl->handle_common_irq)) {
+ if (qcmd->vfeInterruptStatus1 &
+ VFE32_IMASK_COMMON_ERROR_ONLY_1) {
+ pr_err("irq errorIrq\n");
+ vfe32_process_common_error_irq(
+ axi_ctrl,
+ qcmd->vfeInterruptStatus1 &
+ VFE32_IMASK_COMMON_ERROR_ONLY_1);
+ }
+
v4l2_subdev_notify(&axi_ctrl->subdev,
NOTIFY_AXI_IRQ,
(void *)qcmd->vfeInterruptStatus0);
+ }
if (atomic_read(&axi_ctrl->share_ctrl->vstate)) {
if (qcmd->vfeInterruptStatus1 &
- VFE32_IMASK_ERROR_ONLY_1) {
+ VFE32_IMASK_VFE_ERROR_ONLY_1) {
pr_err("irq errorIrq\n");
vfe32_process_error_irq(
axi_ctrl,
qcmd->vfeInterruptStatus1 &
- VFE32_IMASK_ERROR_ONLY_1);
+ VFE32_IMASK_VFE_ERROR_ONLY_1);
}
/* then process stats irq. */
@@ -4693,8 +5063,8 @@
cmd->cmd_type != CMD_STATS_BG_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_BF_BUF_RELEASE &&
cmd->cmd_type != CMD_STATS_BHIST_BUF_RELEASE &&
- cmd->cmd_type != CMD_VFE_SOF_COUNT_UPDATE &&
- cmd->cmd_type != CMD_VFE_COUNT_SOF_ENABLE) {
+ cmd->cmd_type != CMD_VFE_PIX_SOF_COUNT_UPDATE &&
+ cmd->cmd_type != CMD_VFE_COUNT_PIX_SOF_ENABLE) {
if (copy_from_user(&vfecmd,
(void __user *)(cmd->value),
sizeof(vfecmd))) {
@@ -4774,7 +5144,7 @@
case CMD_GENERAL:
rc = vfe32_proc_general(pmctl, &vfecmd, vfe32_ctrl);
break;
- case CMD_VFE_COUNT_SOF_ENABLE: {
+ case CMD_VFE_COUNT_PIX_SOF_ENABLE: {
int enable = *((int *)cmd->value);
if (enable)
vfe32_ctrl->vfe_sof_count_enable = TRUE;
@@ -4782,7 +5152,7 @@
vfe32_ctrl->vfe_sof_count_enable = false;
}
break;
- case CMD_VFE_SOF_COUNT_UPDATE:
+ case CMD_VFE_PIX_SOF_COUNT_UPDATE:
if (!vfe32_ctrl->vfe_sof_count_enable)
vfe32_ctrl->share_ctrl->vfeFrameId =
*((uint32_t *)vfe_params->data);
@@ -4874,6 +5244,10 @@
rc = -EINVAL;
goto mctl_failed;
}
+ axi_ctrl->share_ctrl->axi_ref_cnt++;
+ if (axi_ctrl->share_ctrl->axi_ref_cnt > 1)
+ return rc;
+
spin_lock_init(&axi_ctrl->tasklet_lock);
INIT_LIST_HEAD(&axi_ctrl->tasklet_q);
spin_lock_init(&axi_ctrl->share_ctrl->sd_notify_lock);
@@ -4911,9 +5285,14 @@
else
axi_ctrl->share_ctrl->register_total = VFE33_REGISTER_TOTAL;
+ spin_lock_init(&axi_ctrl->share_ctrl->stop_flag_lock);
+ spin_lock_init(&axi_ctrl->share_ctrl->update_ack_lock);
+ spin_lock_init(&axi_ctrl->share_ctrl->start_ack_lock);
+
enable_irq(axi_ctrl->vfeirq->start);
return rc;
+
clk_enable_failed:
if (axi_ctrl->fs_vfe)
regulator_disable(axi_ctrl->fs_vfe);
@@ -4932,11 +5311,7 @@
struct vfe32_ctrl_type *vfe32_ctrl =
(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
- spin_lock_init(&vfe32_ctrl->share_ctrl->stop_flag_lock);
- spin_lock_init(&vfe32_ctrl->share_ctrl->abort_lock);
spin_lock_init(&vfe32_ctrl->state_lock);
- spin_lock_init(&vfe32_ctrl->share_ctrl->update_ack_lock);
- spin_lock_init(&vfe32_ctrl->share_ctrl->start_ack_lock);
spin_lock_init(&vfe32_ctrl->stats_bufq_lock);
vfe32_ctrl->update_linear = false;
@@ -4946,7 +5321,8 @@
vfe32_ctrl->vfe_sof_count_enable = false;
vfe32_ctrl->hfr_mode = HFR_MODE_OFF;
- memset(&vfe32_ctrl->stats_ctrl, 0, sizeof(struct msm_stats_bufq_ctrl));
+ memset(&vfe32_ctrl->stats_ctrl, 0,
+ sizeof(struct msm_stats_bufq_ctrl));
memset(&vfe32_ctrl->stats_ops, 0, sizeof(struct msm_stats_ops));
return rc;
@@ -4963,6 +5339,9 @@
}
CDBG("%s, free_irq\n", __func__);
+ axi_ctrl->share_ctrl->axi_ref_cnt--;
+ if (axi_ctrl->share_ctrl->axi_ref_cnt > 0)
+ return;
disable_irq(axi_ctrl->vfeirq->start);
tasklet_kill(&axi_ctrl->vfe32_tasklet);
msm_cam_clk_enable(&axi_ctrl->pdev->dev, vfe32_clk_info,
@@ -4978,20 +5357,26 @@
msm_camio_bus_scale_cfg(
pmctl->sdata->pdata->cam_bus_scale_table, S_EXIT);
+
}
void msm_vfe_subdev_release(struct v4l2_subdev *sd)
{
struct vfe32_ctrl_type *vfe32_ctrl =
(struct vfe32_ctrl_type *)v4l2_get_subdevdata(sd);
- if (!vfe32_ctrl->share_ctrl->vfebase)
- vfe32_ctrl->share_ctrl->vfebase = NULL;
+ CDBG("vfe subdev release %p\n",
+ vfe32_ctrl->share_ctrl->vfebase);
}
void axi_abort(struct axi_ctrl_t *axi_ctrl)
{
uint8_t axi_busy_flag = true;
+ unsigned long flags;
/* axi halt command. */
+
+ spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
+ axi_ctrl->share_ctrl->stop_ack_pending = TRUE;
+ spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
msm_camera_io_w(AXI_HALT,
axi_ctrl->share_ctrl->vfebase + VFE_AXI_CMD);
wmb();
@@ -5017,6 +5402,9 @@
* to the command register using the barrier */
msm_camera_io_w_mb(VFE_RESET_UPON_STOP_CMD,
axi_ctrl->share_ctrl->vfebase + VFE_GLOBAL_RESET);
+ if (axi_ctrl->share_ctrl->sync_abort)
+ wait_for_completion_interruptible(
+ &axi_ctrl->share_ctrl->reset_complete);
}
int axi_config_buffers(struct axi_ctrl_t *axi_ctrl,
@@ -5167,8 +5555,12 @@
void axi_start(struct msm_cam_media_controller *pmctl,
struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
{
- uint32_t irq_comp_mask = 0, irq_mask = 0;
+ uint32_t irq_comp_mask = 0, irq_mask = 0, irq_mask1 = 0;
int rc = 0;
+ uint32_t reg_update = 0;
+ uint16_t operation_mode =
+ (axi_ctrl->share_ctrl->current_mode &
+ ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
rc = axi_config_buffers(axi_ctrl, vfe_params);
if (rc < 0)
return;
@@ -5202,59 +5594,55 @@
irq_comp_mask =
msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
VFE_IRQ_COMP_MASK);
+ irq_mask = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_PRIMARY) {
irq_comp_mask |= (
0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1);
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
} else if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
irq_comp_mask |= (
0x1 << axi_ctrl->share_ctrl->outpath.out0.ch0 |
0x1 << axi_ctrl->share_ctrl->outpath.out0.ch1 |
0x1 << axi_ctrl->share_ctrl->outpath.out0.ch2);
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK;
}
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_SECONDARY) {
irq_comp_mask |= (
0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8));
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
} else if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
irq_comp_mask |= (
0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch0 + 8) |
0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch1 + 8) |
0x1 << (axi_ctrl->share_ctrl->outpath.out1.ch2 + 8));
+ irq_mask |= VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE1_MASK;
}
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_TERTIARY1) {
- irq_mask = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0 +
VFE_WM_OFFSET));
- msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
}
if (axi_ctrl->share_ctrl->outpath.output_mode &
VFE32_OUTPUT_MODE_TERTIARY2) {
- irq_mask = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
irq_mask |= (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0 +
VFE_WM_OFFSET));
- msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
- VFE_IRQ_MASK_0);
}
msm_camera_io_w(irq_comp_mask,
axi_ctrl->share_ctrl->vfebase + VFE_IRQ_COMP_MASK);
+ msm_camera_io_w(irq_mask, axi_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_0);
switch (vfe_params.cmd_type) {
case AXI_CMD_PREVIEW: {
- uint16_t operation_mode =
- (axi_ctrl->share_ctrl->operation_mode &
- ~(VFE_OUTPUTS_RDI0|VFE_OUTPUTS_RDI1));
-
switch (operation_mode) {
case VFE_OUTPUTS_PREVIEW:
case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
@@ -5356,14 +5744,46 @@
msm_camera_io_w(1, axi_ctrl->share_ctrl->vfebase +
vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
outpath.out3.ch0]);
- atomic_set(&axi_ctrl->share_ctrl->handle_axi_irq, 1);
+
+ irq_mask1 =
+ msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ irq_mask1 |= VFE_IRQ_STATUS1_RDI0_REG_UPDATE_MASK;
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->rdi0_update_ack_pending,
+ 0, 1))
+ reg_update |= 0x2;
+ }
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ irq_mask1 |= VFE_IRQ_STATUS1_RDI1_REG_UPDATE_MASK;
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->rdi1_update_ack_pending,
+ 0, 1))
+ reg_update |= 0x4;
+ }
+ msm_camera_io_w(irq_mask1, axi_ctrl->share_ctrl->vfebase +
+ VFE_IRQ_MASK_1);
+ if (operation_mode) {
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->pix0_update_ack_pending,
+ 0, 1))
+ reg_update |= 0x1;
+ }
+
+ msm_camera_io_w_mb(reg_update,
+ axi_ctrl->share_ctrl->vfebase +
+ VFE_REG_UPDATE_CMD);
+ axi_ctrl->share_ctrl->operation_mode |=
+ axi_ctrl->share_ctrl->current_mode;
+ axi_enable_irq(axi_ctrl->share_ctrl);
}
void axi_stop(struct msm_cam_media_controller *pmctl,
struct axi_ctrl_t *axi_ctrl, struct msm_camera_vfe_params_t vfe_params)
{
uint32_t reg_update = 0;
- unsigned long flags;
uint32_t operation_mode =
axi_ctrl->share_ctrl->current_mode & ~(VFE_OUTPUTS_RDI0|
VFE_OUTPUTS_RDI1);
@@ -5386,130 +5806,32 @@
return;
}
- if (!axi_ctrl->share_ctrl->skip_abort) {
- atomic_set(&axi_ctrl->share_ctrl->handle_axi_irq, 0);
- axi_disable_irq(axi_ctrl);
+ if (axi_ctrl->share_ctrl->stop_immediately) {
+ axi_disable_irq(axi_ctrl->share_ctrl);
+ axi_stop_process(axi_ctrl->share_ctrl);
+ return;
}
- spin_lock_irqsave(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
- axi_ctrl->share_ctrl->stop_ack_pending = TRUE;
- spin_unlock_irqrestore(&axi_ctrl->share_ctrl->stop_flag_lock, flags);
- switch (vfe_params.cmd_type) {
- case AXI_CMD_PREVIEW: {
- switch (operation_mode) {
- case VFE_OUTPUTS_PREVIEW:
- case VFE_OUTPUTS_PREVIEW_AND_VIDEO:
- if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch1]);
- } else if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch1]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch2]);
- }
- break;
- default:
- if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch1]);
- } else if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch1]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase
- + vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch2]);
- }
- break;
- }
- }
- break;
- default:
- if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY) {
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch1]);
- } else if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_PRIMARY_ALL_CHNLS) {
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch0]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch1]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out0.ch2]);
- }
-
- if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY) {
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch1]);
- } else if (axi_ctrl->share_ctrl->outpath.output_mode &
- VFE32_OUTPUT_MODE_SECONDARY_ALL_CHNLS) {
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch0]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch1]);
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->
- share_ctrl->outpath.out1.ch2]);
- }
- break;
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0) {
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->rdi0_update_ack_pending,
+ 0, 2))
+ reg_update |= 0x2;
}
- if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
- outpath.out2.ch0]);
- if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
- msm_camera_io_w(0, axi_ctrl->share_ctrl->vfebase +
- vfe32_AXI_WM_CFG[axi_ctrl->share_ctrl->
- outpath.out3.ch0]);
-
- if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI0)
- reg_update |= 0x2;
- if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1)
- reg_update |= 0x4;
-
- if (operation_mode)
- reg_update |= 0x1;
+ if (axi_ctrl->share_ctrl->current_mode & VFE_OUTPUTS_RDI1) {
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->rdi1_update_ack_pending,
+ 0, 2))
+ reg_update |= 0x4;
+ }
+ if (operation_mode) {
+ if (!atomic_cmpxchg(
+ &axi_ctrl->share_ctrl->pix0_update_ack_pending,
+ 0, 2))
+ reg_update |= 0x1;
+ }
msm_camera_io_w_mb(reg_update,
axi_ctrl->share_ctrl->vfebase + VFE_REG_UPDATE_CMD);
- if (!axi_ctrl->share_ctrl->skip_abort)
- axi_abort(axi_ctrl);
-
}
static int msm_axi_config(struct v4l2_subdev *sd, void __user *arg)
@@ -5520,7 +5842,6 @@
struct msm_cam_media_controller *pmctl =
(struct msm_cam_media_controller *)v4l2_get_subdev_hostdata(sd);
int rc = 0, vfe_cmd_type = 0, rdi_mode = 0;
- unsigned long flags;
if (!axi_ctrl->share_ctrl->vfebase) {
pr_err("%s: base address unmapped\n", __func__);
@@ -5716,11 +6037,6 @@
}
axi_ctrl->share_ctrl->current_mode =
vfe_params.operation_mode;
- spin_lock_irqsave(&axi_ctrl->share_ctrl->abort_lock, flags);
- axi_ctrl->share_ctrl->skip_abort =
- vfe_params.skip_abort;
- spin_unlock_irqrestore(&axi_ctrl->share_ctrl->abort_lock,
- flags);
axi_start(pmctl, axi_ctrl, vfe_params);
}
break;
@@ -5733,17 +6049,22 @@
}
axi_ctrl->share_ctrl->current_mode =
vfe_params.operation_mode;
- spin_lock_irqsave(&axi_ctrl->share_ctrl->abort_lock, flags);
- axi_ctrl->share_ctrl->skip_abort =
- vfe_params.skip_abort;
- spin_unlock_irqrestore(&axi_ctrl->share_ctrl->abort_lock,
- flags);
+ axi_ctrl->share_ctrl->stop_immediately =
+ vfe_params.stop_immediately;
axi_stop(pmctl, axi_ctrl, vfe_params);
}
break;
case CMD_AXI_RESET:
axi_reset(axi_ctrl);
break;
+ case CMD_AXI_ABORT:
+ if (copy_from_user(&axi_ctrl->share_ctrl->sync_abort,
+ (void __user *)(vfecmd.value),
+ sizeof(uint8_t))) {
+ return -EFAULT;
+ }
+ axi_abort(axi_ctrl);
+ break;
default:
pr_err("%s Unsupported AXI configuration %x ", __func__,
cfgcmd.cmd_type);
@@ -5756,12 +6077,12 @@
{
struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
uint32_t irqstatus = (uint32_t) arg;
- unsigned long flags;
if (!axi_ctrl->share_ctrl->vfebase) {
pr_err("%s: base address unmapped\n", __func__);
return;
}
+
/* next, check output path related interrupts. */
if (irqstatus &
VFE_IRQ_STATUS0_IMAGE_COMPOSIT_DONE0_MASK) {
@@ -5774,12 +6095,12 @@
vfe32_process_output_path_irq_1(axi_ctrl);
}
- if (axi_ctrl->share_ctrl->outpath.output_mode &
+ if (axi_ctrl->share_ctrl->comp_output_mode &
VFE32_OUTPUT_MODE_TERTIARY1)
if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out2.ch0
+ VFE_WM_OFFSET)))
vfe32_process_output_path_irq_rdi0(axi_ctrl);
- if (axi_ctrl->share_ctrl->outpath.output_mode &
+ if (axi_ctrl->share_ctrl->comp_output_mode &
VFE32_OUTPUT_MODE_TERTIARY2)
if (irqstatus & (0x1 << (axi_ctrl->share_ctrl->outpath.out3.ch0
+ VFE_WM_OFFSET)))
@@ -5788,15 +6109,15 @@
/* in snapshot mode if done then send
snapshot done message */
if (
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_THUMB_AND_MAIN ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_MAIN_AND_THUMB ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_THUMB_AND_JPEG ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_JPEG_AND_THUMB ||
- axi_ctrl->share_ctrl->operation_mode ==
+ axi_ctrl->share_ctrl->operation_mode &
VFE_OUTPUTS_RAW) {
if ((axi_ctrl->share_ctrl->outpath.out0.capture_cnt == 0)
&& (axi_ctrl->share_ctrl->outpath.out1.
@@ -5805,17 +6126,10 @@
CAMIF_COMMAND_STOP_IMMEDIATELY,
axi_ctrl->share_ctrl->vfebase +
VFE_CAMIF_COMMAND);
- spin_lock_irqsave(&axi_ctrl->share_ctrl->abort_lock,
- flags);
- if (axi_ctrl->share_ctrl->skip_abort) {
- spin_unlock_irqrestore(&axi_ctrl->share_ctrl->
- abort_lock, flags);
- atomic_set(&axi_ctrl->share_ctrl->
- handle_axi_irq, 0);
- axi_disable_irq(axi_ctrl);
- } else
- spin_unlock_irqrestore(&axi_ctrl->share_ctrl->
- abort_lock, flags);
+ axi_disable_irq(axi_ctrl->share_ctrl);
+ vfe32_send_isp_msg(&axi_ctrl->subdev,
+ axi_ctrl->share_ctrl->vfeFrameId,
+ MSG_ID_PIX0_UPDATE_ACK);
vfe32_send_isp_msg(&axi_ctrl->subdev,
axi_ctrl->share_ctrl->vfeFrameId,
MSG_ID_SNAPSHOT_DONE);
@@ -5893,6 +6207,29 @@
msm_axi_subdev_release(sd);
rc = 0;
break;
+ case VIDIOC_MSM_AXI_RDI_COUNT_UPDATE: {
+ struct rdi_count_msg *msg = (struct rdi_count_msg *)arg;
+ struct axi_ctrl_t *axi_ctrl = v4l2_get_subdevdata(sd);
+ switch (msg->rdi_interface) {
+ case RDI_0:
+ axi_ctrl->share_ctrl->rdi0FrameId = msg->count;
+ rc = 0;
+ break;
+ case RDI_1:
+ axi_ctrl->share_ctrl->rdi1FrameId = msg->count;
+ rc = 0;
+ break;
+ case RDI_2:
+ axi_ctrl->share_ctrl->rdi2FrameId = msg->count;
+ rc = 0;
+ break;
+ default:
+ pr_err("%s: Incorrect interface sent\n", __func__);
+ rc = -EINVAL;
+ break;
+ }
+ break;
+ }
default:
pr_err("%s: command %d not found\n", __func__,
_IOC_NR(cmd));
@@ -5953,7 +6290,7 @@
share_ctrl->vfe32_ctrl = vfe32_ctrl;
axi_ctrl->share_ctrl = share_ctrl;
vfe32_ctrl->share_ctrl = share_ctrl;
-
+ axi_ctrl->share_ctrl->axi_ref_cnt = 0;
v4l2_subdev_init(&axi_ctrl->subdev, &msm_axi_subdev_ops);
axi_ctrl->subdev.internal_ops = &msm_axi_internal_ops;
axi_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.h b/drivers/media/video/msm/vfe/msm_vfe32.h
index f4b7edb..81df0d5 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.h
+++ b/drivers/media/video/msm/vfe/msm_vfe32.h
@@ -62,6 +62,12 @@
* bit 26-32 = 0, domain reset, bit 0-9 = 1 for module reset. */
#define VFE_RESET_UPON_RESET_CMD 0x000003ff
+/* reset the vfe only when reset command*/
+#define VFE_ONLY_RESET_CMD 0x00000002
+
+/*Vfe module reset command*/
+#define VFE_MODULE_RESET_CMD 0x07ffffff
+
/* bit 5 is for axi status idle or busy.
* 1 = halted, 0 = busy */
#define AXI_STATUS_BUSY_MASK 0x00000020
@@ -244,11 +250,11 @@
#define V32_OUT_CLAMP_OFF 0x00000524
#define V32_OUT_CLAMP_LEN 8
-#define V32_OPERATION_CFG_LEN 44
+#define V32_OPERATION_CFG_LEN 32
#define V32_AXI_BUS_CMD_OFF 0x00000038
#define V32_AXI_OUT_OFF 0x0000003C
-#define V32_AXI_OUT_LEN 240
+#define V32_AXI_OUT_LEN 252
#define V32_AXI_CFG_LEN 47
#define V32_AXI_BUS_FMT_OFF 1
#define V32_AXI_BUS_FMT_LEN 4
@@ -787,7 +793,8 @@
#define VFE32_IMASK_ERROR_ONLY_0 0x0
/* when normal case, don't want to block error status. */
/* bit 0-21 are error irq bits */
-#define VFE32_IMASK_ERROR_ONLY_1 0x005FFFFF
+#define VFE32_IMASK_COMMON_ERROR_ONLY_1 0x00407F00
+#define VFE32_IMASK_VFE_ERROR_ONLY_1 0x001F80FF
#define VFE32_IMASK_CAMIF_ERROR (0x00000001<<0)
#define VFE32_IMASK_BHIST_OVWR (0x00000001<<1)
#define VFE32_IMASK_STATS_CS_OVWR (0x00000001<<2)
@@ -941,11 +948,14 @@
uint32_t register_total;
atomic_t vstate;
- atomic_t handle_axi_irq;
+ atomic_t handle_common_irq;
uint32_t vfeFrameId;
+ uint32_t rdi0FrameId;
+ uint32_t rdi1FrameId;
+ uint32_t rdi2FrameId;
uint32_t stats_comp;
+ spinlock_t sd_notify_lock;
spinlock_t stop_flag_lock;
- spinlock_t abort_lock;
int8_t stop_ack_pending;
enum vfe_output_state liveshot_state;
uint32_t vfe_capture_count;
@@ -955,8 +965,13 @@
struct vfe32_output_path outpath;
uint16_t port_info;
- uint32_t skip_abort;
- spinlock_t sd_notify_lock;
+ uint8_t stop_immediately;
+ uint8_t sync_abort;
+ uint16_t cmd_type;
+ uint8_t vfe_reset_flag;
+
+ uint8_t axi_ref_cnt;
+ uint16_t comp_output_mode;
struct completion reset_complete;
@@ -969,9 +984,11 @@
int8_t update_ack_pending;
enum vfe_output_state recording_state;
+ atomic_t pix0_update_ack_pending;
atomic_t rdi0_update_ack_pending;
atomic_t rdi1_update_ack_pending;
atomic_t rdi2_update_ack_pending;
+
};
struct axi_ctrl_t {
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.c b/drivers/media/video/msm/vfe/msm_vfe40.c
index 5a1d488..1aee087 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40.c
@@ -364,19 +364,6 @@
msm_camera_io_w(*(++p),
vfe40_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
msm_camera_io_w(*(++p),
- vfe40_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
- if (msm_camera_io_r(vfe40_ctrl->share_ctrl->vfebase +
- V40_GET_HW_VERSION_OFF) ==
- VFE40_HW_NUMBER) {
- msm_camera_io_w(*(++p),
- vfe40_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
- msm_camera_io_w(*(++p),
- vfe40_ctrl->share_ctrl->vfebase + VFE_RDI2_CFG);
- } else {
- ++p;
- ++p;
- }
- msm_camera_io_w(*(++p),
vfe40_ctrl->share_ctrl->vfebase + VFE_REALIGN_BUF);
msm_camera_io_w(*(++p),
vfe40_ctrl->share_ctrl->vfebase + VFE_CHROMA_UP);
diff --git a/drivers/media/video/msm/vfe/msm_vfe40.h b/drivers/media/video/msm/vfe/msm_vfe40.h
index c8b0cb8..ab913e2 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40.h
+++ b/drivers/media/video/msm/vfe/msm_vfe40.h
@@ -173,10 +173,10 @@
#define V40_OUT_CLAMP_OFF 0x00000874
#define V40_OUT_CLAMP_LEN 16
-#define V40_OPERATION_CFG_LEN 44
+#define V40_OPERATION_CFG_LEN 32
#define V40_AXI_OUT_OFF 0x0000004C
-#define V40_AXI_OUT_LEN 412
+#define V40_AXI_OUT_LEN 424
#define V40_AXI_CH_INF_LEN 32
#define V40_AXI_CFG_LEN 71
diff --git a/drivers/media/video/msm/vfe/msm_vfe40_axi.c b/drivers/media/video/msm/vfe/msm_vfe40_axi.c
index 35d5207..41d1cdd 100644
--- a/drivers/media/video/msm/vfe/msm_vfe40_axi.c
+++ b/drivers/media/video/msm/vfe/msm_vfe40_axi.c
@@ -193,6 +193,16 @@
msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase +
vfe40_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg,
vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length - V40_AXI_CH_INF_LEN);
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG);
+ if (msm_camera_io_r(axi_ctrl->share_ctrl->vfebase +
+ V40_GET_HW_VERSION_OFF) ==
+ VFE40_HW_NUMBER) {
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG);
+ msm_camera_io_w(*ch_info++,
+ axi_ctrl->share_ctrl->vfebase + VFE_RDI2_CFG);
+ }
return 0;
}
@@ -331,6 +341,8 @@
case CMD_AXI_STOP:
axi_stop(axi_ctrl);
break;
+ case CMD_AXI_RESET:
+ break;
default:
pr_err("%s Unsupported AXI configuration %x ", __func__,
cfgcmd.cmd_type);
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index b27debc..80334c4 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -16,6 +16,7 @@
#ifdef MSM_CAMERA_BIONIC
#include <sys/types.h>
#endif
+#include <linux/videodev2.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#ifdef __KERNEL__
@@ -151,7 +152,7 @@
_IOW(MSM_CAM_IOCTL_MAGIC, 39, struct msm_camera_st_frame *)
#define MSM_CAM_IOCTL_V4L2_EVT_NOTIFY \
- _IOR(MSM_CAM_IOCTL_MAGIC, 40, struct v4l2_event *)
+ _IOW(MSM_CAM_IOCTL_MAGIC, 40, struct v4l2_event_and_payload)
#define MSM_CAM_IOCTL_SET_MEM_MAP_INFO \
_IOR(MSM_CAM_IOCTL_MAGIC, 41, struct msm_mem_map_info *)
@@ -216,6 +217,24 @@
#define MSM_CAM_IOCTL_STATS_UNREG_BUF \
_IOR(MSM_CAM_IOCTL_MAGIC, 61, struct msm_stats_flush_bufq *)
+#define MSM_CAM_IOCTL_CSIC_IO_CFG \
+ _IOWR(MSM_CAM_IOCTL_MAGIC, 62, struct csic_cfg_data *)
+
+#define MSM_CAM_IOCTL_CSID_IO_CFG \
+ _IOWR(MSM_CAM_IOCTL_MAGIC, 63, struct csid_cfg_data *)
+
+#define MSM_CAM_IOCTL_CSIPHY_IO_CFG \
+ _IOR(MSM_CAM_IOCTL_MAGIC, 64, struct csiphy_cfg_data *)
+
+#define MSM_CAM_IOCTL_OEM \
+ _IOW(MSM_CAM_IOCTL_MAGIC, 65, struct sensor_cfg_data *)
+
+struct v4l2_event_and_payload {
+ struct v4l2_event evt;
+ uint32_t payload_length;
+ uint32_t transaction_id;
+ void *payload;
+};
struct msm_stats_reqbuf {
int num_buf; /* how many buffers requested */
@@ -350,6 +369,27 @@
uint32_t inst_handle;
};
+struct msm_pp_crop {
+ uint32_t src_x;
+ uint32_t src_y;
+ uint32_t src_w;
+ uint32_t src_h;
+ uint32_t dst_x;
+ uint32_t dst_y;
+ uint32_t dst_w;
+ uint32_t dst_h;
+ uint8_t update_flag;
+};
+
+struct msm_mctl_pp_frame_cmd {
+ uint32_t cookie;
+ uint8_t vpe_output_action;
+ struct msm_pp_frame src_frame;
+ struct msm_pp_frame dest_frame;
+ struct msm_pp_crop crop;
+ int path;
+};
+
struct msm_cam_evt_divert_frame {
unsigned short image_mode;
unsigned short op_mode;
@@ -486,8 +526,8 @@
#define CMD_STATS_BG_BUF_RELEASE 56
#define CMD_STATS_BF_BUF_RELEASE 57
#define CMD_STATS_BHIST_BUF_RELEASE 58
-#define CMD_VFE_SOF_COUNT_UPDATE 59
-#define CMD_VFE_COUNT_SOF_ENABLE 60
+#define CMD_VFE_PIX_SOF_COUNT_UPDATE 59
+#define CMD_VFE_COUNT_PIX_SOF_ENABLE 60
#define CMD_AXI_CFG_PRIM BIT(8)
#define CMD_AXI_CFG_PRIM_ALL_CHNLS BIT(9)
@@ -499,6 +539,8 @@
#define CMD_AXI_START 0xE1
#define CMD_AXI_STOP 0xE2
#define CMD_AXI_RESET 0xE3
+#define CMD_AXI_ABORT 0xE4
+
#define AXI_CMD_PREVIEW BIT(0)
@@ -583,6 +625,7 @@
MSM_STATS_TYPE_BF, /* Bayer Focus */
MSM_STATS_TYPE_BHIST, /* Bayer Hist */
MSM_STATS_TYPE_AE_AW, /* legacy stats for vfe 2.x*/
+ MSM_STATS_TYPE_COMP, /* Composite stats */
MSM_STATS_TYPE_MAX /* MAX */
};
@@ -662,8 +705,11 @@
#define OUTPUT_TYPE_ST_D BIT(7)
#define OUTPUT_TYPE_R BIT(8)
#define OUTPUT_TYPE_R1 BIT(9)
-
-
+#define OUTPUT_TYPE_SAEC BIT(10)
+#define OUTPUT_TYPE_SAFC BIT(11)
+#define OUTPUT_TYPE_SAWB BIT(12)
+#define OUTPUT_TYPE_IHST BIT(13)
+#define OUTPUT_TYPE_CSTA BIT(14)
struct fd_roi_info {
void *info;
@@ -798,7 +844,9 @@
(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+13)
#define MSM_V4L2_EXT_CAPTURE_MODE_RS \
(MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+14)
-#define MSM_V4L2_EXT_CAPTURE_MODE_MAX (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+15)
+#define MSM_V4L2_EXT_CAPTURE_MODE_CSTA \
+ (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+15)
+#define MSM_V4L2_EXT_CAPTURE_MODE_MAX (MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT+16)
#define MSM_V4L2_PID_MOTION_ISO V4L2_CID_PRIVATE_BASE
#define MSM_V4L2_PID_EFFECT (V4L2_CID_PRIVATE_BASE+1)
@@ -851,7 +899,8 @@
#define MSM_V4L2_CLOSE 11
#define MSM_V4L2_SET_CTRL_CMD 12
#define MSM_V4L2_EVT_SUB_MASK 13
-#define MSM_V4L2_MAX 14
+#define MSM_V4L2_PRIVATE_CMD 14
+#define MSM_V4L2_MAX 15
#define V4L2_CAMERA_EXIT 43
struct crop_info {
@@ -918,7 +967,15 @@
#define CFG_START_STREAM 44
#define CFG_STOP_STREAM 45
#define CFG_GET_CSI_PARAMS 46
-#define CFG_MAX 47
+#define CFG_POWER_UP 47
+#define CFG_POWER_DOWN 48
+#define CFG_WRITE_I2C_ARRAY 49
+#define CFG_READ_I2C_ARRAY 50
+#define CFG_PCLK_CHANGE 51
+#define CFG_CONFIG_VREG_ARRAY 52
+#define CFG_CONFIG_CLK_ARRAY 53
+#define CFG_GPIO_OP 54
+#define CFG_MAX 55
#define MOVE_NEAR 0
@@ -1233,6 +1290,33 @@
uint16_t num_info;
};
+struct msm_sensor_exp_gain_info_t {
+ uint16_t coarse_int_time_addr;
+ uint16_t global_gain_addr;
+ uint16_t vert_offset;
+};
+
+struct msm_sensor_output_reg_addr_t {
+ uint16_t x_output;
+ uint16_t y_output;
+ uint16_t line_length_pclk;
+ uint16_t frame_length_lines;
+};
+
+struct sensor_driver_params_type {
+ struct msm_camera_i2c_reg_setting *init_settings;
+ uint16_t init_settings_size;
+ struct msm_camera_i2c_reg_setting *mode_settings;
+ uint16_t mode_settings_size;
+ struct msm_sensor_output_reg_addr_t *sensor_output_reg_addr;
+ struct msm_camera_i2c_reg_setting *start_settings;
+ struct msm_camera_i2c_reg_setting *stop_settings;
+ struct msm_camera_i2c_reg_setting *groupon_settings;
+ struct msm_camera_i2c_reg_setting *groupoff_settings;
+ struct msm_sensor_exp_gain_info_t *sensor_exp_gain_info;
+ struct msm_sensor_output_info_t *output_info;
+};
+
struct mirror_flip {
int32_t x_mirror;
int32_t y_flip;
@@ -1258,8 +1342,78 @@
uint8_t csi_lane_assign;
uint8_t csi_lane_mask;
uint8_t csi_if;
- uint8_t csid_core;
- uint32_t csid_version;
+ uint8_t csid_core[2];
+};
+
+struct msm_camera_csid_lut_params {
+ uint8_t num_cid;
+ struct msm_camera_csid_vc_cfg *vc_cfg;
+};
+
+struct msm_camera_csid_params {
+ uint8_t lane_cnt;
+ uint16_t lane_assign;
+ uint8_t phy_sel;
+ struct msm_camera_csid_lut_params lut_params;
+};
+
+struct msm_camera_csiphy_params {
+ uint8_t lane_cnt;
+ uint8_t settle_cnt;
+ uint16_t lane_mask;
+ uint8_t combo_mode;
+};
+
+struct msm_camera_csi2_params {
+ struct msm_camera_csid_params csid_params;
+ struct msm_camera_csiphy_params csiphy_params;
+};
+
+enum msm_camera_csi_data_format {
+ CSI_8BIT,
+ CSI_10BIT,
+ CSI_12BIT,
+};
+
+struct msm_camera_csi_params {
+ enum msm_camera_csi_data_format data_format;
+ uint8_t lane_cnt;
+ uint8_t lane_assign;
+ uint8_t settle_cnt;
+ uint8_t dpcm_scheme;
+};
+
+enum csic_cfg_type_t {
+ CSIC_INIT,
+ CSIC_CFG,
+};
+
+struct csic_cfg_data {
+ enum csic_cfg_type_t cfgtype;
+ struct msm_camera_csi_params *csic_params;
+};
+
+enum csid_cfg_type_t {
+ CSID_INIT,
+ CSID_CFG,
+};
+
+struct csid_cfg_data {
+ enum csid_cfg_type_t cfgtype;
+ union {
+ uint32_t csid_version;
+ struct msm_camera_csid_params *csid_params;
+ } cfg;
+};
+
+enum csiphy_cfg_type_t {
+ CSIPHY_INIT,
+ CSIPHY_CFG,
+};
+
+struct csiphy_cfg_data {
+ enum csiphy_cfg_type_t cfgtype;
+ struct msm_camera_csiphy_params *csiphy_params;
};
#define CSI_EMBED_DATA 0x12
@@ -1359,6 +1513,81 @@
} cfg;
};
+enum msm_camera_i2c_reg_addr_type {
+ MSM_CAMERA_I2C_BYTE_ADDR = 1,
+ MSM_CAMERA_I2C_WORD_ADDR,
+};
+
+struct msm_camera_i2c_reg_array {
+ uint16_t reg_addr;
+ uint16_t reg_data;
+};
+
+enum msm_camera_i2c_data_type {
+ MSM_CAMERA_I2C_BYTE_DATA = 1,
+ MSM_CAMERA_I2C_WORD_DATA,
+ MSM_CAMERA_I2C_SET_BYTE_MASK,
+ MSM_CAMERA_I2C_UNSET_BYTE_MASK,
+ MSM_CAMERA_I2C_SET_WORD_MASK,
+ MSM_CAMERA_I2C_UNSET_WORD_MASK,
+ MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA,
+};
+
+struct msm_camera_i2c_reg_setting {
+ struct msm_camera_i2c_reg_array *reg_setting;
+ uint16_t size;
+ enum msm_camera_i2c_reg_addr_type addr_type;
+ enum msm_camera_i2c_data_type data_type;
+ uint16_t delay;
+};
+
+enum oem_setting_type {
+ I2C_READ = 1,
+ I2C_WRITE,
+ GPIO_OP,
+ EEPROM_READ,
+ VREG_SET,
+ CLK_SET,
+};
+
+struct sensor_oem_setting {
+ enum oem_setting_type type;
+ void *data;
+};
+
+enum camera_vreg_type {
+ REG_LDO,
+ REG_VS,
+ REG_GPIO,
+};
+
+struct camera_vreg_t {
+ const char *reg_name;
+ enum camera_vreg_type type;
+ int min_voltage;
+ int max_voltage;
+ int op_mode;
+ uint32_t delay;
+};
+
+struct msm_camera_vreg_setting {
+ struct camera_vreg_t *cam_vreg;
+ uint16_t num_vreg;
+ uint8_t enable;
+};
+
+struct msm_cam_clk_info {
+ const char *clk_name;
+ long clk_rate;
+ uint32_t delay;
+};
+
+struct msm_cam_clk_setting {
+ struct msm_cam_clk_info *clk_info;
+ uint16_t num_clk_info;
+ uint8_t enable;
+};
+
struct sensor_cfg_data {
int cfgtype;
int mode;
@@ -1395,12 +1624,30 @@
int ae_mode;
uint8_t wb_val;
int8_t exp_compensation;
+ uint32_t pclk;
struct cord aec_cord;
int is_autoflash;
struct mirror_flip mirror_flip;
+ void *setting;
} cfg;
};
+enum gpio_operation_type {
+ GPIO_REQUEST,
+ GPIO_FREE,
+ GPIO_SET_DIRECTION_OUTPUT,
+ GPIO_SET_DIRECTION_INPUT,
+ GPIO_GET_VALUE,
+ GPIO_SET_VALUE,
+};
+
+struct msm_cam_gpio_operation {
+ enum gpio_operation_type op_type;
+ unsigned address;
+ int value;
+ const char *tag;
+};
+
struct damping_params_t {
uint32_t damping_step;
uint32_t damping_delay;
@@ -1557,11 +1804,17 @@
struct pixel_t video_coord[128];
};
+struct msm_calib_raw {
+ uint8_t *data;
+ uint32_t size;
+};
+
struct msm_camera_eeprom_info_t {
struct msm_eeprom_support af;
struct msm_eeprom_support wb;
struct msm_eeprom_support lsc;
struct msm_eeprom_support dpc;
+ struct msm_eeprom_support raw;
};
struct msm_eeprom_cfg_data {
@@ -1734,6 +1987,9 @@
#define MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL \
_IOWR('V', BASE_VIDIOC_PRIVATE + 9, struct msm_camera_v4l2_ioctl_t)
+#define MSM_CAM_V4L2_IOCTL_PRIVATE_GENERAL \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 10, struct msm_camera_v4l2_ioctl_t)
+
#define VIDIOC_MSM_VPE_INIT \
_IO('V', BASE_VIDIOC_PRIVATE + 15)
@@ -1758,22 +2014,27 @@
#define VIDIOC_MSM_AXI_BUF_CFG \
_IOWR('V', BASE_VIDIOC_PRIVATE + 22, void *)
+#define VIDIOC_MSM_AXI_RDI_COUNT_UPDATE \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 23, struct rdi_count_msg)
+
#define VIDIOC_MSM_VFE_INIT \
- _IO('V', BASE_VIDIOC_PRIVATE + 22)
+ _IO('V', BASE_VIDIOC_PRIVATE + 24)
#define VIDIOC_MSM_VFE_RELEASE \
- _IO('V', BASE_VIDIOC_PRIVATE + 23)
+ _IO('V', BASE_VIDIOC_PRIVATE + 25)
struct msm_camera_v4l2_ioctl_t {
uint32_t id;
- void __user *ioctl_ptr;
uint32_t len;
+ uint32_t trans_code;
+ void __user *ioctl_ptr;
};
struct msm_camera_vfe_params_t {
uint32_t operation_mode;
uint32_t capture_count;
uint32_t skip_abort;
+ uint8_t stop_immediately;
uint16_t port_info;
uint32_t inst_handle;
uint16_t cmd_type;
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index 9fa5932..faaa522 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -68,6 +68,9 @@
#define MSG_ID_RDI0_UPDATE_ACK 49
#define MSG_ID_RDI1_UPDATE_ACK 50
#define MSG_ID_RDI2_UPDATE_ACK 51
+#define MSG_ID_PIX0_UPDATE_ACK 52
+#define MSG_ID_PREV_STOP_ACK 53
+
/* ISP command IDs */
#define VFE_CMD_DUMMY_0 0
@@ -324,30 +327,10 @@
struct msm_vpe_clock_rate {
uint32_t rate;
};
-struct msm_pp_crop {
- uint32_t src_x;
- uint32_t src_y;
- uint32_t src_w;
- uint32_t src_h;
- uint32_t dst_x;
- uint32_t dst_y;
- uint32_t dst_w;
- uint32_t dst_h;
- uint8_t update_flag;
-};
+
#define MSM_MCTL_PP_VPE_FRAME_ACK (1<<0)
#define MSM_MCTL_PP_VPE_FRAME_TO_APP (1<<1)
-struct msm_mctl_pp_frame_cmd {
- uint32_t cookie;
- uint8_t vpe_output_action;
- uint32_t src_buf_handle;
- uint32_t dest_buf_handle;
- struct msm_pp_crop crop;
- int path;
- /* TBD: 3D related */
-};
-
#define VFE_OUTPUTS_MAIN_AND_PREVIEW BIT(0)
#define VFE_OUTPUTS_MAIN_AND_VIDEO BIT(1)
#define VFE_OUTPUTS_MAIN_AND_THUMB BIT(2)