以方便后面的物理地址转换为虚拟地址
camera_dev->reg_base =ioremap(camera_dev->addr_res->start, iosize);//初始化
camera_dev->reg_base 这个成员,跟上面说那个结构体哪里一样,就是地址资源经过映
射后得到虚拟地址的首地址存储在这里
camera_dev->irq =camera_dev->irq_res->start;//初始化 camera_dev->irq 这个成员,其实
就是中断资源的第一个
camera_dev->fimc_clk =clk_get(camera_dev->dev, "fimc");//初始化 camera_dev-
>fimc_clk 这个成员,其实就是通过 clk_get 函数获取 fimc 时钟并赋值给过去
clk_enable(camera_dev->fimc_clk);//使能 fimc 时钟
camera_dev->cam_clk =clk_get(camera_dev->dev, "div_cam");//初始化 camera_dev-
>cam_clk 这个成员,通过 clk_get 获取时钟 cam_clk 时钟
clk_set_rate(camera_dev->cam_clk,24000000);//设置 cam_clk 的时钟为 24Mhz
camera_reset();//camera 复位函数,来看看 camera 接口初始化做了什么事情
writel(readl(camera_dev->reg_base +S5PC100_CISRCFMT) | 1<< 31, camera_dev-
>reg_base + S5PC100_ CISRCFMT);
这里将 CISRCFMTn 这个寄存器的 31 位置 1,那么就是选择 ITU-R BT.601 YCbCr 8-bit
mode enable
writel(readl(camera_dev->reg_base +S5PC100_CIGCTRL) | 1<< 31, camera_dev-
>reg_base + S5PC100_CIGCTRL);
这里是将 CIGCTRLn 的第三十一位置 1,该位为 camera 的软复位位,这里写 1,产生复
位
mdelay(10);//延时等待复位
writel(readl(camera_dev->reg_base +S5PC100_CIGCTRL) & ~(1<< 31), camera_dev-
>reg_base +S5PC100_CIGCTRL);
这里是将 CIGCTRLn 的第三十一位置 0,取消复位;
到这里这个函数就完了,我们接着往下看
sensor_reset(); //外设复位
writel(readl(camera_dev->reg_base +S5PC100_CIGCTRL) | 1<< 30, camera_dev-
>reg_base + S5PC100_CIGCTRL);
这里是将 CIGCTRLn 的第三十位置 1,该位为外设电源,这里写 1,外设断电复位
mdelay(10);延时等待复位
writel(readl(camera_dev->reg_base +S5PC100_CIGCTRL) & ~(1<< 30), camera_dev-
>reg_base +S5PC100_CIGCTRL);重新给外设上电
到这里这个函数结束
mdelay(10); 延时 10ms 等待
for(i = 0; i <ARRAY_SIZE(s5pc100_sensor_table); i++)
{
s5pc100_sensor_table[i].init();
}
这里是循环调用 s5pc100_sensor_table[i].init();这个函数表里面成员的 init 函数来初始化,
用法跟汇编里面查表类似来看看这个循环里面做了什么事情,首先来看看这个函数表里面
的函数
struct s5pc100_sensor s5pc100_sensor_table[] =