ov5640设备树修改

i2ctool的一些使用

文件:drivers/media/platform/mxc/capture/mx6s_capture.c是芯片CSI控制器驱动

drivers/media/platform/mxc/capture/ov5640_v2.c是摄像头配置驱动

模块安装

linux-kernel-6.12.y的ov5640驱动默认编译成的是模块,需要进行安装,当然也可直接单独运行模块或者直接编译进内核,这里使用较为正规的方式。使用如下命令会将模块自动安装到INSTALL_MOD_PATH的bin目录下,linux也会自动加载,无需手动加载。

#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_prepare
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- M=drivers/media/platform/mxc/capture modules    # 编译模块
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_install INSTALL_MOD_PATH=/your/rootfs/path    # 安装模块

最小改动的移植,使用自带驱动的YUYV格式(不完美)

驱动部分,只需要将旧的正点原子驱动中的屏幕配置加入到新的驱动中即可,也可直加入自己屏幕对应的配置部分。一般需要在ov5640_mode添加内容,相应的添加reg_value结构体对应的数据,然后还有ov5640_mode_info_data结构体内添加对应内容。而应用层部分,需要做较大的修改,需要修改成YUYV格式的配置,并且需要进行YUYV->RGB565的转换。显示的不完美,屏幕会被分成两部分,并且左右部分进行了互换。改动部分已在注释中标出。

详细代码:https://github.com/ydteng/ov5640-driver/tree/main/YUYV

尽量跟正点原子官方原版一样的

这个改动较多,最需要注意的是ov5640_subdev_video_opsov5640_subdev_pad_ops的区别,别的其实还好移植。这两个的区别主要是新版本将ov5640_subdev_video_ops的一些接口放到了ov5640_subdev_pad_ops里面,并且删除了try_mbus_fmt,合并到了set_fmt使用fmt->which进行判断,具体如下:

查看代码

static struct v4l2_subdev_video_ops ov5640_subdev_video_ops = {
	.g_parm = ov5640_g_parm,
	.s_parm = ov5640_s_parm,
	.g_std = ov5640_g_std,	/* 也算是一个过时接口,写的很简单 */

	/*
	旧版本驱动这里有下面这些
	.s_mbus_fmt	= ov5640_s_fmt,
	.g_mbus_fmt	= ov5640_g_fmt,
	.try_mbus_fmt	= ov5640_try_fmt,
	.enum_mbus_fmt	= ov5640_enum_fmt,
	*/
};

static const struct v4l2_subdev_pad_ops ov5640_subdev_pad_ops = {
	.enum_frame_size       = ov5640_enum_framesizes,
	.enum_frame_interval   = ov5640_enum_frameintervals,
	/* 新版本的从v4l2_subdev_video_ops移动到了v4l2_subdev_pad_ops,变成了下面这些接口 */
	.enum_mbus_code        = ov5640_enum_code,	/* 对应旧版本enum_mbus_fmt */
	.set_fmt               = ov5640_set_fmt,	/* 对应旧版本s_mbus_fmt*/
	.get_fmt               = ov5640_get_fmt,	/* 对应旧版本g_mbus_fmt */
	/* 
    删除了try_mbus_fmt,合并到了set_fmt使用fmt->which == V4L2_SUBDEV_FORMAT_TRY进行判断,
    if (format->which == V4L2_SUBDEV_FORMAT_TRY){这里可以写旧版本的ov5640_try_fmt函数中的内容}
    */
};