96SEO 2026-02-19 21:44 13
传输2c_imx_dma_readi2c_…IMX6ULL的I2C驱动详细分析

IMX6ULL的I2C驱动详细分析i2c_imx_driver
的平台驱动注册i2c_imx_probe注册函数i2c_imx_algoI2C算法结构体i2c_imx_start开始I2Ci2c_imx_stop停止I2Ci2c_imx_isr中断服务函数i2c_imx_dma_writeDMA
传输2c_imx_dma_readi2c_imx_writei2c_imx_read
platform_driver_register(i2c_imx_driver);
subsys_initcall(i2c_adap_imx_init);
{platform_driver_unregister(i2c_imx_driver);
module_exit(i2c_adap_imx_exit);
的平台驱动结构体并实现了两个函数i2c_adap_imx_init
driver驱动结构体其中包含驱动的名称、模块拥有者、设备树匹配表和电源管理等信息。
i2c_imx_driver。
这将使得驱动在系统初始化期间被加载并可用。
函数返回注册结果。
i2c_imx_driver。
这将在模块退出时执行用于释放已注册的平台驱动。
函数没有返回值。
函数注册为模块的退出函数。
这将在模块卸载时调用以执行平台驱动的注销操作。
驱动并提供了初始化和退出函数来注册和注销该驱动。
驱动注册时将根据设备树的匹配信息进行初始化并在模块退出时进行注销以确保平台驱动的正确加载和释放。
函数的主要功能是在设备匹配成功时进行设备初始化。
下面是该函数的主要步骤
最后函数返回0表示成功初始化设备返回其他错误代码表示初始化失败。
of_match_device(i2c_imx_dt_ids,pdev-dev);//
devm_ioremap_resource(pdev-dev,
*)platform_get_device_id(pdev)-driver_data;/*
复制设备名到I2C适配器结构体中strlcpy(i2c_imx-adapter.name,
sizeof(i2c_imx-adapter.name));//
设置I2C适配器结构体中的成员变量i2c_imx-adapter.owner
THIS_MODULE;i2c_imx-adapter.algo
i2c_imx_algo;i2c_imx-adapter.dev.parent
pdev-id;i2c_imx-adapter.dev.of_node
clk_prepare_enable(i2c_imx-clk);
*/init_waitqueue_head(i2c_imx-queue);
*/i2c_set_adapdata(i2c_imx-adapter,
of_property_read_u32(pdev-dev.of_node,clock-frequency,
*/imx_i2c_write_reg(i2c_imx-hwdata-i2cr_ien_opcode
IMX_I2C_I2CR);imx_i2c_write_reg(i2c_imx-hwdata-i2sr_clr_opcode,
i2c_add_numbered_adapter(i2c_imx-adapter);if
i2c_imx);clk_disable_unprepare(i2c_imx-clk);dev_dbg(i2c_imx-adapter.dev,
irq);dev_dbg(i2c_imx-adapter.dev,
res);dev_dbg(i2c_imx-adapter.dev,
\%s\\n,i2c_imx-adapter.name);dev_info(i2c_imx-adapter.dev,
*/clk_disable:clk_disable_unprepare(i2c_imx-clk);return
针对每个传输消息进行读写操作。
根据消息的标志位如果是读操作则调用
i2c_get_adapdata(adapter);dev_dbg(i2c_imx-adapter.dev,
{dev_dbg(i2c_imx-adapter.dev,%s
fail0;}dev_dbg(i2c_imx-adapter.dev,%s
IMX_I2C_I2CR);dev_dbg(i2c_imx-adapter.dev,%s
IMX_I2C_I2SR);dev_dbg(i2c_imx-adapter.dev,%s
停止I2C传输dev_dbg(i2c_imx-adapter.dev,
I2C_FUNC_SMBUS_READ_BLOCK_DATA;
事务。
它确保时钟和寄存器的设置正确并将控制器设置为主机模式。
函数执行成功后即可开始进行
result;dev_dbg(i2c_imx-adapter.dev,
设置I2C时钟i2c_imx_set_clk(i2c_imx);//
clk_prepare_enable(i2c_imx-clk);if
写入分频值imx_i2c_write_reg(i2c_imx-ifdr,
*/imx_i2c_write_reg(i2c_imx-hwdata-i2sr_clr_opcode,
IMX_I2C_I2SR);imx_i2c_write_reg(i2c_imx-hwdata-i2cr_ien_opcode,
I2CR_MSTA;imx_i2c_write_reg(temp,
~I2CR_DMAEN;imx_i2c_write_reg(temp,
事务的停止过程。
它会清除控制器的相关标志位并释放使用的资源以便下次进行新的
~I2CR_DMAEN;imx_i2c_write_reg(temp,
如果没有或太短的延迟将不会生成“STOP”位。
*/udelay(i2c_imx-disable_delay);}if
I2CR_IEN,imx_i2c_write_reg(temp,
IMX_I2C_I2CR);clk_disable_unprepare(i2c_imx-clk);
如果中断标志位已经被设置则保存状态寄存器的值并清除中断标志位。
然后函数会根据硬件数据表中的操作码将清除中断标志位的操作码写入状态寄存器。
(i2c_imx-hwdata-i2sr_clr_opcode
I2SR_IIF);imx_i2c_write_reg(temp,
IMX_I2C_I2SR);wake_up(i2c_imx-queue);
相关参数进行设置包括选择发送通道、传输方向、数据方向和传输长度。
DMA传输方向为从内存到设备dma-dma_transfer_dir
I2CR_DMAEN;imx_i2c_write_reg(temp,
第一个字节必须由CPU传输。
*/imx_i2c_write_reg(msgs-addr
IMX_I2C_I2DR);reinit_completion(i2c_imx-dma-cmd_complete);time_left
wait_for_completion_timeout(i2c_imx-dma-cmd_complete,msecs_to_jiffies(DMA_TIMEOUT));if
{dmaengine_terminate_all(dma-chan_using);return
msecs_to_jiffies(DMA_TIMEOUT)))
*/imx_i2c_write_reg(msgs-buf[msgs-len-1],i2c_imx,
i2c_imx_trx_complete(i2c_imx);if
函数i2c_imx_dma_read是用于在i.MX系列芯片上进行I2C数据读取的函数。
它使用DMA进行数据传输并处理了传输完成、超时等情况。
开启DMA传输设置I2C控制寄存器的DMAEN位启用DMA传输。
设置DMA通道为接收通道将DMA通道设置为接收通道并指定数据传输方向为从设备到内存。
执行DMA传输调用i2c_imx_dma_xfer函数执行DMA传输。
等待DMA传输完成使用等待完成机制等待DMA传输完成如果超时则终止DMA传输并返回超时错误。
等待数据传输完成循环检查I2C状态寄存器直到传输完成或超时。
如果超时则返回超时错误。
关闭DMA传输将I2C控制寄存器的DMAEN位清除关闭DMA传输。
读取数据从I2C数据寄存器读取n-1个字节的数据并调用i2c_imx_trx_complete函数完成传输。
处理最后一个消息如果是最后一个消息清除主模式和传输模式位将总线设置为空闲状态并标记传输已停止。
否则设置传输模式为主模式接收并读取最后一个字节的数据。
总体而言函数i2c_imx_dma_read使用DMA进行I2C数据读取处理了传输中断、超时和最后一个消息的情况并最终返回传输结果。
I2CR_DMAEN;imx_i2c_write_reg(temp,
DMA传输方向为从设备到内存dma-dma_transfer_dir
等待DMA传输完成reinit_completion(i2c_imx-dma-cmd_complete);time_left
wait_for_completion_timeout(i2c_imx-dma-cmd_complete,msecs_to_jiffies(DMA_TIMEOUT));if
{dmaengine_terminate_all(dma-chan_using);return
msecs_to_jiffies(DMA_TIMEOUT)))
在读取I2DR之前必须生成STOP以防止控制器生成另一个时钟周期*/dev_dbg(dev,
清除MSTA和MTX位imx_i2c_write_reg(temp,
写入I2CR寄存器i2c_imx_bus_busy(i2c_imx,
在第一个读操作中在读取最后一个字节之前控制器必须设置MTX否则第一个读操作会多花费一个时钟周期。
*/temp
函数i2c_imx_write是用于在i.MX系列芯片上进行I2C数据写入的函数。
等待传输完成调用i2c_imx_trx_complete函数等待传输完成。
检查ACK调用i2c_imx_acked函数检查是否收到ACK。
等待传输完成调用i2c_imx_trx_complete函数等待传输完成。
检查ACK调用i2c_imx_acked函数检查是否收到ACK。
总体而言函数i2c_imx_write用于通过I2C总线向从设备写入数据。
它将从设备地址和数据逐个字节写入I2C数据寄存器并在每个字节写入后等待传输完成和检查ACK。
最后函数返回传输结果。
result;dev_dbg(i2c_imx-adapter.dev,
result;dev_dbg(i2c_imx-adapter.dev,
{dev_dbg(i2c_imx-adapter.dev,%s
输出调试信息写字节imx_i2c_write_reg(msgs-buf[i],
函数i2c_imx_read是用于在i.MX系列芯片上进行I2C数据读取的函数。
写入从设备地址将从设备地址左移一位并将最低位设置为1表示读取操作。
等待传输完成调用i2c_imx_trx_complete函数等待传输完成。
检查ACK调用i2c_imx_acked函数检查是否收到ACK。
设置总线以读取数据读取I2CR寄存器的值并清除MTX位表示将进行读取操作。
重置I2CR_TXAK标志位对于SMBus块读或读取长度大于1的情况重置I2CR_TXAK标志位。
读取I2DR寄存器执行虚拟读取读取I2DR寄存器的值此读取不会返回实际的数据。
如果使用DMA传输且满足使用DMA传输的条件则调用i2c_imx_dma_read函数进行数据读取。
等待传输完成调用i2c_imx_trx_complete函数等待传输完成。
对于SMBus块读的第一个字节读取长度并添加到msgs-len中。
如果is_lastmsg为true生成STOP信号并清除MSTA和MTX标志位以防止控制器生成另一个时钟周期。
如果是SMBus块读的第一个字节将长度存储在msgs-buf[0]中。
总体而言函数i2c_imx_read用于通过I2C总线从从设备读取数据。
它发送从设备地址并根据读取长度和是否使用DMA传输等条件进行数据读取。
在循环读取数据时它会检查是否是SMBus块读的第一个字节并根据是否是最后一个消息进行相应的操作。
最后函数返回传输结果。
判断是否为SMBus块读dev_dbg(i2c_imx-adapter.dev,%s
result;dev_dbg(i2c_imx-adapter.dev,
如果是SMBus块读则重置I2CR_TXAK标志位imx_i2c_write_reg(temp,
写入I2CR寄存器imx_i2c_read_reg(i2c_imx,
读取I2DR寄存器dev_dbg(i2c_imx-adapter.dev,
返回错误dev_dbg(i2c_imx-adapter.dev,%s
在读取I2DR之前必须生成STOP以防止控制器生成另一个时钟周期*/dev_dbg(i2c_imx-adapter.dev,%s
I2CR_MTX);imx_i2c_write_reg(temp,
IMX_I2C_I2CR);i2c_imx_bus_busy(i2c_imx,
在第一个读操作中在读取最后一个字节之前控制器必须设置MTX否则第一个读操作会多花费一个时钟周期。
*/temp
{dev_dbg(i2c_imx-adapter.dev,%s
I2CR_TXAK;imx_i2c_write_reg(temp,
IMX_I2C_I2DR);dev_dbg(i2c_imx-adapter.dev,%s
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback