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_ops和ov5640_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函数中的内容}
*/
};