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

瑞芯微 MIPI D-PHY 接收器(RX)驱动学习笔记

驱动文件位置 driver/phy/rockchip/phy-rockchip-mipi-rx.c

1 重要结构体

struct mipidphy_priv {struct device *dev;//表示与驱动程序关联的设备。它用于设备管理,如设备注册、注销等。struct regmap *regmap_grf;//用于映射和访问通用寄存器文件(General Register File,GRF)的寄存器。regmap 提供了一种灵活的寄存器访问接口const struct dphy_reg *grf_regs;//包含了GRF寄存器的定义和布局const struct txrx_reg *txrx_regs;//包含了TX/RX通道寄存器的定义和布局const struct csiphy_reg *csiphy_regs;//包含了CSI PHY寄存器的定义和布局void __iomem *csihost_base_addr;//这是一个指向内存映射I/O区域的指针,表示CSI主机接口的基地址struct clk *clks[MAX_DPHY_CLK];//这是一个指向时钟结构体数组的指针,用于管理设备的所有时钟资源。const struct dphy_drv_data *drv_data;//包含了驱动程序特定的数据和配置信息u64 data_rate_mbps;//表示设备支持的最大数据传输速率,单位是Mbps。struct v4l2_async_notifier notifier;//用于V4L2异步通知机制,允许设备在连接或断开时发送通知。struct v4l2_subdev sd;//表示一个V4L2子设备,用于V4L2框架中的设备管理和媒体流控制。struct mutex mutex; /* lock for updating protection */struct media_pad pads[MIPI_DPHY_RX_PADS_NUM];//表示媒体设备的连接端口。MIPI_DPHY_RX_PADS_NUM 是端口数量的宏定义。struct mipidphy_sensor sensors[MAX_DPHY_SENSORS];//用于存储和管理连接到MIPI DPHY的sensors信息int num_sensors;//表示当前连接到MIPI DPHY的sensors数量int phy_index;//bool is_streaming;//指示设备是否正在处理媒体流void __iomem *txrx_base_addr;//这是一个指向内存映射I/O区域的指针,表示TX/RX通道的基地址。int (*stream_on)(struct mipidphy_priv *priv, struct v4l2_subdev *sd);//该函数在开始媒体流传输时被调用int (*stream_off)(struct mipidphy_priv *priv, struct v4l2_subdev *sd);//该函数在停止媒体流传输时被调用
};

struct dphy_drv_data {const char * const *clks;//包含了设备所需的时钟名称。这些时钟名称用于在设备初始化时请求相应的时钟资源。int num_clks;//表示 clks 数组中时钟名称的数量。const struct hsfreq_range *hsfreq_ranges;//包含了设备支持的高速频率范围。这些范围定义了设备在不同工作模式下可以支持的时钟频率。int num_hsfreq_ranges;//表示 hsfreq_ranges 数组中高速频率范围的数量。const struct dphy_reg *grf_regs;//包含了设备通用寄存器(GRF)的定义和布局const struct txrx_reg *txrx_regs;//包含了设备TX/RX通道寄存器的定义和布局。const struct csiphy_reg *csiphy_regs;//包含了设备CSI PHY寄存器的定义和布局enum mipi_dphy_ctl_type ctl_type;//表示MIPI DPHY的控制类型。这个成员指示了设备应该如何被控制,例如,是通过硬件控制还是软件控制void (*individual_init)(struct mipidphy_priv *priv);//这个函数在设备初始化时被调用,用于执行设备特定的初始化操作。enum mipi_dphy_chip_id chip_id;//表示MIPI DPHY芯片的ID。这个成员用于标识设备的具体型号或版本
};

2 rockchip_mipidphy_probe(struct platform_device *pdev)函数

  

 1 分配内存,匹配设备树。

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);if (!priv)return -ENOMEM;priv->dev = dev;of_id = of_match_device(rockchip_mipidphy_match_id, dev);if (!of_id)return -EINVAL;

2 获取 GRF(全局复用寄存器)

尝试从父设备获取 GRF 寄存器映射。
如果失败,在当前设备的设备树节点中查找一个名为 "rockchip,grf" 的 phandle。
将找到的 regmap 保存到 priv->regmap_grf 中。

形如:

some_device: some-device@... {

rockchip,grf = <&grf>;

};

	grf = syscon_node_to_regmap(dev->parent->of_node);if (IS_ERR(grf)) {grf = syscon_regmap_lookup_by_phandle(dev->of_node,"rockchip,grf");if (IS_ERR(grf)) {dev_err(dev, "Can't find GRF syscon\n");return -ENODEV;}}priv->regmap_grf = grf;

3通过别名(alias)获取 D-PHY 的索引号(例如 dphy0, dphy1)

priv->phy_index = of_alias_get_id(dev->of_node, "dphy");
if (priv->phy_index < 0)priv->phy_index = 0;

4 获取时钟资源

5 设置寄存器指针

priv->grf_regs = drv_data->grf_regs;
priv->txrx_regs = drv_data->txrx_regs;
priv->csiphy_regs = drv_data->csiphy_regs;
priv->drv_data = drv_data;

6 根据控制类型选择操作函数和寄存器地址

CSI Host 模式:SoC 作为摄像头控制器,连接并读取摄像头数据;
TX/RX 模式:SoC 作为通用的 MIPI D-PHY 收发器,可能用于其他用途(比如显示、调试等);

if (drv_data->ctl_type == MIPI_DPHY_CTL_CSI_HOST) {res = platform_get_resource(pdev, IORESOURCE_MEM, 0);priv->csihost_base_addr = devm_ioremap_resource(dev, res);priv->stream_on = csi_mipidphy_stream_on;priv->stream_off = csi_mipidphy_stream_off;
} else {priv->stream_on = mipidphy_txrx_stream_on;priv->txrx_base_addr = NULL;res = platform_get_resource(pdev, IORESOURCE_MEM, 0);priv->txrx_base_addr = devm_ioremap_resource(dev, res);if (IS_ERR(priv->txrx_base_addr))priv->stream_on = mipidphy_rx_stream_on;priv->stream_off = NULL;
}

7 初始化 V4L2 子设备

sd = &priv->sd;
mutex_init(&priv->mutex);
v4l2_subdev_init(sd, &mipidphy_subdev_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
snprintf(sd->name, sizeof(sd->name), "rockchip-mipi-dphy-rx");
sd->dev = dev;

8 初始化媒体实体和电源管理

ret = rockchip_mipidphy_media_init(priv);
if (ret < 0)goto destroy_mutex;pm_runtime_enable(&pdev->dev);
drv_data->individual_init(priv);
return 0;

http://www.xdnf.cn/news/13575.html

相关文章:

  • 达梦数据库(DM)用户名大小写处理规则
  • MAC-苹果电脑专业卸载工具AppCleaner
  • C++ Vector深度解析:动态组的底层机制与实战指南
  • 无人机技术与低空经济的融合:探索未来
  • 桥接模式深度解析:Java设计模式实战指南与抽象实现分离架构设计
  • Mac中安装Anaconda、Anaconda基础命令、Pycharm结合Anaconda,看这一篇就够啦!
  • 接口实现类向上转型和向上转型解析
  • 嵌入式学习笔记 - C语言中结构体的定义,以及结构体变量的内存空间的分配
  • Ubuntu24.04 onnx 模型转 rknn
  • 离线部署openstack 2024.1 glance
  • 离线部署openstack 2024.1控制节点neutron
  • MySQL之事务与读视图
  • 硬件行业职业规划四篇
  • Day-16【选择与循环】04循环结构while
  • Python窗体编程技术详解:从入门到精通实战指南
  • CTF-DAY13 PolarDN2025年夏季个人 复现
  • ETLCloud中数据生成规则使用技巧
  • Vue2 与 Vue3 的插槽(默认插槽、具名插槽、作用域插槽、具名插槽 + 作用域插槽)
  • lesson05-手写数据问题案例实战(理论+代码)
  • linux回收站
  • 爱普生TG5032SGN同步以太网的高精度时钟解决方案
  • P2840 纸币问题 2
  • 华为OD机考-数字螺旋矩阵(JAVA 2025B卷)
  • Python前端系列(三)
  • DATABASE 结构迁移实战手册:脚本生成、分类与部署全流程详解
  • 华为云Flexus+DeepSeek征文|华为云CCE容器高可用部署Dify LLM应用后的资源释放指南
  • 掌握Linux进程替换:从原理到实战(自定义shell)
  • 笔试模拟day1
  • 随记 使用certbot申请ssl证书
  • 跨域的本质与实战:从理论到松鼠短视频系统的演进-优雅草卓伊凡|卢健bigniu