当前位置: 首页 > news >正文

gc2053驱动学习笔记

1 gc2053 数据手册

2 gc2053结构体详解

struct gc2053 {struct i2c_client   *client; //指向 I2C 客户端设备的指针struct clk      *xvclk; //指向时钟设备的指针struct gpio_desc    *reset_gpio;//指向复位 GPIO 设备描述符的指针。struct gpio_desc    *pwdn_gpio;//指向电源关闭 GPIO 设备描述符的指针struct gpio_desc    *power_gpio;//指向电源 GPIO 设备描述符的指针struct regulator_bulk_data supplies[GC2053_NUM_SUPPLIES];//一个包含 GC2053 电源调节器信息的数组,包含多个电压域(如 AVDD、DOVDD、DVDD 等)struct pinctrl      	*pinctrl;//指向 Pinctrl 设备的指针struct pinctrl_state    *pins_default;//指向默认 Pinctrl 状态的指针struct pinctrl_state    *pins_sleep;//指向睡眠 Pinctrl 状态的指针struct v4l2_subdev  subdev;//指向 V4L2 子设备的指针struct media_pad    pad;//媒体管道中的“焊盘”,用于连接其他媒体组件(如 ISP、DMA)struct v4l2_ctrl_handler ctrl_handler;//控件处理器,用于注册和管理 V4L2 控件struct v4l2_ctrl    *exposure;//指向曝光 V4L2 控件的指针struct v4l2_ctrl    *anal_gain;//指向模拟增益 V4L2 控件的指针struct v4l2_ctrl    *hblank;//指向水平消隐 V4L2 控件的指针struct v4l2_ctrl    *vblank;//指向垂直消隐 V4L2 控件的指针struct v4l2_ctrl    *h_flip;//指向水平翻转 V4L2 控件的指针struct v4l2_ctrl    *v_flip;//指向垂直翻转 V4L2 控件的指针struct mutex        mutex;//一个互斥锁bool            streaming;//:一个布尔值,指示摄像头是否正在流式传输数据bool			power_on;//一个布尔值,指示摄像头是否已打开电源const struct gc2053_mode *cur_mode;//指向当前摄像头模式的指针unsigned int        lane_num;//摄像头通道的数量unsigned int        cfg_num;//摄像头配置的数量unsigned int        pixel_rate;//摄像头像素速率u32         module_index;//摄像头模块索引const char      *module_facing;//摄像头模块方向const char      *module_name;//摄像头模块名称const char      *len_name;//摄像头镜头名称struct rkmodule_awb_cfg awb_cfg;//摄像头自动白平衡配置struct rkmodule_lsc_cfg lsc_cfg;//摄像头镜头畸变校正配置u8			flip;//摄像头图像翻转标志
};

 3 gc2053_probe函数

	gc2053->client = client;ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,&gc2053->module_index);ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,&gc2053->module_facing);ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,&gc2053->module_name);ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,&gc2053->len_name);if (ret) {dev_err(dev,"could not get module information!\n");return -EINVAL;}gc2053->xvclk = devm_clk_get(&client->dev, "xvclk");if (IS_ERR(gc2053->xvclk)) {dev_err(&client->dev, "Failed to get xvclk\n");return -EINVAL;}gc2053->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);if (IS_ERR(gc2053->reset_gpio))dev_warn(dev, "Failed to get reset-gpios\n");gc2053->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);if (IS_ERR(gc2053->pwdn_gpio))dev_info(dev, "Failed to get pwdn-gpios, maybe no used\n");gc2053->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);if (IS_ERR(gc2053->power_gpio))dev_warn(dev, "Failed to get power-gpios\n");

 通过设备树获取摄像头模块索引,摄像头模块方向,摄像头模块名称,摄像头镜头名称,摄像头外部时钟,复位,上电,下电的gpio引脚。

static int gc2053_configure_regulators(struct gc2053 *gc2053)
{unsigned int i;// 使用 for 循环遍历 GC2053_NUM_SUPPLIES 次。for (i = 0; i < GC2053_NUM_SUPPLIES; i++)gc2053->supplies[i].supply = gc2053_supply_names[i];// 将 gc2053->supplies[i].supply 设置为 gc2053_supply_names[i]。return devm_regulator_bulk_get(&gc2053->client->dev,GC2053_NUM_SUPPLIES,gc2053->supplies);
}

配置和获取 GC2053 摄像头传感器所需的多个电源调节器(regulators) 的函数

static const char * const gc2053_supply_names[] = {
    "dovdd",    /* I/O电源*/
    "avdd",     /* 模拟电源 */
    "dvdd",     /* 数字电源*/
};

devm_regulator_bulk_get() 一次性获取多个电源调节器。
这个函数会根据 .supply 名称从设备树中查找并绑定对应的电源。

设备树类似如下,对应的电压值在datasheet有描述。

camera@30 {compatible = "galax,gc2053";reg = <0x30>;/* 电源相关 */avdd-supply = <&vcc_2v8>;dvdd-supply = <&vcc_1v2>;iovdd-supply = <&vcc_1v8>;
};

static int gc2053_parse_of(struct gc2053 *gc2053)
{// 获取设备节点和功能节点句柄。struct device *dev = &gc2053->client->dev;struct device_node *endpoint;struct fwnode_handle *fwnode;int rval;// 获取设备树中的下一个端点。endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);if (!endpoint) {// 如果端点不存在,则输出错误信息并返回错误码 -EINVAL。dev_err(dev, "Failed to get endpoint\n");return -EINVAL;}// 将端点转换为功能节点句柄。fwnode = of_fwnode_handle(endpoint);// 读取 "data-lanes" 属性的值,并将其存储在 rval 变量中。rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);if (rval <= 0) {// 如果读取失败,则输出警告信息并返回 -1。dev_warn(dev, " Get mipi lane num failed!\n");return -1;}// 将 rval 的值赋给 gc2053 结构体的 lane_num 成员。gc2053->lane_num = rval;if (2 == gc2053->lane_num) {// 如果 lane_num 等于 2,则设置当前模式为支持的模式列表中的第一个模式。gc2053->cur_mode = &supported_modes[0];gc2053->cfg_num = ARRAY_SIZE(supported_modes);// 计算像素速率:pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE。gc2053->pixel_rate = MIPI_FREQ_297M * 2U * (gc2053->lane_num) / 10U;// 输出信息,显示 lane_num 和 pixel_rate。dev_info(dev, "lane_num(%d)  pixel_rate(%u)\n",gc2053->lane_num, gc2053->pixel_rate);} else {// 如果 lane_num 不等于 2,则输出信息,表示不支持该 lane_num。dev_info(dev, "gc2053 can not support the lane num(%d)\n", gc2053->lane_num);}// 返回 0,表示解析成功。return 0;
}

根据 获取的lane_num(通道数量)设置工作模式和像素速率

gc2053的mipi通道数为2。使用的模式配置

static const struct gc2053_mode supported_modes[] = {
    {
        .width = 1920,
        .height = 1080,
        .max_fps = {
            .numerator = 10000,
            .denominator = 300000,
        },
        .exp_def = 0x460,
        .hts_def = 0x898,
        .vts_def = 0x465,
        .reg_list = gc2053_1920x1080_regs_2lane,
        .hdr_mode = NO_HDR,
        .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
    },
};

.width, .height    u32    输出图像的宽度和高度(像素)
.max_fps    struct v4l2_fract    最大帧率,这里表示 10000/300000 ≈ 30 fps
.exp_def    u32    默认曝光时间(单位通常是行时钟周期)
.hts_def    u32    水平总长度(Horizontal Total Size)
.vts_def    u32    垂直总长度(Vertical Total Size)
.reg_list    const struct regval *    指向该模式下的寄存器初始化列表
.hdr_mode    enum    HDR 模式(如 NO_HDR, HDR_2EXP 等)
.vc[PAD0]    u32    Virtual Channel 编号(用于 MIPI CSI-2 多通道传输)

.width, .height    u32    输出图像的宽度和高度(像素)
.max_fps    struct v4l2_fract    最大帧率,这里表示 10000/300000 ≈ 30 fps
.exp_def    u32    默认曝光时间(单位通常是行时钟周期)
.hts_def    u32    水平总长度(Horizontal Total Size)
.vts_def    u32    垂直总长度(Vertical Total Size)
.reg_list    const struct regval *    指向该模式下的寄存器初始化列表
.hdr_mode    enum    HDR 模式(如 NO_HDR, HDR_2EXP 等)
.vc[PAD0]    u32    Virtual Channel 编号(用于 MIPI CSI-2 多通道传输)

gc2053->pixel_rate = MIPI_FREQ_297M * 2U * (gc2053->lane_num) / 10U;用于计算像素速率,表示单位时间内输出的像素数量。

MIPI_FREQ_297M    MIPI 链路频率,假设为 297 MHz(这是一个常见值)
2U    每个时钟周期传输两个字节(因为使用的是 MIPI CSI-2 协议中的 D-PHY 模式)
gc2053->lane_num    使用的 MIPI 数据通道数(2)
10U    每个像素占用的 bit 数(例如 RAW10 格式就是每个像素占 10 位)

http://www.lqws.cn/news/150193.html

相关文章:

  • 微服务架构下的服务注册与发现:Eureka 深度解析
  • 4.3 HarmonyOS NEXT AI驱动的交互创新:智能助手、实时语音与AR/MR开发实战
  • redis分布式锁的实际业务使用和底层基本原理 对比 lock trylock
  • Linux环境-通过命令查看zookeeper注册的服务
  • DisplayPort 2.0协议介绍(1)
  • x86 汇编中的【条件跳转指令】:从基础到扩展的全面解析(查表版)
  • 新建网站部署流程
  • 力扣面试150题--被围绕的区域
  • ArcGIS Pro 3.4 二次开发 - 公共设施网络
  • 实时数据仓库是什么?数据仓库设计怎么做?
  • Neovim - 常用插件,提升体验(三)
  • [论文阅读] 人工智能+项目管理 | 当 PMBOK 遇见 AI:传统项目管理框架的破局之路
  • flutter 中Stack 使用clipBehavior: Clip.none, 超出的部分无法响应所有事件
  • 深度学习在非线性场景中的核心应用领域及向量/张量数据处理案例,结合工业、金融等领域的实际落地场景分析
  • 电子行业AI赋能软件开发经典案例——某金融软件公司
  • 软考 系统架构设计师系列知识点之杂项集萃(82)
  • Qt实现一个悬浮工具箱源码分享
  • 【HarmonyOS 5】 社交行业详解以及 开发案例
  • 使用 HTML +JavaScript 从零构建视频帧提取器
  • vue3+ts实现百度地图鼠标绘制多边形
  • Oracle-高频业务表的性能检查
  • 深度解析地质灾害风险普查:RS与GIS技术在泥石流、滑坡灾害中的应用,ArcGIS数据管理、空间数据转换、专题地图制作、DEM分析及实战案例分析
  • Transformer实战——词嵌入技术详解
  • 基于Qt的app开发第十三天
  • Java爬虫技术详解:原理、实现与优势
  • 【设计模式-4.11】行为型——解释器模式
  • JMeter 实现 MQTT 协议压力测试 !
  • MySQL中的部分问题(1)
  • kafka入门学习
  • windows10 php报错