media节点

卓胜
2023-12-01

/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;
}

 类似资料: