soc_camera.c
1455 static struct platform_driver __refdata soc_camera_pdrv = { 1456 .remove = __devexit_p(soc_camera_pdrv_remove), 1457 .driver = { 1458 .name = "soc-camera-pdrv", 1459 .owner = THIS_MODULE, 1460 }, 1461 }; 1462 1463 static int __init soc_camera_init(void) 1464 { 1465 int ret = bus_register(&soc_camera_bus_type); 1466 if (ret) 1467 return ret; 1468 ret = driver_register(&ic_drv); 1469 if (ret) 1470 goto edrvr; 1471 1472 ret = platform_driver_probe(&soc_camera_pdrv, soc_camera_pdrv_probe); 1473 if (ret) 1474 goto epdr; 1475 1476 return 0; 1477 1478 epdr: 1479 driver_unregister(&ic_drv); 1480 edrvr: 1481 bus_unregister(&soc_camera_bus_type); 1482 return ret; 1483 }1472 platform_driver_probe和platform_driver_register的区别:前者功能上和platform_driver_register是一样的,但是在内核启动完成后,这个函数就不能再执行了,这样可以释放函数soc_camera_pdrv_probe所占的空间。
soc_camera_pdrv_probe会probe系统内名称为"soc-camera-pdrv"的平台设备,系统内有几个这样的平台设备,那么就会创建几个soc_camera_device。这些平台设备可如下定义:
struct platform_device your_mach_cameras[] = { { .name = "soc-camera-pdrv", .id = 0, .dev = { .platform_data = adv7180_link, }, }, { .name = "soc-camera-pdrv", .id = 1, .dev = { .platform_data = tw9912_link, }, } };
注意,这里假定系统的camera处理模块,接了两个camera sensor, adv7180_link和tw9912_link
static struct i2c_board_info decoder_i2c_adv7180 = { I2C_BOARD_INFO("adv7180", (0x42 >> 1)), }; struct soc_camera_link adv7180_link = { .bus_id = 0, .board_info = &decoder_i2c_adv7180, .i2c_adapter_id = 0, };soc_camera_link主要用来定义i2c地址,如果sensor不是通过i2c连接到host上,那么要定义add_device和del_device函数
1465 注册一条新的总线soc-camera,这样在scan_add_host中调用device_register时,就会把这个设备挂到这个总线上。
1135 struct bus_type soc_camera_bus_type = { 1136 .name = "soc-camera", 1137 .probe = soc_camera_probe, 1138 .remove = soc_camera_remove, 1139 .suspend = soc_camera_suspend, 1140 .resume = soc_camera_resume, 1141 }; 1142 EXPORT_SYMBOL_GPL(soc_camera_bus_type);
当一个soc-camera-device设备通过device_register注册设备时,就会调用soc_camera_probe函数
1402 static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) 1403 { 1404 struct soc_camera_link *icl = pdev->dev.platform_data; 1405 struct soc_camera_device *icd; 1406 int ret; 1407 1408 if (!icl) 1409 return -EINVAL; 1410 1411 icd = kzalloc(sizeof(*icd), GFP_KERNEL); 1412 if (!icd) 1413 return -ENOMEM; 1414 1415 icd->iface = icl->bus_id; 1416 icd->pdev = &pdev->dev; 1417 platform_set_drvdata(pdev, icd); 1418 1419 ret = soc_camera_device_register(icd); 1420 if (ret < 0) 1421 goto escdevreg; 1422 1423 soc_camera_device_init(&icd->dev, icl); 1424 1425 icd->user_width = DEFAULT_WIDTH; 1426 icd->user_height = DEFAULT_HEIGHT; 1427 1428 return 0; 1429 1430 escdevreg: 1431 kfree(icd); 1432 1433 return ret; 1434 }
查找匹配名为soc-camera-pdrv的platform device时,调用该函数。
1419 调用soc_camera_device_register,把这个soc_camera_device加到全局camera device链表@devices上,并且为它分配设备号,做一些必要的初始化
1423 设置soc_came_device对应device的bus为soc_camera_bus_type,这样当我们注册设备时,就会调用soc_camera_probe
1374 /* 1375 * Called from soc_camera_probe() above (with .video_lock held???) 1376 */ 1377 static int soc_camera_video_start(struct soc_camera_device *icd) 1378 { 1379 struct device_type *type = icd->vdev->dev.type; 1380 int ret; 1381 1382 if (!icd->dev.parent) 1383 return -ENODEV; 1384 1385 if (!icd->ops || 1386 !icd->ops->query_bus_param || 1387 !icd->ops->set_bus_param) 1388 return -EINVAL; 1389 1390 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1); 1391 if (ret < 0) { 1392 dev_err(&icd->dev, "video_register_device failed: %d\n", ret); 1393 return ret; 1394 } 1395 1396 /* Restore device type, possibly set by the subdevice driver */ 1397 icd->vdev->dev.type = type; 1398 1399 return 0; 1400 }
在当前的上下文,soc_camera_video_start的调用路径如下
soc_camera_host_register ==> scan_add_host ==> device_register ==> bus_probe_device ==> soc_camera_bus_type.probe ==> soc_camera_video_start
1390 我们可以看出,系统为每一个soc-camera-device创建了一个video device设备节点
1352 static int video_dev_create(struct soc_camera_device *icd) 1353 { 1354 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1355 struct video_device *vdev = video_device_alloc(); 1356 1357 if (!vdev) 1358 return -ENOMEM; 1359 1360 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); 1361 1362 vdev->parent = &icd->dev; 1363 vdev->current_norm = V4L2_STD_UNKNOWN; 1364 vdev->fops = &soc_camera_fops; 1365 vdev->ioctl_ops = &soc_camera_ioctl_ops; 1366 vdev->release = video_device_release; 1367 vdev->tvnorms = V4L2_STD_UNKNOWN; 1368 1369 icd->vdev = vdev; 1370 1371 return 0; 1372 }
当前的上下文,video_dev_create的调用路径如下
soc_camera_host_register ==> scan_add_host ==> device_register ==> bus_probe_device ==> soc_camera_bus_type.probe ==> soc_camera_video_start
这里面设置了video_device的两个非常重要的参数:soc_camera_ioctl_ops和soc_camera_fops,当user space打开video device后,所有可执行的操作,都是通过这两个入口进行的,下面是他们的定义。
549 static struct v4l2_file_operations soc_camera_fops = { 550 .owner = THIS_MODULE, 551 .open = soc_camera_open, 552 .release = soc_camera_close, 553 .unlocked_ioctl = video_ioctl2, 554 .read = soc_camera_read, 555 .mmap = soc_camera_mmap, 556 .poll = soc_camera_poll, 557 };
1321 static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { 1322 .vidioc_querycap = soc_camera_querycap, 1323 .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap, 1324 .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap, 1325 .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap, 1326 .vidioc_enum_input = soc_camera_enum_input, 1327 .vidioc_g_input = soc_camera_g_input, 1328 .vidioc_s_input = soc_camera_s_input, 1329 .vidioc_s_std = soc_camera_s_std, 1330 .vidioc_reqbufs = soc_camera_reqbufs, 1331 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap, 1332 .vidioc_querybuf = soc_camera_querybuf, 1333 .vidioc_qbuf = soc_camera_qbuf, 1334 .vidioc_dqbuf = soc_camera_dqbuf, 1335 .vidioc_streamon = soc_camera_streamon, 1336 .vidioc_streamoff = soc_camera_streamoff, 1337 .vidioc_queryctrl = soc_camera_queryctrl, 1338 .vidioc_g_ctrl = soc_camera_g_ctrl, 1339 .vidioc_s_ctrl = soc_camera_s_ctrl, 1340 .vidioc_cropcap = soc_camera_cropcap, 1341 .vidioc_g_crop = soc_camera_g_crop, 1342 .vidioc_s_crop = soc_camera_s_crop, 1343 .vidioc_g_parm = soc_camera_g_parm, 1344 .vidioc_s_parm = soc_camera_s_parm, 1345 .vidioc_g_chip_ident = soc_camera_g_chip_ident, 1346 #ifdef CONFIG_VIDEO_ADV_DEBUG 1347 .vidioc_g_register = soc_camera_g_register, 1348 .vidioc_s_register = soc_camera_s_register, 1349 #endif 1350 };
soc_camera_ops 不支持read操作,因此如果使用了soc camera子系统,那么应用层就无法再使用read操作获取camera 数据,而只能选择使用mmap方式。不支持read操作没什么关系,大部分camera操作都是使用mmap方式进行的。samsung的s5pv210不支持read操作,而freescale mxc系列则支持read操作获取camera数据。
soc_camera_ioctl_ops也仅仅支持了v4l2_ioctl_ops的一个子集,这就意味着应用程序的作者需要考虑ioctl可能没有被支持。
1281 /* Image capture device */ 1282 static int soc_camera_device_register(struct soc_camera_device *icd) 1283 { 1284 struct soc_camera_device *ix; 1285 int num = -1, i; 1286 1287 for (i = 0; i < 256 && num < 0; i++) { 1288 num = i; 1289 /* Check if this index is available on this interface */ 1290 list_for_each_entry(ix, &devices, list) { 1291 if (ix->iface == icd->iface && ix->devnum == i) { 1292 num = -1; 1293 break; 1294 } 1295 } 1296 } 1297 1298 if (num < 0) 1299 /* 1300 * ok, we have 256 cameras on this host... 1301 * man, stay reasonable... 1302 */ 1303 return -ENOMEM; 1304 1305 icd->devnum = num; 1306 icd->use_count = 0; 1307 icd->host_priv = NULL; 1308 mutex_init(&icd->video_lock); 1309 1310 list_add_tail(&icd->list, &devices); 1311 1312 return 0; 1313 }
把给定的@icd加到全局soc camera device列表中
1290~1294 @devices是一个全局soc camera device列表,这段代码相当拗口,注意1293行是break 1290这个循环
1194 int soc_camera_host_register(struct soc_camera_host *ici) 1195 { 1196 struct soc_camera_host *ix; 1197 int ret; 1198 1199 if (!ici || !ici->ops || 1200 !ici->ops->try_fmt || 1201 !ici->ops->set_fmt || 1202 !ici->ops->set_bus_param || 1203 !ici->ops->querycap || 1204 !ici->ops->init_videobuf || 1205 !ici->ops->reqbufs || 1206 !ici->ops->add || 1207 !ici->ops->remove || 1208 !ici->ops->poll || 1209 !ici->v4l2_dev.dev) 1210 return -EINVAL; 1211 1212 if (!ici->ops->set_crop) 1213 ici->ops->set_crop = default_s_crop; 1214 if (!ici->ops->get_crop) 1215 ici->ops->get_crop = default_g_crop; 1216 if (!ici->ops->cropcap) 1217 ici->ops->cropcap = default_cropcap; 1218 if (!ici->ops->set_parm) 1219 ici->ops->set_parm = default_s_parm; 1220 if (!ici->ops->get_parm) 1221 ici->ops->get_parm = default_g_parm; 1222 1223 mutex_lock(&list_lock); 1224 list_for_each_entry(ix, &hosts, list) { 1225 if (ix->nr == ici->nr) { 1226 ret = -EBUSY; 1227 goto edevreg; 1228 } 1229 } 1230 1231 ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev); 1232 if (ret < 0) 1233 goto edevreg; 1234 1235 list_add_tail(&ici->list, &hosts); 1236 mutex_unlock(&list_lock); 1237 1238 scan_add_host(ici); 1239 1240 return 0; 1241 1242 edevreg: 1243 mutex_unlock(&list_lock); 1244 return ret; 1245 } 1246 EXPORT_SYMBOL(soc_camera_host_register);
1231 每个camera host对应一个v4l2 device(注意不是video device),host上device对应的才是video device
1235 @host是一个全局camera host 链表
1238 scan_add_host 关联系统内属于这个host的video device
1135 struct bus_type soc_camera_bus_type = { 1136 .name = "soc-camera", 1137 .probe = soc_camera_probe, 1138 .remove = soc_camera_remove, 1139 .suspend = soc_camera_suspend, 1140 .resume = soc_camera_resume, 1141 }; 1142 EXPORT_SYMBOL_GPL(soc_camera_bus_type);
soc camera总线代码,当调用device_register注册一个新设备时,会调用probe函数
947 static int soc_camera_probe(struct device *dev) 948 { 949 struct soc_camera_device *icd = to_soc_camera_dev(dev); 950 struct soc_camera_host *ici = to_soc_camera_host(dev->parent); 951 struct soc_camera_link *icl = to_soc_camera_link(icd); 952 struct device *control = NULL; 953 struct v4l2_subdev *sd; 954 struct v4l2_mbus_framefmt mf; 955 int ret; 956 957 dev_info(dev, "Probing %s\n", dev_name(dev)); 958 959 ret = regulator_bulk_get(icd->pdev, icl->num_regulators, 960 icl->regulators); 961 if (ret < 0) 962 goto ereg; 963 964 ret = soc_camera_power_set(icd, icl, 1); 965 if (ret < 0) 966 goto epower; 967 968 /* The camera could have been already on, try to reset */ 969 if (icl->reset) 970 icl->reset(icd->pdev); 971 972 ret = ici->ops->add(icd); 973 if (ret < 0) 974 goto eadd; 975 976 /* Must have icd->vdev before registering the device */ 977 ret = video_dev_create(icd); 978 if (ret < 0) 979 goto evdc; 980 981 /* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */ 982 if (icl->board_info) { 983 ret = soc_camera_init_i2c(icd, icl); 984 if (ret < 0) { 985 goto eadddev; 986 } 987 } else if (!icl->add_device || !icl->del_device) { 988 ret = -EINVAL; 989 goto eadddev; 990 } else { 991 if (icl->module_name) 992 ret = request_module(icl->module_name); 993 994 ret = icl->add_device(icl, &icd->dev); 995 if (ret < 0) 996 goto eadddev; 997 998 /* 999 * FIXME: this is racy, have to use driver-binding notification, 1000 * when it is available 1001 */ 1002 control = to_soc_camera_control(icd); 1003 if (!control || !control->driver || !dev_get_drvdata(control) || 1004 !try_module_get(control->driver->owner)) { 1005 icl->del_device(icl); 1006 goto enodrv; 1007 } 1008 } 1009 1010 /* At this point client .probe() should have run already */ 1011 ret = soc_camera_init_user_formats(icd); 1012 if (ret < 0) 1013 goto eiufmt; 1014 1015 icd->field = V4L2_FIELD_ANY; 1016 1017 icd->vdev->lock = &icd->video_lock; 1018 1019 /* 1020 * ..._video_start() will create a device node, video_register_device() 1021 * itself is protected against concurrent open() calls, but we also have 1022 * to protect our data. 1023 */ 1024 mutex_lock(&icd->video_lock); 1025 1026 ret = soc_camera_video_start(icd); 1027 if (ret < 0) 1028 goto evidstart; 1029 1030 /* Try to improve our guess of a reasonable window format */ 1031 sd = soc_camera_to_subdev(icd); 1032 if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { 1033 icd->user_width = mf.width; 1034 icd->user_height = mf.height; 1035 icd->colorspace = mf.colorspace; 1036 icd->field = mf.field; 1037 } 1038 1039 /* Do we have to sysfs_remove_link() before device_unregister()? */ 1040 if (sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj, 1041 "control")) 1042 dev_warn(&icd->dev, "Failed creating the control symlink\n"); 1043 1044 ici->ops->remove(icd); 1045 1046 soc_camera_power_set(icd, icl, 0); 1047 1048 mutex_unlock(&icd->video_lock); 1049 1050 return 0; 1051 1052 evidstart: 1053 mutex_unlock(&icd->video_lock); 1054 soc_camera_free_user_formats(icd); 1055 eiufmt: 1056 if (icl->board_info) { 1057 soc_camera_free_i2c(icd); 1058 } else { 1059 icl->del_device(icl); 1060 module_put(control->driver->owner); 1061 } 1062 enodrv: 1063 eadddev: 1064 video_device_release(icd->vdev); 1065 evdc: 1066 ici->ops->remove(icd); 1067 eadd: 1068 soc_camera_power_set(icd, icl, 0); 1069 epower: 1070 regulator_bulk_free(icl->num_regulators, icl->regulators); 1071 ereg: 1072 return ret; 1073 }
在host-driver probe函数中调用,soc_camera_host_register ==> scan_add_host ==> device_register ==> bus_probe_device ==> soc_camera_probe
972 调用camera host驱动的add函数,比如pxa平台的pxa_camera_add_device
977 在调用video_device_register之前,要先创建video_device
982~1008 如果是i2c camera,那么调用soc_camera_init_i2c来初始华i2c,否则就调用add_device增加设备。soc_camera_init_i2c会调用到芯片驱动i2c_driver.probe,对于我们的项目,则是adv7180_probe
1010~1013 初始化client format,调用soc_camera_init_user_format之前,已经执行了芯片的probe函数,已经可以对芯片进一步的操作。
1026 调用soc_camera_video_start注册一个video device
1031 每一个soc camera device都一一对应一个v4l2 subdev
1044 ~ 1046 已经获取了soc camera device必要的信息后,调用remove_device关闭soc camera device,然后调用soc_camera_power_set关闭soc camera device的电源。
869 /* So far this function cannot fail */ 870 static void scan_add_host(struct soc_camera_host *ici) 871 { 872 struct soc_camera_device *icd; 873 874 mutex_lock(&list_lock); 875 876 list_for_each_entry(icd, &devices, list) { 877 if (icd->iface == ici->nr) { 878 int ret; 879 icd->dev.parent = ici->v4l2_dev.dev; 880 dev_set_name(&icd->dev, "%u-%u", icd->iface, 881 icd->devnum); 882 ret = device_register(&icd->dev); 883 if (ret < 0) { 884 icd->dev.parent = NULL; 885 dev_err(&icd->dev, 886 "Cannot register device: %d\n", ret); 887 } 888 } 889 } 890 891 mutex_unlock(&list_lock); 892 }
这个函数只被soc_camera_host_register调用。扫描系统所有的camera device,把属于这个camera host(参数@ici指定)的所有camera device注册到系统中。
876 系统所有的camera device,在没有被camera host注册前,这些camera device仅保存在@devices链表中
877 比较camera device的host number是否等于这个camera host
882 device_register 注册一个设备到系统中,这个函数会调用bus_probe_device,而bus_probe_device则会调用soc_camera_bus_type.probe,也就是soc_camera_probe。这样soc_camera_host_register就会注册所有属于这个host的camera device到系统中,并且创建了相应的设备节点/dev/videoX,整个设备的注册过程全部结束了,从现在开始,可以在设备节点/dev/videoX上调用open read write ioctl以及poll。
178 static int soc_camera_s_input(struct file *file, void *priv, unsigned int i) 179 { 180 int ret; 181 struct soc_camera_device *icd = file->private_data; 182 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 183 184 /* call s_routing to select the input of camera sensor */ 185 ret = v4l2_subdev_call(sd, video, s_routing, i, 0, 0); 186 187 return ret; 188 }185 soc_camera驱动并没有实现这句话,而是直接 return 0,这就导致当前的soc camera子系统不支持S_INPUT接口。
384 static int soc_camera_open(struct file *file) 385 { 386 struct video_device *vdev = video_devdata(file); 387 struct soc_camera_device *icd = container_of(vdev->parent, 388 struct soc_camera_device, 389 dev); 390 struct soc_camera_link *icl = to_soc_camera_link(icd); 391 struct soc_camera_host *ici; 392 int ret; 393 394 if (!icd->ops) 395 /* No device driver attached */ 396 return -ENODEV; 397 398 ici = to_soc_camera_host(icd->dev.parent); 399 400 if (!try_module_get(ici->ops->owner)) { 401 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 402 return -EINVAL; 403 } 404 405 icd->use_count++; 406 407 /* Now we really have to activate the camera */ 408 if (icd->use_count == 1) { 409 /* Restore parameters before the last close() per V4L2 API */ 410 struct v4l2_format f = { 411 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 412 .fmt.pix = { 413 .width = icd->user_width, 414 .height = icd->user_height, 415 .field = icd->field, 416 .colorspace = icd->colorspace, 417 .pixelformat = 418 icd->current_fmt->host_fmt->fourcc, 419 }, 420 }; 421 422 ret = soc_camera_power_set(icd, icl, 1); 423 if (ret < 0) 424 goto epower; 425 426 /* The camera could have been already on, try to reset */ 427 if (icl->reset) 428 icl->reset(icd->pdev); 429 430 ret = ici->ops->add(icd); 431 if (ret < 0) { 432 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); 433 goto eiciadd; 434 } 435 436 pm_runtime_enable(&icd->vdev->dev); 437 ret = pm_runtime_resume(&icd->vdev->dev); 438 if (ret < 0 && ret != -ENOSYS) 439 goto eresume; 440 441 /* 442 * Try to configure with default parameters. Notice: this is the 443 * very first open, so, we cannot race against other calls, 444 * apart from someone else calling open() simultaneously, but 445 * .video_lock is protecting us against it. 446 */ 447 ret = soc_camera_set_fmt(icd, &f); 448 if (ret < 0) 449 goto esfmt; 450 451 ici->ops->init_videobuf(&icd->vb_vidq, icd); 452 } 453 454 file->private_data = icd; 455 dev_dbg(&icd->dev, "camera device open\n"); 456 457 return 0; 458 459 /* 460 * First four errors are entered with the .video_lock held 461 * and use_count == 1 462 */ 463 esfmt: 464 pm_runtime_disable(&icd->vdev->dev); 465 eresume: 466 ici->ops->remove(icd); 467 eiciadd: 468 soc_camera_power_set(icd, icl, 0); 469 epower: 470 icd->use_count--; 471 module_put(ici->ops->owner); 472 473 return ret; 474 }
当应用通过open系统调用,打开设备节点/dev/videoX时,会调用soc_camera_open
430 ici->ops->add 不仅要执行host内部的初始化,还会调用camera sensor(参数icd指定)的init
447 配置camera sensor缺省的格式参数,从我个人理解,一切合理的fmt都应该在调用S_INPUT之后进行设置。当然,这需要应用程序编程时先调用S_INPUT再进行S_FMT。
405~408 仅在第一次打开时,才对camera host和camera sensor做初始化操作,否则,仅仅增加引用计数。