/sys/kernel/debug/camera_memmgr
通过media找到video,video分别代表CRM camsync
CRM:CAM_VNODE_DEVICE_TYPE
cam_sync:CAM_SYNC_DEVICE_TYPE
hal的写法
BOOL CSLHwEnumerateAndAddCSLHwDevice(
CSLHwInternalHwEnumeration deviceType,
UINT32 deviceClass)
{
struct media_device_info mediadevInfo;
CHAR mediaName[CSLHwMaxDevName];
INT32 numMediaDevices = 0;
INT32 mediaFd = 0;
CamxResult result = 0;
BOOL returnCode = FALSE;
INT32 numEntities = 0;
INT deviceFd = -1;
while (1)
{
CamX::OsUtils::SNPrintF(mediaName, sizeof(mediaName), "/dev/media%d", numMediaDevices++);
mediaFd = open(mediaName, O_RDWR | O_NONBLOCK);
if (mediaFd < 0)
{
CAMX_LOG_VERBOSE(CamxLogGroupCSL, "No more media devices found on %s", mediaName);
break;
}
result = CSLHwInternalFDIoctl(mediaFd, MEDIA_IOC_DEVICE_INFO, &mediadevInfo);
if (CamxResultSuccess != result)
{
CAMX_LOG_VERBOSE(CamxLogGroupCSL, "media device get device info failed");
close(mediaFd);
continue;
}
CAMX_LOG_ERROR(CamxLogGroupCSL, "media devices found on %s and name = %s", mediaName, mediadevInfo.model);
if (0 != (strncmp(mediadevInfo.model, CAM_REQ_MGR_VNODE_NAME, sizeof(mediadevInfo.model))))
{
close(mediaFd);
continue;
}
numEntities = 1;
while (1)
{
struct media_entity_desc entity = {};
CHAR deviceName[CSLHwMaxDevName] = {0};
CHAR subdeviceName[CSLHwMaxDevName] = {0};
entity.id = numEntities;
result = CSLHwInternalFDIoctl(mediaFd, MEDIA_IOC_ENUM_ENTITIES, &entity);
if (result != CamxResultSuccess)
{
CAMX_LOG_VERBOSE(CamxLogGroupCSL, "media device enumerate entities failed for %s (id:%d)",
entity.name, entity.id);
break;
}
numEntities = entity.id | MEDIA_ENT_ID_FLAG_NEXT;
CAMX_LOG_ERROR(CamxLogGroupCSL, "Found entity name:%s, type:%d, id:%d, device_class:%d deviceType:%d",
entity.name, entity.type, entity.id, deviceClass, deviceType);
if (CSLInternalHwVideodevice == deviceType)
{
if (entity.type == deviceClass)
{
CamX::OsUtils::SNPrintF(deviceName, sizeof(deviceName), "/dev/%s", entity.name);
returnCode = CSLHwAddKMDPrivateDeviceToInstance(deviceName, entity.type);
close(mediaFd);
return returnCode;
}
}
else if (CSLInternalHwVideoSubdevice == deviceType)
{
if (entity.type == deviceClass)
{
CamX::OsUtils::SNPrintF(subdeviceName, sizeof(subdeviceName), "/dev/%s", entity.name);
returnCode = CSLHwAddKMDPrivateDeviceToInstance(subdeviceName, entity.type);
close(mediaFd);
return returnCode;
}
}
else if (CSLInternalHwVideoSubdeviceAll == deviceType)
{
CSLHwInternalDeviceType type;
INT32 deviceIndex = -1;
CSLHwKmdGroupidToCslDevicetype(entity.type, &type);
if ((FALSE == CSLHwIsKmdGroupidCslInternalDevicetype(entity.type)) &&
(CamxResultSuccess == CSLHwKmdGroupidToCslDevicetype(entity.type, &type)))
{
CamX::OsUtils::SNPrintF(subdeviceName, sizeof(subdeviceName), "/dev/%s", entity.name);
if (CAM_SENSOR_DEVICE_TYPE == entity.type)
{
CSLHwAddSensorSlotDeviceToInstance(subdeviceName, entity.type, &deviceIndex);
}
else
{
// Non-sensor devices will be opened and then added to the KMD device list
// Therefore, fd is not known at this point of time and should be -1
CSLHwAddKMDDeviceToInstance(subdeviceName, entity.type, &deviceIndex, deviceFd);
}
returnCode = TRUE;
}
}
else
{
CAMX_LOG_ERROR(CamxLogGroupCSL, "Invalid device type %d", deviceType);
break;
}
}
close(mediaFd);
return returnCode;
}
return returnCode;
}
kernel的写法
static int cam_media_device_setup(struct device *dev)
{
int rc;
g_dev.v4l2_dev->mdev = kzalloc(sizeof(*g_dev.v4l2_dev->mdev),
GFP_KERNEL);
if (!g_dev.v4l2_dev->mdev) {
rc = -ENOMEM;
goto mdev_fail;
}
media_device_init(g_dev.v4l2_dev->mdev);
g_dev.v4l2_dev->mdev->dev = dev;
strlcpy(g_dev.v4l2_dev->mdev->model, CAM_REQ_MGR_VNODE_NAME,
sizeof(g_dev.v4l2_dev->mdev->model));
rc = media_device_register(g_dev.v4l2_dev->mdev);
if (rc)
goto media_fail;
return rc;
media_fail:
kfree(g_dev.v4l2_dev->mdev);
g_dev.v4l2_dev->mdev = NULL;
mdev_fail:
return rc;
}
static int cam_video_device_setup(void)
{
int rc;
g_dev.video = video_device_alloc();
if (!g_dev.video) {
rc = -ENOMEM;
goto video_fail;
}
g_dev.video->v4l2_dev = g_dev.v4l2_dev;
strlcpy(g_dev.video->name, "cam-req-mgr",
sizeof(g_dev.video->name));
g_dev.video->release = video_device_release;
g_dev.video->fops = &g_cam_fops;
g_dev.video->ioctl_ops = &g_cam_ioctl_ops;
g_dev.video->minor = -1;
g_dev.video->vfl_type = VFL_TYPE_GRABBER;
rc = video_register_device(g_dev.video, VFL_TYPE_GRABBER, -1);
if (rc)
goto v4l2_fail;
rc = media_entity_pads_init(&g_dev.video->entity, 0, NULL);
if (rc)
goto entity_fail;
g_dev.video->entity.function = CAM_VNODE_DEVICE_TYPE;
g_dev.video->entity.name = video_device_node_name(g_dev.video);
return rc;
entity_fail:
video_unregister_device(g_dev.video);
v4l2_fail:
video_device_release(g_dev.video);
g_dev.video = NULL;
video_fail:
return rc;
}