Android/Linux 视频解码器 ADV7282M 驱动调试方法和参考代码
1、dtsi代码:
--- a/src/LINUX/android/kernel/arch/arm/boot/dts/qcom/msm8916-camera-sensor-qrd-skui.dtsi
+++ b/src/LINUX/android/kernel/arch/arm/boot/dts/qcom/msm8916-camera-sensor-qrd-skui.dtsi
@@ -98,7 +98,7 @@
<&clock_gcc clk_gcc_camss_mclk0_clk>;
clock-names = "cam_src_clk", "cam_clk";
};
-
+/*
qcom,camera@0 {
cell-index = <0>;
compatible = "qcom,camera";
@@ -184,7 +184,7 @@
<&clock_gcc clk_gcc_camss_mclk1_clk>;
clock-names = "cam_src_clk", "cam_clk";
};
-
+ */
qcom,camera@20 {
compatible = "qcom,s5k4h5_liteon";
reg = <0x20 0x0>;
@@ -278,4 +278,49 @@
<&clock_gcc clk_gcc_camss_mclk1_clk>;
clock-names = "cam_src_clk", "cam_clk";
};
+ qcom,camera@6a {
+ compatible = "shinetech,adv7282m";
+ reg = <0x6a 0x0>;
+ qcom,slave-id = <0x40 0x01 0xc8>;
+ qcom,csiphy-sd-index = <1>;
+ qcom,csid-sd-index = <1>;
+ qcom,mount-angle = <90>;
+ qcom,sensor-name = "adv7282m";
+ cam_vdig-supply = <&pm8916_l6>;
+ cam_vana-supply = <&pm8916_l17>;
+ cam_vio-supply = <&pm8916_l6>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-type = <0 1 0>;
+ qcom,cam-vreg-min-voltage = <1800000 0 2850000>;
+ qcom,cam-vreg-max-voltage = <1800000 0 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front_sleep>;
+ gpios = <&msm_gpio 27 0>,
+ <&msm_gpio 28 0>,
+ <&msm_gpio 33 0>,
+ <&msm_gpio 118 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <3>;
+ qcom,gpio-req-tbl-num = <0 1 2 3>;
+ qcom,gpio-req-tbl-flags = <1 0 0 0>;
+ qcom,gpio-req-tbl-label = "CAMIF_MCLK",
+ "CAM_RESET",
+ "CAM_STANDBY",
+ "CAM_VANA";
+ qcom,gpio-set-tbl-num = <1 1>;
+ qcom,gpio-set-tbl-flags = <0 2>;
+ qcom,gpio-set-tbl-delay = <1000 4000>;
+ qcom,csi-lane-assign = <0x4320>;
+ qcom,csi-lane-mask = <0x3>;
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <0>;
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ };
};
2、driver 代码:
目录:kernel/drivers/media/platform/msm/camera_v2/sensor/adv7282m.c
/* Copyright (c) 2013, The Linux Foundation. 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.
*
* Modify History For This Module
* When Who What,Where,Why
* --------------------------------------------------------------------------------------
* 13/11/25 Add ADV7282M camera driver code
* 20140505 travis V2.1.0 update the init & modified for DPC
* --------------------------------------------------------------------------------------
*/
#include "msm_sensor.h"
#include "msm_cci.h"
#include "msm_camera_io_util.h"
#define ADV7282M_SENSOR_NAME "adv7282m"
#define I2C_RETRY_COUNT 5
#define CONFIG_MSMB_CAMERA_DEBUG
#undef CDBG
#ifdef CONFIG_MSMB_CAMERA_DEBUG
#define CDBG(fmt, args...) printk(fmt, ##args)
#else
#define CDBG(fmt, args...) do { } while (0)
#endif
static uint16_t Preview_Shutter = 0;
static uint16_t Capture_Shutter = 0;
DEFINE_MSM_MUTEX(adv7282m_mut);
static struct msm_sensor_ctrl_t adv7282m_s_ctrl;
static struct msm_sensor_power_setting adv7282m_power_setting[] = {
{
.seq_type = SENSOR_GPIO,
.seq_val = SENSOR_GPIO_RESET,
.config_val = GPIO_OUT_LOW,
.delay = 0,
},
{
.seq_type = SENSOR_GPIO,
.seq_val = SENSOR_GPIO_STANDBY,
.config_val = GPIO_OUT_LOW,
.delay = 0,
},
{
.seq_type =SENSOR_GPIO,
.seq_val = SENSOR_GPIO_VANA,
.config_val = GPIO_OUT_HIGH,
.delay = 0,
},
{
.seq_type = SENSOR_VREG,
.seq_val = CAM_VIO,
.config_val = 0,
.delay = 0,
},
{
.seq_type = SENSOR_VREG,
.seq_val = CAM_VDIG,
.config_val = 0,
.delay = 0,
},
{
.seq_type = SENSOR_GPIO,
.seq_val = SENSOR_GPIO_STANDBY,
.config_val = GPIO_OUT_HIGH,
.delay = 5,
},
{
.seq_type = SENSOR_GPIO,
.seq_val = SENSOR_GPIO_RESET,
.config_val = GPIO_OUT_HIGH,
.delay = 5,
},
{
.seq_type = SENSOR_CLK,
.seq_val = SENSOR_CAM_MCLK,
.config_val = 23880000,
.delay = 10,
},
};
static struct msm_sensor_power_setting adv7282m_power_down_setting[] = {
{
.seq_type = SENSOR_VREG,
.seq_val = CAM_VIO,
.config_val = 0,
.delay = 0,
},
{
.seq_type = SENSOR_VREG,
.seq_val = CAM_VDIG,
.config_val = 0,
.delay = 0,
},
{
.seq_type = SENSOR_GPIO,
.seq_val = SENSOR_GPIO_STANDBY,
.config_val = GPIO_OUT_HIGH,
.delay = 5,
},
{
.seq_type = SENSOR_GPIO,
.seq_val = SENSOR_GPIO_RESET,
.config_val = GPIO_OUT_HIGH,
.delay = 5,
},
{
.seq_type = SENSOR_GPIO,
.seq_val = SENSOR_GPIO_VANA,
.config_val = GPIO_OUT_LOW,
.delay = 5,
},
{
.seq_type = SENSOR_CLK,
.seq_val = SENSOR_CAM_MCLK,
.config_val = 23880000,
.delay = 10,
},
};
static struct msm_camera_i2c_reg_conf adv7282m_start_settings[] = {
{0x00, 0x00}, //Power up MIPI CSI-2 Tx
};
static struct msm_camera_i2c_reg_conf adv7282m_stop_settings[] = {
{0x00, 0x80}, //Power down MIPI CSI-2 Tx
};
//set sensor init setting
static struct msm_camera_i2c_reg_conf adv7282m_recommend_settings[] = {
{0x0F, 0x00}, //Exit power down mode
{0x00, 0x00}, //INSEL = CVBS in on Ain 1
{0x0E, 0x80}, //ADI Required Write
{0x9C, 0x00}, //ADI Required Write
{0x9C, 0xFF}, //ADI Required Write
{0x0E, 0x00}, //Enter User Sub Map
{0x03, 0x4E}, //ADI Required Write
{0x02, 0x04},
{0x04, 0x57}, //Enable Intrq pin
{0x13, 0x00}, //Enable INTRQ output driver
{0x17, 0x41}, //select SH1
{0x1D, 0xC0}, //Tri-State LLC output driver
{0x52, 0xCD}, //ADI Required Write
{0x80, 0x51}, //ADI Required Write
{0x81, 0x51}, //ADI Required Write
{0x82, 0x68}, //ADI Required Write
{0x5D, 0x1C}, //Enable Diagnostic pin 1 - Level=1.125V
{0x5E, 0x1C}, //Enable Diagnostic pin 2 - Level=1.125V
{0xFD, 0x84}, //Set VPP Map Address
};
static struct msm_camera_i2c_reg_conf adv7282m_recommend1_settings[] = {
{0xA3, 0x00}, //ADI Required Write
{0x5B, 0x00}, //Advanced Timing Enabled
{0x55, 0x80}, //Enable I2P
};
static struct msm_camera_i2c_reg_conf adv7282m_recommend2_settings[] = {
{0xFE, 0x88}, //Set CSI Map Address
};
static struct msm_camera_i2c_reg_conf adv7282m_recommend3_settings[] = {
{0x01, 0x20}, //ADI Required Write
{0x02, 0x28}, //ADI Required Write
{0x03, 0x38}, //ADI Required Write
{0x04, 0x30}, //ADI Required Write
{0x05, 0x30}, //ADI Required Write
{0x06, 0x80}, //ADI Required Write
{0x07, 0x70}, //ADI Required Write
{0x08, 0x50}, //ADI Required Write
{0xDE, 0x02}, //Power up D-PHY
{0xD2, 0xF7}, //ADI Required Write
{0xD8, 0x65}, //ADI Required Write
{0xE0, 0x09}, //ADI Required Write
{0x2C, 0x00}, //ADI Required Write
{0x1D, 0x80}, //ADI Required Write
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_saturation[11][5] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_contrast[11][3] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_sharpness[6][3] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_exposure_compensation[5][3] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_antibanding[][17] = {
};
//begin effect
static struct msm_camera_i2c_reg_conf ADV7282M_reg_effect_normal[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_effect_black_white[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_effect_negative[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_effect_old_movie[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_effect_solarize[] = {
};
// end effect
//begin scene, not realised
static struct msm_camera_i2c_reg_conf ADV7282M_reg_scene_auto[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_scene_portrait[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_scene_landscape[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_scene_night[] = {
};
//end scene
//begin white balance
static struct msm_camera_i2c_reg_conf ADV7282M_reg_wb_auto[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_wb_sunny[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_wb_cloudy[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_wb_office[] = {
};
static struct msm_camera_i2c_reg_conf ADV7282M_reg_wb_home[] = {
};
//end white balance
static void adv7282m_set_stauration(struct msm_sensor_ctrl_t *s_ctrl, int value)
{
pr_debug("%s %d", __func__, value);
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_saturation[value],
ARRAY_SIZE(ADV7282M_reg_saturation[value]),
MSM_CAMERA_I2C_BYTE_DATA);
}
static void adv7282m_set_contrast(struct msm_sensor_ctrl_t *s_ctrl, int value)
{
pr_debug("%s %d", __func__, value);
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_contrast[value],
ARRAY_SIZE(ADV7282M_reg_contrast[value]),
MSM_CAMERA_I2C_BYTE_DATA);
}
static void adv7282m_set_sharpness(struct msm_sensor_ctrl_t *s_ctrl, int value)
{
int val = value / 6;
pr_debug("%s %d", __func__, value);
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_sharpness[val],
ARRAY_SIZE(ADV7282M_reg_sharpness[val]),
MSM_CAMERA_I2C_BYTE_DATA);
}
static void adv7282m_set_exposure_compensation(struct msm_sensor_ctrl_t *s_ctrl,
int value)
{
int val = (value + 12) / 6;
pr_debug("%s %d", __func__, val);
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_exposure_compensation[val],
ARRAY_SIZE(ADV7282M_reg_exposure_compensation[val]),
MSM_CAMERA_I2C_BYTE_DATA);
}
static void adv7282m_set_effect(struct msm_sensor_ctrl_t *s_ctrl, int value)
{
pr_debug("%s %d", __func__, value);
switch (value) {
case MSM_CAMERA_EFFECT_MODE_OFF: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_effect_normal,
ARRAY_SIZE(ADV7282M_reg_effect_normal),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_EFFECT_MODE_MONO: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_effect_black_white,
ARRAY_SIZE(ADV7282M_reg_effect_black_white),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_EFFECT_MODE_NEGATIVE: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_effect_negative,
ARRAY_SIZE(ADV7282M_reg_effect_negative),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_EFFECT_MODE_SEPIA: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_effect_old_movie,
ARRAY_SIZE(ADV7282M_reg_effect_old_movie),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_EFFECT_MODE_SOLARIZE: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_effect_solarize,
ARRAY_SIZE(ADV7282M_reg_effect_solarize),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
default:
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_effect_normal,
ARRAY_SIZE(ADV7282M_reg_effect_normal),
MSM_CAMERA_I2C_BYTE_DATA);
}
}
static void adv7282m_set_antibanding(struct msm_sensor_ctrl_t *s_ctrl, int value)
{
pr_debug("%s %d", __func__, value);
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_antibanding[value],
ARRAY_SIZE(ADV7282M_reg_antibanding[value]),
MSM_CAMERA_I2C_BYTE_DATA);
}
static void adv7282m_set_scene_mode(struct msm_sensor_ctrl_t *s_ctrl, int value)
{
pr_debug("%s %d", __func__, value);
switch (value) {
case MSM_CAMERA_SCENE_MODE_OFF: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_scene_auto,
ARRAY_SIZE(ADV7282M_reg_scene_auto),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_SCENE_MODE_NIGHT: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_scene_night,
ARRAY_SIZE(ADV7282M_reg_scene_night),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_SCENE_MODE_LANDSCAPE: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_scene_landscape,
ARRAY_SIZE(ADV7282M_reg_scene_landscape),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_SCENE_MODE_PORTRAIT: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_scene_portrait,
ARRAY_SIZE(ADV7282M_reg_scene_portrait),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
default:
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_scene_auto,
ARRAY_SIZE(ADV7282M_reg_scene_auto),
MSM_CAMERA_I2C_BYTE_DATA);
}
}
static void adv7282m_set_white_balance_mode(struct msm_sensor_ctrl_t *s_ctrl,
int value)
{
pr_debug("%s %d", __func__, value);
switch (value) {
case MSM_CAMERA_WB_MODE_AUTO: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_wb_auto,
ARRAY_SIZE(ADV7282M_reg_wb_auto),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_WB_MODE_INCANDESCENT: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_wb_home,
ARRAY_SIZE(ADV7282M_reg_wb_home),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_WB_MODE_DAYLIGHT: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_wb_sunny,
ARRAY_SIZE(ADV7282M_reg_wb_sunny),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_WB_MODE_FLUORESCENT: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_wb_office,
ARRAY_SIZE(ADV7282M_reg_wb_office),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
case MSM_CAMERA_WB_MODE_CLOUDY_DAYLIGHT: {
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_wb_cloudy,
ARRAY_SIZE(ADV7282M_reg_wb_cloudy),
MSM_CAMERA_I2C_BYTE_DATA);
break;
}
default:
s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, ADV7282M_reg_wb_auto,
ARRAY_SIZE(ADV7282M_reg_wb_auto),
MSM_CAMERA_I2C_BYTE_DATA);
}
}
static struct v4l2_subdev_info adv7282m_subdev_info[] = {
{
.code = V4L2_MBUS_FMT_YUYV8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.fmt = 1,
.order = 0,
},
};
static const struct i2c_device_id adv7282m_i2c_id[] = {
{ADV7282M_SENSOR_NAME, (kernel_ulong_t)&adv7282m_s_ctrl},
{ }
};
static int32_t msm_adv7282m_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc = 0;
rc = msm_sensor_i2c_probe(client, id, &adv7282m_s_ctrl);
//adv7282m_info->client = client;
return rc;
}
static struct i2c_driver adv7282m_i2c_driver = {
.id_table = adv7282m_i2c_id,
.probe = msm_adv7282m_i2c_probe,
.driver = {
.name = ADV7282M_SENSOR_NAME,
},
};
static struct msm_camera_i2c_client adv7282m_sensor_i2c_client = {
.addr_type = MSM_CAMERA_I2C_BYTE_ADDR,
};
static const struct of_device_id adv7282m_dt_match[] = {
{.compatible = "shinetech,adv7282m", .data = &adv7282m_s_ctrl},
{}
};
MODULE_DEVICE_TABLE(of, adv7282m_dt_match);
static struct platform_driver adv7282m_platform_driver = {
.driver = {
.name = "shinetech,adv7282m",
.owner = THIS_MODULE,
.of_match_table = adv7282m_dt_match,
},
};
static int32_t adv7282m_platform_probe(struct platform_device *pdev)
{
int32_t rc;
const struct of_device_id *match;
match = of_match_device(adv7282m_dt_match, &pdev->dev);
rc = msm_sensor_platform_probe(pdev, match->data);
return rc;
}
static int __init adv7282m_init_module(void)
{
int32_t rc;
rc = platform_driver_probe(&adv7282m_platform_driver,
adv7282m_platform_probe);
if (!rc)
return rc;
return i2c_add_driver(&adv7282m_i2c_driver);
}
static void __exit adv7282m_exit_module(void)
{
if (adv7282m_s_ctrl.pdev) {
msm_sensor_free_sensor_data(&adv7282m_s_ctrl);
platform_driver_unregister(&adv7282m_platform_driver);
} else
i2c_del_driver(&adv7282m_i2c_driver);
return;
}
//ppp
uint16_t adv7282m_read_shutter(struct msm_sensor_ctrl_t *s_ctrl)
{
uint16_t shutter_h, shutter_L, shutter;
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client,
0x03,
&shutter_h, MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client,
0x04,
&shutter_L, MSM_CAMERA_I2C_BYTE_DATA);
return ((shutter_h << 8) | (shutter_L & 0xff));
CDBG("=====>preview_shutter= %x n", shutter);
}
static void adv7282m_write_shutter(struct msm_sensor_ctrl_t *s_ctrl, uint16_t shutter)
{
int32_t temp = 0;
if (shutter < 1)
return;
temp = shutter & 0xff;
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write(
s_ctrl->sensor_i2c_client,
0x04,
temp, MSM_CAMERA_I2C_BYTE_DATA);
temp = (shutter >> 8) & 0xff;
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write(
s_ctrl->sensor_i2c_client,
0x03,
temp, MSM_CAMERA_I2C_BYTE_DATA);
}
void adv7282m_set_capture_shutter(struct msm_sensor_ctrl_t *s_ctrl)
{
//int32_t temp = 0;
uint16_t shutter = 1;
s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write(
s_ctrl->sensor_i2c_client,
0xb6,
0x00, MSM_CAMERA_I2C_BYTE_DATA); //AEC off
shutter = adv7282m_read_shutter(s_ctrl);
Preview_Shutter = shutter;
Capture_Shutter = Preview_Shutter/2;
adv7282m_write_shutter(s_ctrl, Capture_Shutter);
//mdelay(200);
//return temp;
}
void adv7282m_set_preview_shutter(struct msm_sensor_ctrl_t *s_ctrl)
{
//int32_t temp = 0;
//uint16_t shutter =Preview_Shutter;
adv7282m_write_shutter(s_ctrl, Preview_Shutter);
//s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write(
// s_ctrl->sensor_i2c_client,
// 0xb6,
// 0x03, MSM_CAMERA_I2C_BYTE_DATA); //AEC on
}
int32_t adv7282m_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
void __user *argp)
{
struct sensorb_cfg_data *cdata = (struct sensorb_cfg_data *)argp;
long rc = 0;
int32_t i = 0;
mutex_lock(s_ctrl->msm_sensor_mutex);
CDBG("%s:%d %s cfgtype = %dn", __func__, __LINE__,
s_ctrl->sensordata->sensor_name, cdata->cfgtype);
switch (cdata->cfgtype) {
case CFG_GET_SENSOR_INFO:
memcpy(cdata->cfg.sensor_info.sensor_name,
s_ctrl->sensordata->sensor_name,
sizeof(cdata->cfg.sensor_info.sensor_name));
cdata->cfg.sensor_info.session_id =
s_ctrl->sensordata->sensor_info->session_id;
for (i = 0; i < SUB_MODULE_MAX; i++)
cdata->cfg.sensor_info.subdev_id[i] =
s_ctrl->sensordata->sensor_info->subdev_id[i];
CDBG("%s:%d sensor name %sn", __func__, __LINE__,
cdata->cfg.sensor_info.sensor_name);
CDBG("%s:%d session id %dn", __func__, __LINE__,
cdata->cfg.sensor_info.session_id);
for (i = 0; i < SUB_MODULE_MAX; i++)
CDBG("%s:%d subdev_id[%d] %dn", __func__, __LINE__, i,
cdata->cfg.sensor_info.subdev_id[i]);
break;
case CFG_SET_INIT_SETTING:
/* 1. Write Recommend settings */
/* 2. Write change settings */
{
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend_settings,
ARRAY_SIZE(adv7282m_recommend_settings),
MSM_CAMERA_I2C_BYTE_DATA);
printk("[Beyond] CFG_SET_INIT_SETTING enter!!n");
s_ctrl->sensor_i2c_client->cci_client->sid = 0x42;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend1_settings,
ARRAY_SIZE(adv7282m_recommend1_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend2_settings,
ARRAY_SIZE(adv7282m_recommend2_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x44;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend3_settings,
ARRAY_SIZE(adv7282m_recommend3_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
}
break;
case CFG_SET_RESOLUTION: //peter
{
int val = 0;
if (copy_from_user(&val,
(void *)cdata->cfg.setting, sizeof(int))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_err("%s:%d ppp enter val =%dn", __func__, __LINE__,val);
if (val == 0)
{
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend_settings,
ARRAY_SIZE(adv7282m_recommend_settings),
MSM_CAMERA_I2C_BYTE_DATA);
printk("[Beyond] CFG_SET_INIT_SETTING enter!!n");
s_ctrl->sensor_i2c_client->cci_client->sid = 0x42;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend1_settings,
ARRAY_SIZE(adv7282m_recommend1_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend2_settings,
ARRAY_SIZE(adv7282m_recommend2_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x44;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend3_settings,
ARRAY_SIZE(adv7282m_recommend3_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
}
else if (val == 1)
{
uint16_t adv_stat = 0;
int i = 0;
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend_settings,
ARRAY_SIZE(adv7282m_recommend_settings),
MSM_CAMERA_I2C_BYTE_DATA);
printk("[Beyond] CFG_SET_INIT_SETTING enter!!n");
s_ctrl->sensor_i2c_client->cci_client->sid = 0x42;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend1_settings,
ARRAY_SIZE(adv7282m_recommend1_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend2_settings,
ARRAY_SIZE(adv7282m_recommend2_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x44;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_recommend3_settings,
ARRAY_SIZE(adv7282m_recommend3_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
for(i = 0;i < 5 ;i++){
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client, 0x10,
&adv_stat, MSM_CAMERA_I2C_BYTE_DATA);
printk("nr[young]: adv stat 0x10(addr) = 0x%02x(data)n ",adv_stat);
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client, 0x12,
&adv_stat, MSM_CAMERA_I2C_BYTE_DATA);
printk("nr[young]: adv stat 0x12(addr) = 0x%02x(data)n ",adv_stat);
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_read(
s_ctrl->sensor_i2c_client, 0x13,
&adv_stat, MSM_CAMERA_I2C_BYTE_DATA);
printk("nr[young]: adv stat 0x13(addr) = 0x%02x(data)n ",adv_stat);
}
}
}
break;
case CFG_SET_STOP_STREAM:
s_ctrl->sensor_i2c_client->cci_client->sid = 0x44;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_stop_settings,
ARRAY_SIZE(adv7282m_stop_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
break;
case CFG_SET_START_STREAM:
s_ctrl->sensor_i2c_client->cci_client->sid = 0x44;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_conf_tbl(
s_ctrl->sensor_i2c_client, adv7282m_start_settings,
ARRAY_SIZE(adv7282m_start_settings),
MSM_CAMERA_I2C_BYTE_DATA);
s_ctrl->sensor_i2c_client->cci_client->sid = 0x20;
break;
case CFG_GET_SENSOR_INIT_PARAMS:
cdata->cfg.sensor_init_params.modes_supported =
s_ctrl->sensordata->sensor_info->modes_supported;
cdata->cfg.sensor_init_params.position =
s_ctrl->sensordata->sensor_info->position;
cdata->cfg.sensor_init_params.sensor_mount_angle =
s_ctrl->sensordata->sensor_info->sensor_mount_angle;
CDBG("%s:%d init params mode %d pos %d mount %dn", __func__,
__LINE__,
cdata->cfg.sensor_init_params.modes_supported,
cdata->cfg.sensor_init_params.position,
cdata->cfg.sensor_init_params.sensor_mount_angle);
break;
case CFG_SET_SLAVE_INFO: {
struct msm_camera_sensor_slave_info sensor_slave_info;
struct msm_sensor_power_setting_array *power_setting_array;
int slave_index = 0;
if (copy_from_user(&sensor_slave_info,
(void *)cdata->cfg.setting,
sizeof(struct msm_camera_sensor_slave_info))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
/* Update sensor slave address */
if (sensor_slave_info.slave_addr) {
s_ctrl->sensor_i2c_client->cci_client->sid =
sensor_slave_info.slave_addr >> 1;
}
/* Update sensor address type */
s_ctrl->sensor_i2c_client->addr_type =
sensor_slave_info.addr_type;
/* Update power up / down sequence */
s_ctrl->power_setting_array =
sensor_slave_info.power_setting_array;
power_setting_array = &s_ctrl->power_setting_array;
power_setting_array->power_setting = kzalloc(
power_setting_array->size *
sizeof(struct msm_sensor_power_setting), GFP_KERNEL);
if (!power_setting_array->power_setting) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -ENOMEM;
break;
}
if (copy_from_user(power_setting_array->power_setting,
(void *)sensor_slave_info.power_setting_array.power_setting,
power_setting_array->size *
sizeof(struct msm_sensor_power_setting))) {
kfree(power_setting_array->power_setting);
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
//s_ctrl->free_power_setting = true;
CDBG("%s sensor id %xn", __func__,
sensor_slave_info.slave_addr);
CDBG("%s sensor addr type %dn", __func__,
sensor_slave_info.addr_type);
CDBG("%s sensor reg %xn", __func__,
sensor_slave_info.sensor_id_info.sensor_id_reg_addr);
CDBG("%s sensor id %xn", __func__,
sensor_slave_info.sensor_id_info.sensor_id);
for (slave_index = 0; slave_index <
power_setting_array->size; slave_index++) {
CDBG("%s i %d power setting %d %d %ld %dn", __func__,
slave_index,
power_setting_array->power_setting[slave_index].
seq_type,
power_setting_array->power_setting[slave_index].
seq_val,
power_setting_array->power_setting[slave_index].
config_val,
power_setting_array->power_setting[slave_index].
delay);
}
kfree(power_setting_array->power_setting);
break;
}
case CFG_WRITE_I2C_ARRAY: {
struct msm_camera_i2c_reg_setting conf_array;
struct msm_camera_i2c_reg_array *reg_setting = NULL;
if (copy_from_user(&conf_array,
(void *)cdata->cfg.setting,
sizeof(struct msm_camera_i2c_reg_setting))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
reg_setting = kzalloc(conf_array.size *
(sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
if (!reg_setting) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -ENOMEM;
break;
}
if (copy_from_user(reg_setting, (void *)conf_array.reg_setting,
conf_array.size *
sizeof(struct msm_camera_i2c_reg_array))) {
pr_err("%s:%d failedn", __func__, __LINE__);
kfree(reg_setting);
rc = -EFAULT;
break;
}
conf_array.reg_setting = reg_setting;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->i2c_write_table(
s_ctrl->sensor_i2c_client, &conf_array);
kfree(reg_setting);
break;
}
case CFG_WRITE_I2C_SEQ_ARRAY: {
struct msm_camera_i2c_seq_reg_setting conf_array;
struct msm_camera_i2c_seq_reg_array *reg_setting = NULL;
if (copy_from_user(&conf_array,
(void *)cdata->cfg.setting,
sizeof(struct msm_camera_i2c_seq_reg_setting))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
reg_setting = kzalloc(conf_array.size *
(sizeof(struct msm_camera_i2c_seq_reg_array)),
GFP_KERNEL);
if (!reg_setting) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -ENOMEM;
break;
}
if (copy_from_user(reg_setting, (void *)conf_array.reg_setting,
conf_array.size *
sizeof(struct msm_camera_i2c_seq_reg_array))) {
pr_err("%s:%d failedn", __func__, __LINE__);
kfree(reg_setting);
rc = -EFAULT;
break;
}
conf_array.reg_setting = reg_setting;
rc = s_ctrl->sensor_i2c_client->i2c_func_tbl->
i2c_write_seq_table(s_ctrl->sensor_i2c_client,
&conf_array);
kfree(reg_setting);
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_SET_STOP_STREAM_SETTING: {
struct msm_camera_i2c_reg_setting *stop_setting =
&s_ctrl->stop_setting;
struct msm_camera_i2c_reg_array *reg_setting = NULL;
if (copy_from_user(stop_setting, (void *)cdata->cfg.setting,
sizeof(struct msm_camera_i2c_reg_setting))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
reg_setting = stop_setting->reg_setting;
stop_setting->reg_setting = kzalloc(stop_setting->size *
(sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);
if (!stop_setting->reg_setting) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -ENOMEM;
break;
}
if (copy_from_user(stop_setting->reg_setting,
(void *)reg_setting, stop_setting->size *
sizeof(struct msm_camera_i2c_reg_array))) {
pr_err("%s:%d failedn", __func__, __LINE__);
kfree(stop_setting->reg_setting);
stop_setting->reg_setting = NULL;
stop_setting->size = 0;
rc = -EFAULT;
break;
}
break;
}
case CFG_SET_SATURATION: {
int32_t sat_lev;
if (copy_from_user(&sat_lev, (void *)cdata->cfg.setting,
sizeof(int32_t))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_debug("%s: Saturation Value is %d", __func__, sat_lev);
adv7282m_set_stauration(s_ctrl, sat_lev);
break;
}
case CFG_SET_CONTRAST: {
int32_t con_lev;
if (copy_from_user(&con_lev, (void *)cdata->cfg.setting,
sizeof(int32_t))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_debug("%s: Contrast Value is %d", __func__, con_lev);
adv7282m_set_contrast(s_ctrl, con_lev);
break;
}
case CFG_SET_SHARPNESS: {
int32_t shp_lev;
if (copy_from_user(&shp_lev, (void *)cdata->cfg.setting,
sizeof(int32_t))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_debug("%s: Sharpness Value is %d", __func__, shp_lev);
adv7282m_set_sharpness(s_ctrl, shp_lev);
break;
}
case CFG_SET_AUTOFOCUS: {
/* TO-DO: set the Auto Focus */
pr_debug("%s: Setting Auto Focus", __func__);
break;
}
case CFG_CANCEL_AUTOFOCUS: {
/* TO-DO: Cancel the Auto Focus */
pr_debug("%s: Cancelling Auto Focus", __func__);
break;
}
case CFG_SET_ANTIBANDING: {
int32_t anti_mode;
if (copy_from_user(&anti_mode,
(void *)cdata->cfg.setting,
sizeof(int32_t))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_debug("%s: anti-banding mode is %d", __func__,
anti_mode);
adv7282m_set_antibanding(s_ctrl, anti_mode);
break;
}
case CFG_SET_EXPOSURE_COMPENSATION: {
int32_t ec_lev;
if (copy_from_user(&ec_lev, (void *)cdata->cfg.setting,
sizeof(int32_t))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_debug("%s: Exposure compensation Value is %d",
__func__, ec_lev);
adv7282m_set_exposure_compensation(s_ctrl, ec_lev);
break;
}
case CFG_SET_WHITE_BALANCE: {
int32_t wb_mode;
if (copy_from_user(&wb_mode, (void *)cdata->cfg.setting,
sizeof(int32_t))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_debug("%s: white balance is %d", __func__, wb_mode);
adv7282m_set_white_balance_mode(s_ctrl, wb_mode);
break;
}
case CFG_SET_EFFECT: {
int32_t effect_mode;
if (copy_from_user(&effect_mode, (void *)cdata->cfg.setting,
sizeof(int32_t))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_debug("%s: Effect mode is %d", __func__, effect_mode);
adv7282m_set_effect(s_ctrl, effect_mode);
break;
}
case CFG_SET_BESTSHOT_MODE: {
int32_t bs_mode;
if (copy_from_user(&bs_mode, (void *)cdata->cfg.setting,
sizeof(int32_t))) {
pr_err("%s:%d failedn", __func__, __LINE__);
rc = -EFAULT;
break;
}
pr_debug("%s: best shot mode is %d", __func__, bs_mode);
adv7282m_set_scene_mode(s_ctrl, bs_mode);
break;
}
case CFG_SET_ISO:
break;
default:
rc = -EFAULT;
break;
}
mutex_unlock(s_ctrl->msm_sensor_mutex);
return rc;
}
static struct msm_sensor_fn_t adv7282m_sensor_func_tbl = {
.sensor_config = adv7282m_sensor_config,
.sensor_power_up = msm_sensor_power_up,
.sensor_power_down = msm_sensor_power_down,
.sensor_match_id = msm_sensor_match_id,
};
static struct msm_sensor_ctrl_t adv7282m_s_ctrl = {
.sensor_i2c_client = &adv7282m_sensor_i2c_client,
.power_setting_array.power_setting = adv7282m_power_setting,
.power_setting_array.size = ARRAY_SIZE(adv7282m_power_setting),
.power_setting_array.power_down_setting = adv7282m_power_down_setting,
.power_setting_array.size_down =
ARRAY_SIZE(adv7282m_power_down_setting),
.msm_sensor_mutex = &adv7282m_mut,
.sensor_v4l2_subdev_info = adv7282m_subdev_info,
.sensor_v4l2_subdev_info_size = ARRAY_SIZE(adv7282m_subdev_info),
.func_tbl = &adv7282m_sensor_func_tbl,
};
module_init(adv7282m_init_module);
module_exit(adv7282m_exit_module);
MODULE_DESCRIPTION("ADV7282M 2MP YUV sensor driver");
MODULE_LICENSE("GPL v2");
3、vendor 代码:
目录:vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sensor_libs/adv7282m/
/* Copyright (c) 2012, The Linux Foundation. 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.
*
* Modify History For This Module
* When Who What,Where,Why
* --------------------------------------------------------------------------------------
* 13/09/21 Add driver for RoilTF's 1st sub CAM [can't work now]
* --------------------------------------------------------------------------------------
*/
#include
#include
#include "sensor_lib.h"
static sensor_lib_t sensor_lib_ptr;
static struct msm_sensor_init_params sensor_init_params = {
.modes_supported = 1,
.position = 1,
.sensor_mount_angle = 90,
};
static sensor_output_t sensor_output = {
.output_format = SENSOR_YCBCR,
.connection_mode = SENSOR_MIPI_CSI,
.raw_output = SENSOR_8_BIT_DIRECT,
};
static sensor_lens_info_t default_lens_info = {
.focal_length = 2.64, //EFL
.pix_size = 1.75,
.f_number = 2.8, //F no
.total_f_dist = 1.97,
.hor_view_angle = 57.5,
.ver_view_angle = 44.7,
};
#if 0
static struct csi_lane_params_t csi_lane_params = {
.csi_lane_assign = 0xE4,
.csi_lane_mask = 0xF,
.csi_if = 1,
.csid_core = {0},
.csi_phy_sel = 1,
};
#else
//by wangpl, this is used
static struct csi_lane_params_t csi_lane_params = {
.csi_lane_assign = 0x4320,
.csi_lane_mask = 0x3,
.csi_if = 1,
.csid_core = {0},
.csi_phy_sel = 1,
};
#endif
static struct msm_camera_csid_vc_cfg adv7282m_cid_cfg[] = {
{0, CSI_YUV422_8, CSI_DECODE_8BIT},
{1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
};
static struct msm_camera_csi2_params adv7282m_csi_params = {
.csid_params = {
.lane_cnt = 1,
.lut_params = {
.num_cid = ARRAY_SIZE(adv7282m_cid_cfg),
.vc_cfg = {
&adv7282m_cid_cfg[0],
&adv7282m_cid_cfg[1],
},
},
},
.csiphy_params = {
.lane_cnt = 1,
.settle_cnt = 0x1c, //5ns/1
},
};
static struct sensor_pix_fmt_info_t adv7282m_pix_fmt0_fourcc[] = {
{ V4L2_MBUS_FMT_UYVY8_2X8 },
};
static struct sensor_pix_fmt_info_t adv7282m_pix_fmt1_fourcc[] = {
{ MSM_V4L2_PIX_FMT_META },
};
static sensor_stream_info_t adv7282m_stream_info[] = {
{1, &adv7282m_cid_cfg[0], adv7282m_pix_fmt0_fourcc},
{1, &adv7282m_cid_cfg[1], adv7282m_pix_fmt1_fourcc},
};
static sensor_stream_info_array_t adv7282m_stream_info_array = {
.sensor_stream_info = adv7282m_stream_info,
.size = ARRAY_SIZE(adv7282m_stream_info),
};
static struct msm_camera_csi2_params *csi_params[] = {
&adv7282m_csi_params, /* RES 0*/
&adv7282m_csi_params, /* RES 1*/
};
static struct sensor_lib_csi_params_array csi_params_array = {
.csi2_params = &csi_params[0],
.size = ARRAY_SIZE(csi_params),
};
static struct sensor_crop_parms_t crop_params[] = {
// top, bottom, left, right
{0, 0, 0, 0}, /* RES 0 */
{0, 0, 0, 0}, /* RES 1 */
};
static struct sensor_lib_crop_params_array crop_params_array = {
.crop_params = crop_params,
.size = ARRAY_SIZE(crop_params),
};
static struct sensor_lib_out_info_t sensor_out_info[] = {
{ /* For SNAPSHOT */
.x_output = 720*2, // 1600*2 = 0x640 *2 = 0xC80, for 2Mp
.y_output = 525, // 1200 = 0x4B0
// no many use for YUV
//.line_length_pclk = 2236,
//.frame_length_lines = 1288, // AD_9M AD_LINE=1118 N=81
.vt_pixel_clk = 22680000,
.op_pixel_clk = 22680000,
.binning_factor = 1,
.max_fps = 30, //30
.min_fps = 7.5,//10
.mode = SENSOR_DEFAULT_MODE,
},
{
//by wangpl, set platform vfe clk. need >= camera, for preview
.x_output = 720*2, //640 x2 1600
.y_output = 525, //480 600
//.line_length_pclk = 2236, //
//.frame_length_lines = 623, // AD_18M AD_LINE=1118 N=161
.vt_pixel_clk = 22680000,
.op_pixel_clk = 22680000,
.binning_factor = 1,
.max_fps = 30, // //Must 30 ,can't change
.min_fps = 7.5,//10
.mode = SENSOR_DEFAULT_MODE,
},
};
static struct sensor_lib_out_info_array out_info_array = {
.out_info = sensor_out_info,
.size = ARRAY_SIZE(sensor_out_info),
};
static sensor_res_cfg_type_t adv7282m_res_cfg[] = {
SENSOR_SET_STOP_STREAM,
SENSOR_SET_NEW_RESOLUTION, /* set stream config */
SENSOR_SET_CSIPHY_CFG,
SENSOR_SET_CSID_CFG,
SENSOR_SEND_EVENT, /* send event */
SENSOR_SET_START_STREAM,
};
static struct sensor_res_cfg_table_t adv7282m_res_table = {
.res_cfg_type = adv7282m_res_cfg,
.size = ARRAY_SIZE(adv7282m_res_cfg),
};
static sensor_lib_t sensor_lib_ptr = {
/* sensor init params */
.sensor_init_params = &sensor_init_params,
/* sensor output settings */
.sensor_output = &sensor_output,
/* sensor snapshot exposure wait frames info */
.snapshot_exp_wait_frames = 2,//add
/* number of frames to skip after start stream */
.sensor_num_frame_skip = 1,
/* sensor pipeline immediate delay */
.sensor_max_pipeline_frame_delay = 0,
/* sensor lens info */
.default_lens_info = &default_lens_info,
/* csi lane params */
.csi_lane_params = &csi_lane_params,
/* csi cid params */
.csi_cid_params = adv7282m_cid_cfg,
/* csi csid params array size */
.csi_cid_params_size = ARRAY_SIZE(adv7282m_cid_cfg),
/* resolution cfg table */
.sensor_res_cfg_table = &adv7282m_res_table,
/* out info array */
.out_info_array = &out_info_array,
/* crop params array */
.crop_params_array = &crop_params_array,
/* csi params array */
.csi_params_array = &csi_params_array,
/* sensor port info array */
.sensor_stream_info_array = &adv7282m_stream_info_array,
};
/*===========================================================================
* FUNCTION - adv7282m_open_lib -
*
* DESCRIPTION:
*==========================================================================*/
void *adv7282m_open_lib(void)
{
ALOGE("=====>in [adv7282m_open_lib]n");
return &sensor_lib_ptr;
}
4、vendor 分辨率设置:
目录:vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/pipeline/mct_pipeline.c
--- a/src/LINUX/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/pipeline/mct_pipeline.c
+++ b/src/LINUX/android/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/pipeline/mct_pipeline.c
@@ -42,6 +42,7 @@ static cam_dimension_t default_preview_sizes[] = {
{ 800, 480}, // WVGA
{ 768, 432},
{ 720, 480},
+ { 720, 525},
{ 640, 480}, // VGA
{ 576, 432},
{ 480, 320}, // HVGA
@@ -65,14 +66,15 @@ static cam_dimension_t default_picture_sizes[] = {
{ 1280, 960},
{ 1280, 768}, // WXGA
{ 1280, 720}, // HD720
- { 1024, 768}, // 1MP XGA
+ { 1024, 768}, // 1MP XGA
{ 800, 600}, // SVGA
{ 800, 480}, // WVGA
{ 720, 480}, // 480p
+ { 720, 525},
{ 640, 480}, // VGA
- //{ 352, 288}, // CIF
+ { 352, 288}, // CIF
{ 320, 240}, // QVGA
- //{ 176, 144} // QCIF
+ { 176, 144} // QCIF
};
static cam_dimension_t default_liveshot_sizes[] = {
@@ -107,6 +109,7 @@ static cam_dimension_t default_video_sizes[] = {
{ 864, 480}, //FWVGA
{ 800, 480}, // WVGA
{ 720, 480}, // 480p
+ { 720, 525},
{ 640, 480}, // VGA
{ 480, 320}, // HVGA
{ 352, 288}, // CIF
@@ -117,7 +120,7 @@ static cam_dimension_t default_video_sizes[] = {
static cam_fps_range_t default_fps_ranges[] = {
{ 15.0, 15.0, 15.0, 15.0},
{ 24.0, 24.0, 24.0, 24.0},
- { 30.0, 30.0, 30.0, 30.0},
+ { 59.94, 59.94, 59.94, 59.94},
};
/** mct_pipeline_check_stream_t
5、vendor so文件的设置:
--- a/src/LINUX/android/vendor/qcom/proprietary/common/config/device-vendor.mk
+++ b/src/LINUX/android/vendor/qcom/proprietary/common/config/device-vendor.mk
@@ -936,6 +936,8 @@ MM_CAMERA += libmmcamera_skuf_ov5648_p5v23c
MM_CAMERA += libmmcamera_sp1628
MM_CAMERA += libmmcamera_gc2035
+MM_CAMERA += libmmcamera_adv7282m
+
MM_CAMERA += libmmcamera_statsproc31
MM_CAMERA += libmmcamera_sunny_p12v01m_eeprom