static void camif_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
{
if(src >= 64*tar) {return;}
else if(src >= 32*tar) {*ratio = 32; *shift = 5;}
else if(src >= 16*tar) {*ratio = 16; *shift = 4;}
else if(src >= 8*tar) {*ratio = 8; *shift = 3;}
else if(src >= 4*tar) {*ratio = 4; *shift = 2;}
else if(src >= 2*tar) {*ratio = 2; *shift = 1;}
else {*ratio = 1; *shift = 0;}
}
static void cmos_ov7740_calculate_scaler_info(void)
{
unsigned int sx, sy, tx, ty;
sx = SRC_Width;
sy = SRC_Height;
tx = TargetHsize_Pr;
ty = TargetVsize_Pr;
printk("%s: SRC_in(%d, %d), Target_out(%d, %d)\n", __func__, sx, sy, tx, ty);
camif_get_scaler_factor(sx, tx, &sc.PreHorRatio, &sc.H_Shift);
camif_get_scaler_factor(sy, ty, &sc.PreVerRatio, &sc.V_Shift);
sc.PreDstWidth = sx / sc.PreHorRatio;
sc.PreDstHeight = sy / sc.PreVerRatio;
sc.MainHorRatio = (sx << 8) / (tx << sc.H_Shift);
sc.MainVerRatio = (sy << 8) / (ty << sc.V_Shift);
sc.SHfactor = 10 - (sc.H_Shift + sc.V_Shift);
sc.ScaleUpDown = (tx>=sx)?1:0;
}
/* A11 启动传输
* 参考: uvc_video_enable(video, 1):
* uvc_commit_video
* uvc_init_video
*/
static int cmos_ov7740_vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
unsigned int Main_burst, Remained_burst;
/*
CISRCFMT:
bit[31] -- 选择传输方式为BT601或者BT656
bit[30] -- 设置偏移值(0 = +0 (正常情况下) - for YCbCr)
bit[29] -- 保留位,必须设置为0
bit[28:16] -- 设置源图片的水平像素值(640)
bit[15:14] -- 设置源图片的颜色顺序(0x0c --> 0x2)
bit[12:0] -- 设置源图片的垂直像素值(480)
*/
*CISRCFMT |= (0<<30)|(0<<29)|(CAM_SRC_HSIZE<<16)|(CAM_ORDER_CbYCrY<<14)|(CAM_SRC_VSIZE<<0);
/*
CIWDOFST:
bit[31] -- 1 = 使能窗口功能、0 = 不使用窗口功能
bit[30、15:12]-- 清除溢出标志位
bit[26:16] -- 水平方向的裁剪的大小
bit[10:0] -- 垂直方向的裁剪的大小
*/
*CIWDOFST |=(1<<30)|(0xf<<12);
*CIWDOFST |= (1<<31)|(WinHorOfst<<16)|(WinVerOfst<<0);
SRC_Width = CAM_SRC_HSIZE - 2*WinHorOfst;
SRC_Height = CAM_SRC_VSIZE - 2*WinVerOfst;
/*
CIGCTRL:
bit[31] -- 软件复位CAMIF控制器
bit[30] -- 用于复位外部摄像头模块
bit[29] -- 保留位,必须设置为1
bit[28:27] -- 用于选择信号源(00 = 输入源来自摄像头模块)
bit[26] -- 设置像素时钟的极性(猜0)
bit[25] -- 设置VSYNC的极性(0)
bit[24] -- 设置HREF的极性(0)
*/
*CIGCTRL |= (1<<29)|(0<<27)|(0<<26)|(0<<25)|(0<<24);