高通骁龙系列 Android驱动层 Camera摄像头驱动配置方法、代码说明等。
Camera Sensor 按输出数据类型可分为RAW Sensor 和YUV Sensor。
RAW Sensor 的输出数据经由ISP 处理。配合RAW Sensor 时,ISP 实现的功能包括:自动曝光、自动增益、自动白平衡、坏点检测、镜头阴影校正、灯光闪烁消除、伽玛校正、图像降噪、锐化增强、高动态范围等。开发RAW Sensor 时,需要调整ISP 参数来调试图像效果。
YUV Sensor 的输出数据也经由ISP 处理,但ISP 仅负责图像裁剪、伸缩、特效功能,主要的图像处理由Sensor 内置的图像处理单元完成。
Camera Sensor 的代码在drivers/media/video/comip/sensors 目录,开发RAW Sensor 可参照ov5648 的代码,开发YUV Sensor 可参照gc2145 的代码,1860 的camera 接口全部为mipi 接口,没有DVP 接口,前摄的m_clk 是19.5MHZ,后摄为26MHZ。OV5648 的配置如下:
(1) GPIO
board-xxx.h 文件中存放了GPIO 管脚的定义值,以ov5648 为例:
#if defined(CONFIG_VIDEO_OV5648)
#define OV5648_POWERDOWN_PIN MFP_PIN_GPIO(172)
#define OV5648_RESET_PIN MFP_PIN_GPIO(170)
#endif修改时作类似定义即可。
Board-xxx.c 中,需要设置相应pin 脚的复用模式:
在static struct mfp_pin_cfg comip_mfp_cfg[]数组定义中增加如下:
#if defined(CONFIG_VIDEO_OV5648){OV5648_POWERDOWN_PIN, MFP_PIN_MODE_GPIO},{OV5648_RESET_PIN, MFP_PIN_MODE_GPIO},
#endif
(2) Sensor Client 的板级配置
Board-xxx.c 中,对client 进行配置,以ov5648 为例:
static struct comip_camera_client comip_camera_clients[] = {
#if defined(CONFIG_VIDEO_OV5648)
{
.board_info = &ov5648_board_info,
.flags = CAMERA_CLIENT_IF_MIPI,
.caps = CAMERA_CAP_FOCUS_INFINITY
| CAMERA_CAP_FOCUS_AUTO
| CAMERA_CAP_FOCUS_CONTINUOUS_AUTO
| CAMERA_CAP_METER_CENTER
| CAMERA_CAP_METER_DOT
| CAMERA_CAP_FACE_DETECT
| CAMERA_CAP_ANTI_SHAKE_CAPTURE
| CAMERA_CAP_HDR_CAPTURE,
.if_id = 1,
.mipi_lane_num = 2,
.power = ov5648_power,
.reset = ov5648_reset, },
#endif
若sensor 的size 较大(如:8M、13M),需要采用ISP 的高速时钟时,则在flag 中配置:
.flags = CAMERA_CLIENT_IF_MIPI
|CAMERA_CLIENT_CLK_EXT
|CAMERA_CLIENT_ISP_CLK_HIGH,
CAMERA_CLIENT_CLK_EXT 表明采用的是BB 端的时钟,
CAMERA_CLIENT_ISP_CLK_HIGH 表示采用ISP 的高速时钟,最大可配置为416MHZ,目
前默认为312MHZ。
(3) 电源管理
电源配置和复位时序会影响到Camera 能否正常工作,具体实现也在板级文件中,以ov5648
为例:
#if defined(CONFIG_VIDEO_OV5648)
static int ov5648_pwdn = mfp_to_gpio(OV5648_POWERDOWN_PIN);
static int ov5648_rst = mfp_to_gpio(OV5648_RESET_PIN);
static int ov5648_power(int onoff)
{
printk("ov5648 power : %dn", onoff);
if (onoff) {
pmic_voltage_set(PMIC_POWER_CAMERA_IO, 1,
PMIC_POWER_VOLTAGE_ENABLE);
pmic_voltage_set(PMIC_POWER_CAMERA_ANALOG, 1,
PMIC_POWER_VOLTAGE_ENABLE);
pmic_voltage_set(PMIC_POWER_CAMERA_CORE, 1,
PMIC_POWER_VOLTAGE_ENABLE);
gpio_request(ov5648_pwdn, "OV5648 Powerdown");
gpio_direction_output(ov5648_pwdn, 1);
msleep(50);
gpio_free(ov5648_pwdn);
} else {
pmic_voltage_set(PMIC_POWER_CAMERA_IO, 1,
PMIC_POWER_VOLTAGE_DISABLE);
pmic_voltage_set(PMIC_POWER_CAMERA_ANALOG, 1,
PMIC_POWER_VOLTAGE_DISABLE);
pmic_voltage_set(PMIC_POWER_CAMERA_CORE, 1,
PMIC_POWER_VOLTAGE_DISABLE);
gpio_request(ov5648_pwdn, "OV5648 Powerdown");
gpio_direction_output(ov5648_pwdn, 0);
gpio_free(ov5648_pwdn);
}
return 0;
}
static int ov5648_reset(void)
{
printk("ov5648 resetn");
gpio_request(ov5648_rst, "OV5648 Reset");
gpio_direction_output(ov5648_rst, 0);
msleep(50);
gpio_direction_output(ov5648_rst, 1);
msleep(50);
gpio_free(ov5648_rst);
return 0;
}
static struct i2c_board_info ov5648_board_info = {
.type = "ov5648",
.addr = 0x36,//sensor 的I2C 地址
};
(4) 添加Chip_Ident
在v4l2-chip-ident.h 文件中添加sensor 的chip_ident,尽量将同一厂商的sensor 按照顺序写
在一起,如:
V4L2_IDENT_OV5648 = 264,
(5) Makefile、Kconfig 和defconfig 默认编译项
在加入新增器件的源文件,配置好相应的板级信息后,还要做好相关的编译配置,使得
系统编译的时候能够被正确的加入到kernel 中。
Makefile
在archarmplat-lcdriverscamerasensor中的Makefile的最后添加类似如下示例的编译语
句
obj-$(CONFIG_VIDEO_OV5648) += ov5648.o
Kconfig
在archarmplat-lcdriverscamerasensors 中的Kconfig 的最后添加类似如下示例的语句,
以供menuconfig 使用。
config VIDEO_OV5648
tristate "OmniVision OV5648 sensor support"
depends on I2C && VIDEO_V4L2
---help---
This is a Video4Linux2 sensor-level driver for the OmniVision
OV5648 5.0 Mpixel camera.
defconfig 默认编译项
在archarmconfigs下有板卡的默认编译配置。如果要使新增的触摸屏成为某个板卡的
默认配置,需要开启对应板卡的默认编译项。以Lc1860evb 板为例,其默认配置文件为
lc1860_evb_defconfig,在其中Camera 部分增加类似如下示例的语句
CONFIG_VIDEO_OV5648=y
将不使用的Camera 做如下设置
# CONFIG_VIDEO_OV8825 is not set
需要特别留意的是,以上宏定义需和板卡配置文件以及Makefile 和Kconfig 中一致,否则无法正确配置。