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
- fs4412开发板学习笔记(九)
- fs4412开发板学习笔记(一)
- fs4412开发板学习笔记(二)
- fs4412开发板学习笔记(三)
- fs4412开发板学习笔记(四)
- fs4412开发板学习笔记(五)
- fs4412开发板学习笔记(六)
- fs4412开发板学习笔记(七)
- fs4412开发板学习笔记(八)
- fs4412开发板学习笔记(十)
- fs4412开发板学习笔记(十一)
- fs4412开发板学习笔记(十二)
- fs4412开发板学习笔记(十三)
- fs4412开发板学习笔记(十四)
- fs4412开发板学习笔记(十五)
- fs4412开发板学习笔记(十六)
- fs4412开发板学习笔记(十七)
- fs4412开发板学习笔记(十八)
- [Leetcode]Gas Station
- 重新学习COCOs2D-X版本2.2.3开始---第一篇引擎的游戏入口
- POJ 1089 解题报告
- printf( )的格式字符
- NSDate NSString NSArray NSDictionary 数据类型相互转换
- fs4412开发板学习笔记(九)
- container-with-most-water
- 一些实用PHP代码片段
- Two Sum
- ZigZag Conversion
- 整数的拆分
- springMVC配置一个通配的url请求,替代@RequestMapping中指定的方式
- fs4412开发板学习笔记(十)
- Java异常捕获之try...catch...finally语句