camera_kernel之---media子系统(3)

在rk 9.0之前还没有实现这个子系统,为了解决多媒体设备的复杂性和流动性,我的理解是把多媒体各个模块树状链接,可以很方便的操作各个链接点的格式分辨率等。但是这样需要代码来支持,所以就有media子系统,虽然增加了大段代码,但是这样操作更加灵活。
由于media子系统在网上很多,这里只做简单讲述,后面自己看看代码。
图片描述camera的拓扑结构
Media子系统是一种pipeline形式
Rk从sensor到ddr设定了4个设备如下
sensor —> DPHY —> isp —> stream
其中每个设备都认为是一个entity,是一个节点。每个都包含一个或者多个pads,可以认为是各个分叉,link就是将各个分叉pad链接起来,也就是谁链接谁。谁是源端,谁是目的端。
根据上图:
sensor有ov5695和ov2659,它们只有一个pad,因为只能输出
DPHY 就是mipi dphy 接收sensor数据,输出输出到isp,所有有2个pads
Isp 因为isp除了要接收dphy进来的数据,还要接收input参数,输出统计信息,最后将数据输出到 mainpath和selfpath(这个不清楚是否rkisp独有),4个pads
Mp和sp 接收isp处理好的数据 一个pad。

下面看下media设备的注册,以及相关操作函数
Media设备结构体

struct media_device {
   
   
	/* dev->driver_data points to this struct. */
	struct device *dev;
	struct media_devnode devnode;	//设备节点

	char model[32];	//名字以及相关信息
	char serial[40];
	char bus_info[32];
	u32 hw_revision;
	u32 driver_version;

	u32 entity_id;
	struct list_head entities;	//entity 列表

	/* Protects the entities list */
	spinlock_t lock;
	/* Serializes graph operations. */
	struct mutex graph_mutex;

	int (*link_notify)(struct media_link *link, u32 flags,
			   unsigned int notification);//link改变后的callback函数
};

在rkisp1_plat_probe函数是初始化rkisp1_device结构体的,里面包含media_device结构,

static int rkisp1_plat_probe(struct platform_device *pdev)
{
   
   
……
strlcpy(isp_dev->media_dev.model, "rkisp1",
		sizeof(isp_dev->media_dev.model));
isp_dev->media_dev.dev = &pdev->dev;
isp_dev->media_dev.link_notify = rkisp1_pipeline_link_notify;
media_device_register(&isp_dev->media_dev);
rkisp1_register_platform_subdevs (isp_dev);

media_device_register这个是公共函数,

int __must_check __media_device_register(struct media_device *mdev,
					 struct module *owner)
{
   
   
	int ret;

	if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0))
		return -EINVAL;

	mdev->entity_id = 1;
	INIT_LIST_HEAD(&mdev->entities);
	spin_lock_init(&mdev->lock);
	mutex_init(&mdev->graph_mutex);

	/* Register the device node. */
	mdev->devnode.fops = &media_device_fops;//ioctl函数就在这里
	mdev->devnode.parent = mdev->dev;
	mdev->devnode.release = media_device_release;
	ret = media_devnode_register(&mdev-&g
完善 RK3588 驱动 #include <linux/module.h> #include <linux/platform_device.h> #include <media/v4l2-subdev.h> #include <media/media-entity.h> #define DRV_NAME "fpga_mipi" struct fpga_device { struct v4l2_subdev sd; struct media_pad pad; struct gpio_desc *reset_gpio; struct gpio_desc *power_en_gpio; }; static struct fpga_device *fpga_dev; // V4L2子设备操作函数 static const struct v4l2_subdev_ops fpga_subdev_ops = { }; // 媒体实体初始化 static int fpga_init_media_entity(struct fpga_device *dev) { dev->pad.flags = MEDIA_PAD_FL_SOURCE; dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; return media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); } // 格式配置回调 static int fpga_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_format *fmt) { // 设置FPGA输出格式(需与硬件匹配) fmt->format.width = 1920; fmt->format.height = 1080; fmt->format.code = MEDIA_BUS_FMT_UYVY8_2X8; // YUV422格式 return 0; } // 探测函数 static int fpga_probe(struct platform_device *pdev) { struct fpga_device *dev; int ret; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; // 初始化V4L2子设备 v4l2_subdev_init(&dev->sd, &fpga_subdev_ops); dev->sd.owner = THIS_MODULE; snprintf(dev->sd.name, sizeof(dev->sd.name), DRV_NAME); // 配置GPIO dev->reset_gpio = devm_gpiod_get(&pdev->dev, "reset", GPIOD_OUT_LOW); dev->power_en_gpio = devm_gpiod_get(&pdev->dev, "power-en", GPIOD_OUT_HIGH); // 初始化媒体实体 ret = fpga_init_media_entity(dev); if (ret) return ret; // 注册子设备 ret = v4l2_async_register_subdev(&dev->sd); if (ret) { media_entity_cleanup(&dev->sd.entity); return ret; } platform_set_drvdata(pdev, dev); fpga_dev = dev; return 0; } // 移除函数 static int fpga_remove(struct platform_device *pdev) { struct fpga_device *dev = platform_get_drvdata(pdev); v4l2_async_unregister_sub
最新发布
03-14
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值