1、先在lichee\tools\pack\chips\config\sys_config.fex 里面的[csi0]节点下,配置双摄
;vip (video input port) configuration
;vip_used: 0:disable 1:enable
;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer
;vip_dev_qty: The quantity of devices linked to capture bus
;
;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and
; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured!
;
;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1,vip_dev(x)_pos must be configured!
;
;vip_dev(x)_isp_used 0:not use isp 1:use isp
;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb
;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby
;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable
;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable
;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply
;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply
;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply
;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply
;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply
;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply
;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply
;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply
;x indicates the index of the devices which are linked to the same capture bus
;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000
;fill handle string as below:
;axp22_eldo3
;axp22_dldo4
;axp22_eldo2
;fill handle string "" when not using any pmu power supply
[csi0]
vip_used = 1 ;是否使用摄像头 0:disable 1:enable
vip_mode = 0 ;one interface to one buffer
vip_dev_qty = 2 ;link to capture bus的设备数量,双摄
vip_define_sensor_list = 0 ;是否使用了sensor detect功能
;原理图上引脚定义(vip_csi_XX)对应的gpio口(以SOC上的对应的gpio为准,有些小公司硬件出图不严谨)
; port configuration:
; port_name = port:GPIO<mux><pull up/down><driver level><default value>
; mux: GPIO function configuration, 0-input, 1-output, 2+: special funciton for modules
; pull up/down: 1-pull up, 2-pull down
; driver level: 0,1,2,3. 2 is recommended
; default value: default output value when this IO is configured as an output IO
vip_csi_pck = port:PE00<2><default><default><default>
vip_csi_mck = port:PE01<2><default><default><default>
vip_csi_hsync = port:PE02<2><default><default><default>
vip_csi_vsync = port:PE03<2><default><default><default>
vip_csi_d0 = port:PE04<2><default><default><default>
vip_csi_d1 = port:PE05<2><default><default><default>
vip_csi_d2 = port:PE06<2><default><default><default>
vip_csi_d3 = port:PE07<2><default><default><default>
vip_csi_d4 = port:PE08<2><default><default><default>
vip_csi_d5 = port:PE09<2><default><default><default>
vip_csi_d6 = port:PE10<2><default><default><default>
vip_csi_d7 = port:PE11<2><default><default><default>
vip_dev0_mname = "gc2145r" ;与drive.c中进行匹配的名字
vip_dev0_pos = "rear" ;.前摄还是后摄
vip_dev0_lane = 1 ;camera sensor使用的是8 or 10bit的RGB ROW,1lane指只具有一组8bit的RGB ROW 即CSI-D0-D7
vip_dev0_twi_id = 2 ;原理图上CSI-SCK对应gpio对应的 I2C 组号,sysconfig.fex中的 I2C_CONFIG下的 i2c组号下的used 必须为1 即enable, 该组号下的 I2C_CLK、SDA必须与原理图上的gpio口对应,否则 I2C 无法通信
vip_dev0_twi_addr = 0x78 ;I2C ADDR
vip_dev0_isp_used = 0 ;是否使用 ISP
vip_dev0_fmt = 0 ;输出格式 0:yuv 1:bayer raw rgb
vip_dev0_stby_mode = 0 ;0:not shut down power at standby 1:shut down power at standby
vip_dev0_vflip = 0 ;垂直翻转
vip_dev0_hflip = 0 ;水平翻转
vip_dev0_iovdd = "axp22_dldo3"
vip_dev0_iovdd_vol = 2800000 ;
vip_dev0_avdd = "axp22_ldoio0"
vip_dev0_avdd_vol = 2800000
vip_dev0_dvdd = "axp22_eldo2"
vip_dev0_dvdd_vol = 1800000
vip_dev0_afvdd =
vip_dev0_afvdd_vol =
vip_dev0_power_en =
vip_dev0_reset = port:PE16<1><default><default><0> ;reset 引脚对应的 gpio
vip_dev0_pwdn = port:PE15<1><default><default><1> ;stby对应的gpio
vip_dev0_flash_en =
vip_dev0_flash_mode =
vip_dev0_af_pwdn =
vip_dev1_mname = "gc2145f"
vip_dev1_pos = "front"
vip_dev1_lane = 1
vip_dev1_twi_id = 2
vip_dev1_twi_addr = 0x42
vip_dev1_isp_used = 0
vip_dev1_fmt = 0
vip_dev1_stby_mode = 0
vip_dev1_vflip = 1
vip_dev1_hflip = 1
vip_dev1_iovdd = "axp22_dldo3"
vip_dev1_iovdd_vol = 2800000
vip_dev1_avdd = "axp22_ldoio0"
vip_dev1_avdd_vol = 2800000
vip_dev1_dvdd = "axp22_eldo2"
vip_dev1_dvdd_vol = 1800000
vip_dev1_afvdd =
vip_dev1_afvdd_vol =
vip_dev1_power_en =
vip_dev1_reset = port:PE16<1><default><default><0>
vip_dev1_pwdn = port:PB03<1><default><default><1> ;前后摄stby对应的gpio不能一样,原理图会给出两个不同的gpio
vip_dev1_flash_en =
vip_dev1_flash_mode =
vip_dev1_af_pwdn =
2、在lichee\linux 3.4\drive\media\video\sunxi_vfe\devices\camera.c 在这目录下添加came drive.c文件,并配置Makefile ,配置Makefile时 用obj -m +=camera.c 便于模块化编译,也便于在android\device\softwinner\aster-m86\init.sun8i.rc 里的modules下添加该camera.ko 开机自动加载。避免配置Kconfig后.config更改又得重新配置linux编译环境
3、如果双摄 I2C ADDR 一样,则会存在冲突,需要在lichee\linux 3.4\drive\media\video\sunxi_vfe\cci_help\cci_help.c下cci_read_a8_d8函数下和cci_write_a8_d8函数下(ADDR 8位,DATA 8位)把其中一个摄像头的 I2C ADDR 右移一位得到msg[0].addr = 0x3c(右移一位后的数据);从而解决了 I2C地址冲突的问题,如果两个摄像头 I2C地址没有冲突,则无需更改
4、lichee\linux-3.4\drivers\media\video\sunxi-vfe\sensorinfo.c里,如果sensor没有注册上时,可以在sensorinfo.c 的sensor_list_t中手动添加
5、android\device\softwinner\astar-m86\configs\camera.cfg中可以配置camera_orientation=180和支持的图片SIZEkey_support_picture_size = 1600x1200
6、android\device\softwinner\polaris-common\hardware\camera\在 hal 层这目录下的
/****************************************************/
HALCameraFactory.cpp:
int HALCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
{
if (total_num_of_cameras == 2)
{
getCallingProcessName(calling_process);
if(strcmp(calling_process, "com.tencent.devicedemo") == 0)
{
LOGE("--------== agSRGERghhq=======857: id = %d", camera_id);
// cts, mobile qq need facing-back camera
info->facing = CAMERA_FACING_FRONT;
info->orientation = 0;
}
if((strcmp(calling_process, "com.cloudring.magic") == 0))
{
LOGE("--------=========857: id = %d", camera_id);
// cts, mobile qq need facing-back camera
info->facing = CAMERA_FACING_FRONT;
info->orientation = 0;
}
if(strcmp(calling_process, "com.lejent.zuoyeshenqi.afanti") == 0)
{
info->facing = CAMERA_FACING_FRONT;
info->orientation = 0;
LOGE("--------=========333333: id = %d", camera_id);
}
if((strcmp(calling_process, "com.android.camera2")== 0)) //»ñÈ¡µ±Ç°°üÃû
{
LOGE("77777777777777777777777777\n");
char prop_value[512];
property_get("sys.product.camera.used", prop_value, "");
if(atoi(prop_value) == 1) //Ç¿ÖÆת»»×Ö·ûÀàÐÍΪÕûÐÎ
{
// camera_id =0; //Ç¿ÖÆÐÞ¸ÄÐèÒª´ò¿ªµÄÉãÏñÍ·ID
info->facing = CAMERA_FACING_BACK;
info->orientation = 180;
LOGE("pppppppppppppppppppppppppppp\n");
}
else
{
// camera_id =1;
info->facing = CAMERA_FACING_BACK;
info->orientation = 0;
LOGE("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n");
}
}
if(strcmp(calling_process, "com.cloudring.picbook") == 0)
{
LOGE("--------==com.cloudring.picbook=======857: id = %d", CAMERA_FACING_FRONT);
// cts, mobile qq need facing-back camera
info->facing = CAMERA_FACING_FRONT;
info->orientation = 0;
}
}
int HALCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
{
LOGV("%s: id = %d", __FUNCTION__, camera_id);
*device = NULL;
int total_num_of_cameras = mAttachedCamerasNum + mRemovableCamerasNum;
char calling_process[256];
getCallingProcessName(calling_process);
if((strcmp(calling_process, "com.android.camera2")== 0) ) //»ñÈ¡µ±Ç°°üÃû
{
char prop_value[512];
//»ñÈ¡sys.product.camera.used ÊôÐÔ£¬Õâ¸öÊÇͨ¹ýAPP½øÐеÄÉèÖ㬱£´æÔÚprop_value
property_get("sys.product.camera.used", prop_value, "");
if(atoi(prop_value) == 1) //Ç¿ÖÆת»»×Ö·ûÀàÐÍΪÕûÐÎ
{
camera_id =0; //Ç¿ÖÆÐÞ¸ÄÐèÒª´ò¿ªµÄÉãÏñÍ·ID
LOGE("%s: ----iffffffff---->id = %d", __FUNCTION__, camera_id);
}
else
{
LOGE("%s: ----elssssssssss---->id = %d", __FUNCTION__, camera_id);
camera_id =1;
}
}
}
/****************************************************/
V4L2CameraDevice.cpp中无需添加什么
/****************************************************/
V4L2CameraDevice2.cpp:
添加#include <cutils/properties.h>
int V4L2CameraDevice::setVideoHflip(bool fliped)
{
F_LOG;
int ret = -1;
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_HFLIP;
if(fliped){
LOGD(" set H----->1..\n");
ctrl.value = 1;
}
else{
LOGD(" set H----->0..\n");
ctrl.value = 0;
}
ret = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0)
LOGD("setVideoHflip failed, %s", strerror(errno));
else
LOGD("setVideoHflip ok");
return ret;
}
int V4L2CameraDevice::setVideoVflip(bool fliped)
{
F_LOG;
int ret = -1;
struct v4l2_control ctrl;
ctrl.id = V4L2_CID_VFLIP;
if(fliped){
LOGD(" set V----->1..\n");
ctrl.value = 1;
}
else{
LOGD(" set V----->0..\n");
ctrl.value = 0;
}
ret = ioctl(mCameraFd, VIDIOC_S_CTRL, &ctrl);
if (ret < 0)
LOGD("setVideoVflip failed, %s", strerror(errno));
else
LOGD("setVideoVflip ok");
return ret;
}
char calling_process_for_qq[256];
getCallingProcessName(calling_process_for_qq);
LOGD("calling process: %s", calling_process_for_qq);
if (strcmp(calling_process_for_qq, "com.Yin.ARTeaching") == 0)
{
LOGD("huiben camera facing.............H\n");
setVideoHflip(0);
//setVideoVflip(1);
}
LOGD("calling process: %s", calling_process_for_qq);
if(strcmp(calling_process_for_qq, "com.cloudring.magic.camera") == 0)
{
LOGD("huiben camera facing.............H\n");
//setVideoHflip(0);
setVideoVflip(0);
}
if((strcmp(calling_process_for_qq, "com.mosca.XBbaike") == 0))
{
LOGD("com.mosca.XBbaike camera facing.............H\n");
// setVideoHflip(0);
// setVideoVflip(1);
}
if((strcmp(calling_process_for_qq, "com.lejent.zuoyeshenqi.afanti") == 0))
{
setVideoHflip(0);
}
if((strcmp(calling_process_for_qq, "com.cloudring.magic") == 0))
{
setVideoVflip(1);
LOGE("=====com.cloudring.magic\n");
}
if((strcmp(calling_process_for_qq, "com.android.camera2")== 0)) //获取当前包名
{
char prop_value[512];
property_get("sys.product.camera.used", prop_value, "");
if(atoi(prop_value) == 1) //强制转换字符类型为整形
{
setVideoVflip(1);
LOGE("ffffffffffffffffffffffffffff\n");
}
else
{
setVideoHflip(0);
LOGE("2222222222222222222222222222222222\n");
}
}
if ((strcmp(calling_process_for_qq, "com.cloudring.picbook") == 0))
{
LOGD("com.cloudring.picbook camera facing.............H\n");
setVideoHflip(0);
// setVideoVflip(0);
}
char calling_process_for_qq[256];
getCallingProcessName(calling_process_for_qq);
LOGD("calling process: %s", calling_process_for_qq);
if(strcmp(calling_process_for_qq, "com.Yin.ARTeaching") == 0)
{
LOGD("huiben camera facing , rotate");
setVideoHflip(0);
//setVideoVflip(1);
}
LOGD("calling process: %s", calling_process_for_qq);
if(strcmp(calling_process_for_qq, "com.cloudring.magic.camera") == 0)
{
LOGD("huiben camera facing.............H\n");
//setVideoHflip(0);
setVideoVflip(0);
}
if ((strcmp(calling_process_for_qq, "com.mosca.XBbaike") == 0) )
{
LOGD("weixin camera facing.............H\n");
//setVideoHflip(0);
//setVideoVflip(1);
}
if((strcmp(calling_process_for_qq, "com.lejent.zuoyeshenqi.afanti") == 0))
{
setVideoHflip(0);
}
if((strcmp(calling_process_for_qq, "com.cloudring.magic") == 0))
{
setVideoVflip(1);
LOGE("=====com.cloudring.magic\n");
}
if((strcmp(calling_process_for_qq, "com.android.camera2")== 0)) //获取当前包名
{
char prop_value[512];
property_get("sys.product.camera.used", prop_value, "");
if(atoi(prop_value) == 1) //强制转换字符类型为整形
{
setVideoHflip(1);
}
else
{
setVideoHflip(0);
LOGE("2222222222222222222222222222222222\n");
}
}
if ((strcmp(calling_process_for_qq, "com.cloudring.picbook") == 0))
{
LOGD("com.cloudring.picbook camera facing.............H\n");
setVideoHflip(0);
// setVideoVflip(1);
}
7、android\frameworks\base\core\java\android\hardware\Camera.java的修改如下
Log.e(TAG, "--------call cam :" +packageName );
if(packageName.equals("com.cloudring.picbook")){
cameraId = 1;
}
if(packageName.equals("com.Yin.ARTeaching")){
cameraId = 1;
}
if(packageName.equals("com.cloudring.magic")){
cameraId = 0;
}
这文件是与上层进行交互的camera的接口函数
hal、framework接口搞好后,camera是可以正常工作了的,如果没有LCD、TP支持,则可以通过连上adb 后由 total control 进行安卓投影,在系统自带的camera apk上测试验证camera是否已经ok
camera的hal、framework还不怎么熟,后续还要跟下camera的整个流程