深入学习Linux摄像头(四)三星平台fimc驱动详解

深入学习Linux摄像头系列

深入学习Linux摄像头(一)v4l2应用编程

深入学习Linux摄像头(二)v4l2驱动框架

深入学习Linux摄像头(三)虚拟摄像头驱动分析

深入学习Linux摄像头(四)三星平台fimc驱动详解

深入学习Linux摄像头(四)三星平台fimc驱动详解

一、硬件接口

  • 摄像头

    摄像头传感器由摄像头接口和控制接口(一般为i2c)组成

    摄像头接口用于传输传感器采集到的数据

    控制接口用于控制摄像头传感器(例如设置图像格式…)

    在这里插入图片描述

  • 芯片

    芯片上由多个摄像头控制器,多个摄像头接口,多个i2c控制器(i2c总线)

    摄像头控制器负责控制摄像头接口和处理接收到的数据,摄像头接口负责传输图像数据,i2c控制器负责传输控制信息

    在这里插入图片描述

摄像头传感器和芯片的接法如下

在这里插入图片描述

其中摄像头控制器和摄像头接口是分离的,摄像头控制器可以选择控制哪一个摄像头接口

fimc是三星平台摄像头控制器的一套驱动程序

二、fimc驱动总览

fimc的文件集中在drivers/media/video/samsung/fimc目录下

有以下文件

  • fimc_dev.c

    fimc的平台驱动

  • fimc_v4l2.c

    实现了一系列的ioctl操作

  • fimc_capture.c

    实现了capture功能

  • fimc_output.c

    实现了output功能

  • fimc_overlay.c

    实现了overlay功能

  • fimc_regs.c

    fimc控制器的寄存器操作

  • csis.c

    csis接口的摄像头

各文件的组织形式如下

在这里插入图片描述

fimc_dev.c是平台的驱动,负责一些初始化的工作,fimc_v4l2.c设置了一系列的ioctl操作,fimc_capture.cfimc_output.cfimc_overlay.c实现了一些具体功能的ioctl,通过fimc_regs.c实现对摄像头控制器的硬件操作

三、源码分析

3.1 几个主要对象

在分析源码前,先介绍几个对象

  • s3c_platform_camera

    摄像头传感器

    struct s3c_platform_camera {
         
         
        /* 标记摄像头在哪个摄像头接口 */
    	enum fimc_cam_index		id;
    
        /* 摄像头接口类型 */
    	enum fimc_cam_type		type; //ITU or MIPI
        
        /* 像素格式 */
    	enum fimc_cam_format	fmt;
    
        /* i2c相关信息 */
    	int						i2c_busnum; //摄像头所接的i2c总线
    	struct i2c_board_info	  *info; //摄像头的i2c信息
    	struct v4l2_subdev		 *sd; //表明这是一个v4l2_subdev
    
    	int				width; //图像的宽
    	int				height; //图像的高
    
    
    	/* 摄像头接口的时序极性 */
    	int				inv_pclk;
    	int				inv_vsync;
    	int				inv_href;
    	int				inv_hsync;
    
        /* 使能摄像头 */
    	int				(*cam_power)(int onoff);
    };
    
  • s3c_platform_fimc

    摄像头接口的平台信息

    struct s3c_platform_fimc {
         
         
        /* 时钟相关 */
    	const char			srclk_name[16];		/* source of interface clock name */
    	const char			clk_name[16];		/* interface clock name */
    	const char			lclk_name[16];		/* interface clock name */
    	u32				clk_rate;		/* clockrate for interface clock */
    	
        /* 保存摄像头的信息 */
    	struct s3c_platform_camera	*camera[5];		/* FIXME */
    	
    	void				(*cfg_gpio)(struct platform_device *pdev);
    	int				(*clk_on)(struct platform_device *pdev, struct clk *clk);
    	int				(*clk_off)(struct platform_device *pdev, struct clk *clk);
    };
    
  • fimc_control

    摄像头控制器

    struct fimc_control {
         
         
        /* 寄存器地址 */
    	void __iomem			*regs;
    
    	/* video_device和v4l2_device */
    	struct video_device		*vd;
    	struct v4l2_device		v4l2_dev;
    
        ...
    };
    
  • fimc_global

    fimc驱动的全局变量

    struct fimc_global {
         
         
    	struct fimc_control		ctrl[FIMC_DEVICES]; //摄像头控制器
    	struct s3c_platform_camera	camera[FIMC_MAXCAMS]; //摄像头
    	int				camera_isvalid[FIMC_MAXCAMS]; //标记是否存在摄像头
    	int				active_camera; // 当前使用的摄像头
    };
    

介绍完上面几个结构体后,开始分析源码

3.2 fimc的平台设备

fimc的驱动采用的platform总线,分成设备和驱动,我们先介绍设备

首先看mach-smdkc110.c文件,这里描述了一系列的硬件信息

这里有多个摄像头描述,其中一个如下

static struct s3c_platform_camera s5k4ba = {
   
   
	.id		= CAMERA_PAR_A, //摄像头在接口A
	.type		= CAM_TYPE_ITU, //ITU模式
	.fmt		= ITU_601_YCBCR422_8BIT, //传感器输入格式YCbCr422
	.order422	= CAM_ORDER422_8BIT_CBYCRY, //输入Y U V的顺序
	.i2c_busnum	= 0, //i2c总线0
	.info		= &s5k4ba_i2c_info, //i2c的设备描述
	.pixelformat	= V4L2_PIX_FMT_UYVY, //经过摄像头控制器后的输出格式
	.srclk_name	= "mout_mpll",
	.clk_name	= "sclk_cam1",
	.clk_rate	= 44000000, //时钟频率
	.line_length	= 1920,
	.width		= 800, //图像宽
	.height		= 600, //图像高
	/* 裁剪 */
    .window		= {
   
   
		.left	= 0,
		.top	= 0,
		.width	= 800,
		.height	= 600,
	},

	/* 时序极性 */
	.inv_pclk	= 0,
	.inv_vsync	= 1,
	.inv_href	= 0,
	.inv_hsync	= 0,

	.initialized	= 0,
	.cam_power	= s5k5ba_power_en,
};

看一看s5k4ba_i2c_info

static struct i2c_board_info  s5k4ba_i2c_info = {
   
   
	I2C_BOARD_INFO("S5K4BA", 0x2d),
	.platform_data = &s5k4ba_plat,
};

其中表明i2c设备名称为S5K4BA,i2c从地址0x2d

再看一看s5k5ba_power_en如何使能摄像头

static int s5k5ba_power_en(int onoff)
{
   
   
    smdkv210_cam1_power(onoff);
}
/* 设置GPIO */
static int smdkv210_cam0_power(int onoff)
{
   
   
	int err;
	/* Camera A */
	err = gpio_request(GPIO_PS_VOUT, "GPH0");
	if (err)
		printk(KERN_ERR "failed to request GPH0 for CAM_2V8\n");

	s3c_gpio_setpull(GPIO_PS_VOUT, S3C_GPIO_PULL_NONE);
	gpio_direction_output(GPIO_PS_VOUT, 0);
	gpio_direction_output(GPIO_PS_VOUT, 1);
	gpio_free(GPIO_PS_VOUT);

	return 0;
}

s3c_platform_camera描述一个摄像头的信息(哪个摄像头接口,在哪个i2c总线,像素格式…)

s5k4ba被嵌入到fimc的平台数据中

static struct s3c_platform_fimc fimc_plat_lsi = {
   
   
	.srclk_name	= "mout_mpll",
	.clk_name	= "sclk_fimc",
	.lclk_name	= "sclk_fimc_lclk",
	.clk_rate	= 166750000,
	.default
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值