fs4412开发板学习笔记(九)

来源:互联网 发布:中国木制品数据 编辑:程序博客网 时间:2024/06/05 08:34
分析linux-3.0-fs4412_v7的fimc是如何调用ov3640的:cp arch/arm/boot/uImage /tftpboot/uImage_3.14.29系统启动时的信息:[    4.137178] FIMC0 registered successfully[    4.141076] FIMC1 registered successfully[    4.145056] FIMC2 registered successfully[    4.149059] FIMC3 registered successfully\linux-3.0-fs4412_v7\drivers\media\video\samsung\fimc\Fimc_dev.c  1768platform_driver_register(&fimc_driver);static int __devinit fimc_probe(struct platform_device *pdev){    /* V4L2 device-subdev registration */    ret = v4l2_device_register(&pdev->dev, &ctrl->v4l2_dev);//初始化v4l2_device结构    /* things to initialize once */    ret = fimc_init_global(pdev);    这里面会完成摄像头的分配以及时钟的获取    这个platform_device是内核从平台代码那里传递过来的,    里面包含的就是和具体平台相关的信息,其中就应该包含摄像头信息。    /* video device register */    ret = video_register_device(ctrl->vd, VFL_TYPE_GRABBER, ctrl->id);    video_set_drvdata(ctrl->vd, ctrl);    ret = device_create_file(&(pdev->dev), &dev_attr_log_level);    ret = device_create_file(&(pdev->dev), &dev_attr_range_mode);    printk(KERN_INFO "FIMC%d registered successfully\n", ctrl->id);//是在这里打印.}相机启动拍照信息(1):<4>[  145.909856] s3c-fimc0: FIMC0 1 opened.                                                //ov3640驱动开始:<6>[  145.910423] OV3640 7-003c: fetching platform data<6>[  145.910444] OV3640 7-003c: parallel mode<6>[  145.910462] OV3640 7-003c: ov3640 has been probed<6>[  145.910884] OV3640 7-003c: ov3640_init: camera initialization start<4>[  145.910901] leesheen : sensor is power on                                  ||                  \/=============================================================\linux-3.0-fs4412_v7\drivers\media\video\samsung\fimc\Fimc_dev.cstatic int fimc_open(struct file *filp){    if (in_use >= max_use) {        ret = -EBUSY;        goto resource_busy;    } else {        atomic_inc(&ctrl->in_use);        fimc_warn("FIMC%d %d opened.\n", ctrl->id, atomic_read(&ctrl->in_use));//打印第一条信息    }}=================//ov3640.cstatic int ov3640_s_config(struct v4l2_subdev *sd, int irq, void *platform_data){    struct i2c_client *client = v4l2_get_subdevdata(sd);    struct ov3640_state *state = to_state(sd);    struct ov3640_platform_data *pdata;    dev_info(&client->dev, "fetching platform data\n");//打印第二条信息    pdata = client->dev.platform_data;    if (!pdata->is_mipi)    {        state->is_mipi = 0;        dev_info(&client->dev, "parallel mode\n");//打印第三条信息    }}static int ov3640_probe(struct i2c_client *client,        const struct i2c_device_id *id){    struct ov3640_state *state;    struct v4l2_subdev *sd;    int ret = 0;    state = kzalloc(sizeof(struct ov3640_state), GFP_KERNEL);    if (state == NULL)        return -ENOMEM;    sd = &state->sd;    strcpy(sd->name, OV3640_DRIVER_NAME);    /* Registering subdev */    v4l2_i2c_subdev_init(sd, client, &ov3640_ops);    dev_info(&client->dev, "ov3640 has been probed\n");//打印第四条信息}static int ov3640_init(struct v4l2_subdev *sd, u32 val){    struct i2c_client *client = v4l2_get_subdevdata(sd);    struct ov3640_state *state = to_state(sd);    int err = -EINVAL;    v4l_info(client, "%s: camera initialization start\n", __func__);//打印第五条信息    ov3640_power(1);}static int ov3640_power(int flag){    printk("leesheen : sensor is power %s\n",flag == 1 ?"on":"off");//打印第六条信息    //Attention: Power On the all the camera module when system turn on    //Here only control the reset&&powerdown pin  }相机启动拍照信息(2):<4>[  145.991430] s3c-fimc1: FIMC1 1 opened.<4>[  146.341052] ov3640_s_mbus_fmt<4>[  146.341065] ov3640_s_mbus_fmt<4>[  146.341074] ov3640_s_mbus_fmt<4>[  146.343097] ov3640_enum_framesizes<4>[  146.343110] s_stream: mode = 1<4>[  146.343120] ov3640_s_stream: do nothing(movie on)!!                                  ||                  \/=============================================================\linux-3.0-fs4412_v7\drivers\media\video\samsung\fimc\Fimc_dev.cstatic int fimc_open(struct file *filp){    if (in_use >= max_use) {        ret = -EBUSY;        goto resource_busy;    } else {        atomic_inc(&ctrl->in_use);        fimc_warn("FIMC%d %d opened.\n", ctrl->id, atomic_read(&ctrl->in_use));//打印第一条信息    }}=================//ov3640.cstatic int ov3640_s_mbus_fmt(struct v4l2_subdev *sd,struct v4l2_mbus_framefmt *fmt){    printk("%s\n", __func__);//打印第二条信息    printk("%s\n", __func__);    printk("%s\n", __func__);}static int ov3640_enum_framesizes(struct v4l2_subdev *sd,struct v4l2_frmsizeenum *fsize){    printk("%s\n", __func__);//打印第三条信息}static int ov3640_s_stream(struct v4l2_subdev *sd, int enable){    struct ov3640_state *state = to_state(sd);    int err = 0;    printk("s_stream: mode = %d\n", enable);//打印第四条信息    case STREAM_MODE_CAM_ON:    case STREAM_MODE_MOVIE_ON:        printk("%s: do nothing(movie on)!!\n", __func__);//打印第五条信息        break;    case STREAM_MODE_MOVIE_OFF:        printk("%s: do nothing(movie off)!!\n", __func__);        break;    default:        printk("%s: ERROR, Invalid stream mode %d\n",                    __func__, enable);        err = -EINVAL;        break;    }}相机启动拍照信息(3):<4>[  153.841047] s_stream: mode = 0<4>[  153.841060] ov3640_s_stream: do nothing(movie on)!!<4>[  153.850673] ov3640_s_mbus_fmt<4>[  153.850699] ov3640_s_mbus_fmt<4>[  153.850709] ov3640_s_mbus_fmt<4>[  153.852413] ov3640_enum_framesizes<4>[  153.852430] s_stream: mode = 1<4>[  153.852443] ov3640_s_stream: do nothing(movie on)!!                                  ||                  \/=============================================================static int ov3640_s_stream(struct v4l2_subdev *sd, int enable){    struct ov3640_state *state = to_state(sd);    int err = 0;    printk("s_stream: mode = %d\n", enable);//打印第1条信息    case STREAM_MODE_CAM_ON:    case STREAM_MODE_MOVIE_ON:        printk("%s: do nothing(movie on)!!\n", __func__);//打印第2条信息        break;    case STREAM_MODE_MOVIE_OFF:        printk("%s: do nothing(movie off)!!\n", __func__);        break;    default:        printk("%s: ERROR, Invalid stream mode %d\n",                    __func__, enable);        err = -EINVAL;        break;    }}static int ov3640_s_mbus_fmt(struct v4l2_subdev *sd,struct v4l2_mbus_framefmt *fmt){    printk("%s\n", __func__);//打印第3条信息    printk("%s\n", __func__);    printk("%s\n", __func__);}static int ov3640_enum_framesizes(struct v4l2_subdev *sd,struct v4l2_frmsizeenum *fsize){    printk("%s\n", __func__);//打印第4条信息}相机启动拍照信息(4):<3>[  154.344485] OV3640 7-003c: ov3640_g_ctrl: no such ctrl<7>[  154.349764] vb2_common_vm_close: d4ccfed4, refcount: 2, vma: 40fd7000-40fdc000<4>[  154.355164] s_stream: mode = 0<4>[  154.355177] ov3640_s_stream: do nothing(movie on)!!<4>[  154.382859] ov3640_s_mbus_fmt<4>[  154.385653] ov3640_enum_framesizes<4>[  154.385665] s_stream: mode = 1<4>[  154.385675] ov3640_s_stream: do nothing(movie on)!!                                  ||                  \/=============================================================static int ov3640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl){    default:        dev_err(&client->dev, "%s: no such ctrl\n", __func__);//打印第1条信息}static int ov3640_s_stream(struct v4l2_subdev *sd, int enable){    struct ov3640_state *state = to_state(sd);    int err = 0;    printk("s_stream: mode = %d\n", enable);//打印第3条信息    case STREAM_MODE_CAM_ON:    case STREAM_MODE_MOVIE_ON:        printk("%s: do nothing(movie on)!!\n", __func__);//打印第4条信息        break;    case STREAM_MODE_MOVIE_OFF:        printk("%s: do nothing(movie off)!!\n", __func__);        break;    default:        printk("%s: ERROR, Invalid stream mode %d\n",                    __func__, enable);        err = -EINVAL;        break;    }}static int ov3640_s_mbus_fmt(struct v4l2_subdev *sd,struct v4l2_mbus_framefmt *fmt){    printk("%s\n", __func__);//打印第5条信息    printk("%s\n", __func__);    printk("%s\n", __func__);}static int ov3640_enum_framesizes(struct v4l2_subdev *sd,struct v4l2_frmsizeenum *fsize){    printk("%s\n", __func__);//打印第6条信息}==============================================================================================================================\linux-3.0-fs4412_v7\drivers\media\video\samsung\fimc\Fimc_core.cstatic int fimc_probe(struct platform_device *pdev){    struct fimc_dev *fimc;      fimc = kzalloc(sizeof(struct fimc_dev), GFP_KERNEL);    fimc->id = pdev->id;    fimc->pdev = pdev;    fimc->pdata = pdev->dev.platform_data;    fimc->state = ST_IDLE;    /* At least one camera sensor is required to register capture node */    if (cap_input_index >= 0) {        ret = fimc_register_capture_device(fimc);//调用了Fimc_capture.c的register函数        if (ret)            goto err_m2m;    }}=========================================================\linux-3.0-fs4412_v7\drivers\media\video\samsung\fimc\Fimc_capture.cstatic int fimc_configure_subdev(struct fimc_control *ctrl){    struct i2c_adapter *i2c_adap;    struct i2c_board_info *i2c_info;    struct v4l2_subdev *sd;    unsigned short addr;    char *name;    int ret = 0;    i2c_adap = i2c_get_adapter(ctrl->cam->i2c_busnum);    if (!i2c_adap) {        fimc_err("subdev i2c_adapter missing-skip registration\n");        return -ENODEV;    }    i2c_info = ctrl->cam->info;    if (!i2c_info) {        fimc_err("%s: subdev i2c board info missing\n", __func__);        return -ENODEV;    }    name = i2c_info->type;    if (!name) {        fimc_err("subdev i2c driver name missing-skip registration\n");        return -ENODEV;    }    addr = i2c_info->addr;    if (!addr) {        fimc_err("subdev i2c address missing-skip registration\n");        return -ENODEV;    }    /*     * NOTE: first time subdev being registered,     * s_config is called and try to initialize subdev device     * but in this point, we are not giving MCLK and power to subdev     * so nothing happens but pass platform data through     */    sd = v4l2_i2c_new_subdev_board(&ctrl->v4l2_dev, i2c_adap,            i2c_info, &addr);    if (!sd) {        fimc_err("%s: v4l2 subdev board registering failed\n",                __func__);    }    /* Assign subdev to proper camera device pointer */    ctrl->cam->sd = sd;    if (!ctrl->cam->initialized) {        ret = fimc_init_camera(ctrl);        if (ret < 0) {            fimc_err("%s: fail to initialize subdev\n", __func__);            return ret;        }    }    return 0;}int fimc_s_input(struct file *file, void *fh, unsigned int i){    struct fimc_global *fimc = get_fimc_dev();    struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;    ret = fimc_configure_subdev(ctrl);    它首先从平台数据那里取得camera,如果不为空,就从上面的i2c_board_info里面取得i2c相应的信息,    比如适配器(adapter),i2c_info, name, addr等信息,这里就不详细讲解i2c驱动的框架层了,    这部分单独去学习难度并不大。总之获得所有需要的信息之后,    就会调用v4l2_i2c_new_subdev_board()这个函数,这函数是整个Camera驱动的关键。    简单来说,这个函数会做两件事情,第一件事情是根据传递过来的i2c设备的相关信息向I2C总线添加一个i2c设备,    然后向v4l2子系统注册一个v4l2子设备(sub-dev)。也就是说OV9650既是一个I2C设备,    也是一个V4L的子设备,这样就把i2c和v4l2联系起来了。}static int fimc_init_camera(struct fimc_control *ctrl){    struct fimc_global *fimc = get_fimc_dev();    struct s3c_platform_fimc *pdata;    struct s3c_platform_camera *cam;    int ret = 0, retry_cnt = 0;    /* "0" argument means preview init for s5k4ea */    ret = v4l2_subdev_call(cam->sd, core, init, 0);      //这里将会调用ov3640.c  的ov3640_init      ov3640_init做的工作其实就是初始化摄像头的寄存器    return ret;}=========================================================e:\fs4412\linux-3.0-fs4412_v7\arch\arm\mach-exynos\Mach-fs4412.c/* add by leesheen for ov3640 */#ifdef CONFIG_SOC_CAMERA_OV3640#include <media/ov3640_platform.h>#endif/* end add *//* add by leesheen for fs4412 ov3640 */#ifdef CONFIG_SOC_CAMERA_OV3640struct ov3640_platform_data ov3640_plat = {    .default_width = DEFAULT_PREVIEW_WIDTH,    .default_height = DEFAULT_PREVIEW_HEIGHT,    .pixelformat = DEFAULT_FMT,    .freq = 24000000,    .is_mipi = 0,    .streamoff_delay = 50,//  .dbg_level = CAMDBG_LEVEL_DEFAULT,};static struct i2c_board_info ov3640_i2c_info = {    I2C_BOARD_INFO("OV3640", 0x78>>1),    .platform_data = &ov3640_plat,};static struct s3c_platform_camera ov3640 = {            .id     = CAMERA_PAR_A,            .clk_name   = "sclk_cam0",            .i2c_busnum = 7,            .cam_power  = smdk4x12_cam1_reset,        .type       = CAM_TYPE_ITU,        .fmt        = ITU_601_YCBCR422_8BIT,        .order422   = CAM_ORDER422_8BIT_YCBYCR,        .info       = &ov3640_i2c_info,        .pixelformat    = DEFAULT_FMT,        .srclk_name = "xusbxti",        .clk_rate   = 24000000,        .line_length    = 1920,        .width      = DEFAULT_PREVIEW_WIDTH,        .height     = DEFAULT_PREVIEW_HEIGHT,        .window     = {            .left   = 0,            .top    = 0,            .width  = DEFAULT_PREVIEW_WIDTH,            .height = DEFAULT_PREVIEW_HEIGHT,        },        /* Polarity */        .inv_pclk   = 0,        .inv_vsync  = 1,        .inv_href   = 0,        .inv_hsync  = 0,        .reset_camera   = 1,        .initialized    = 0,        .layout_rotate = 0,//270 for shuping, //180, };#endif/* end add */
0 0
原创粉丝点击