高通msm8916 LK阶段配置使用i2c5

高通msm8916 LK阶段配置使用i2c5背景:在调试SLM753某客户项目LCM时,客户使用LVDS的LCM,而msm8916只有一个mipi的接口,所以就是用到了mipi-2-lvds转换芯片:icn6202。这颗芯片需要使用I2C进行配置LVDS屏的时钟和分辨率等信息,以至于LVDS屏可以正常显示。Kernel阶段i2c比较容易使用,只需在dts中配置一个i2c设备即可以使用对应的i2c接口进行数据传输,但是LK阶段的代码就显得

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

背景:

在调试SLM753某客户项目LCM时,客户使用LVDS的LCM,而msm8916只有一个mipi的接口,所以就是用到了mipi-2-lvds转换芯片:icn6202。这颗芯片需要使用I2C进行配置LVDS屏的时钟和分辨率等信息,以至于LVDS屏可以正常显示。Kernel阶段i2c比较容易使用,只需在dts中配置一个i2c设备即可以使用对应的i2c接口进行数据传输,但是LK阶段的代码就显得蹩脚了,默认只配置了i2c0接口!!其他的i2c都不能使用,所以在不能修改硬件的情况下,调试i2c5成了不能绕开的关口!

解决方法:

注意:本文只介绍LK阶段配置i2c5,并测试i2c5的方法,不介绍i2cn6202的使用方法,谢谢!

1、下图为i2c0和i2c5对应的GPIO口。

高通msm8916 LK阶段配置使用i2c5

i2c0:gpio6&gpio7;i2c5:gpio18&gpio19;

I2c0对应的物理地址为0x78B6000

I2c5对应的物理地址为0x78B9000

2、LK qup_blsp_i2c_init函数剖析

         在文件I2c_qup.c(platform\msm_shared)中定义了高通申请i2c的接口:qup_blsp_i2c_init。

申请I2C5:

         staticstruct qup_i2c_dev  *i2c_dev_6202;
         i2c_dev_6202= qup_blsp_i2c_init(BLSP_ID_1, QUP_ID_4, 100000, 19200000);

进入qup_blsp_i2c_init函数,修改下面两个函数:

  /*Initialize the GPIO for BLSP i2c */
 gpio_config_blsp_i2c(blsp_id, qup_id);
 
 clock_config_blsp_i2c(blsp_id, qup_id);

首先修改GPIO配置,进入gpio_config_blsp_i2c(blsp_id, qup_id);

加入一个case选项:

case QUP_ID_4:
                                     /*configure I2C SDA gpio */
                                     gpio_tlmm_config(18,2, GPIO_OUTPUT, GPIO_NO_PULL,
                                                        GPIO_8MA,GPIO_DISABLE);
 
                                     /*configure I2C SCL gpio */
                                     gpio_tlmm_config(19,2, GPIO_OUTPUT, GPIO_NO_PULL,
                                               GPIO_8MA,GPIO_DISABLE);
                                     dprintf(CRITICAL,"eliot : gpio_config_blsp_i2c QUP_ID_4 %d\n",qup_id);
                            break;

进入clock_config_blsp_i2c(blsp_id, qup_id);

屏蔽如下代码:

/*
         if((blsp_id!= BLSP_ID_1) || (qup_id != QUP_ID_1)) {
                   dprintf(CRITICAL,"Incorrect BLSP-%d or QUP-%d configuration\n", blsp_id, qup_id);
                   ASSERT(0);
         }
*/

然后修改时钟的一些配置,这里比较关键,也比较复杂。

修改

snprintf(clk_name, sizeof(clk_name),"blsp1_qup2_ahb_iface_clk");
to
snprintf(clk_name, sizeof(clk_name),"blsp1_qup4_ahb_iface_clk");
 
修改
snprintf(clk_name, sizeof(clk_name),"gcc_blsp1_qup2_i2c_apps_clk");
to
snprintf(clk_name, sizeof(clk_name),"gcc_blsp1_qup4_i2c_apps_clk");

但是我们发现,”blsp1_qup4_ahb_iface_clk”和”gcc_blsp1_qup4_i2c_apps_clk”其实并没有定义!

找到定义的地方,在文件Msm8916-clock.c (platform\msm8916)

时钟列表中加入qup4_i2c这三个时钟:

static struct clk_lookup msm_clocks_8916[]= {
         CLK_LOOKUP("blsp1_qup2_ahb_iface_clk",gcc_blsp1_ahb_clk.c),
         CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk_src",gcc_blsp1_qup2_i2c_apps_clk_src.c),
         CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk",gcc_blsp1_qup2_i2c_apps_clk.c),
 
         CLK_LOOKUP("blsp1_qup4_ahb_iface_clk",gcc_blsp1_ahb_clk.c),
         CLK_LOOKUP("gcc_blsp1_qup4_i2c_apps_clk_src",gcc_blsp1_qup4_i2c_apps_clk_src.c),
         CLK_LOOKUP("gcc_blsp1_qup4_i2c_apps_clk",gcc_blsp1_qup4_i2c_apps_clk.c),
};

注意到每一个时钟名字都和一个结构体相连,所以我们还要补充后面的结构体!

gcc_blsp1_ahb_clk.c同”blsp1_qup2_ahb_iface_clk”一致。

gcc_blsp1_qup4_i2c_apps_clk_src结构体如下:

static struct rcg_clkgcc_blsp1_qup4_i2c_apps_clk_src =
{
         .cmd_reg      = (uint32_t *) GCC_BLSP1_QUP4_CMD_RCGR,
         .cfg_reg      = (uint32_t *) GCC_BLSP1_QUP4_CFG_RCGR,
         .set_rate     = clock_lib2_rcg_set_rate_hid,
         .freq_tbl     = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src,
         .current_freq= &rcg_dummy_freq,
 
         .c= {
                   .dbg_name= "gcc_blsp1_qup4_i2c_apps_clk_src",
                   .ops      = &clk_ops_rcg,
         },
};

gcc_blsp1_qup4_i2c_apps_clk结构体如下:

static struct branch_clkgcc_blsp1_qup4_i2c_apps_clk = {
         .cbcr_reg= GCC_BLSP1_QUP4_APPS_CBCR,
         .parent   = &gcc_blsp1_qup4_i2c_apps_clk_src.c,
 
         .c= {
                   .dbg_name= "gcc_blsp1_qup4_i2c_apps_clk",
                   .ops      = &clk_ops_branch,
         },
};

此时需要重新定义

#define GCC_BLSP1_QUP4_APPS_CBCR    (CLK_CTL_BASE + 0x6020)
#define GCC_BLSP1_QUP4_CFG_RCGR     (CLK_CTL_BASE + 0x6004)
#define GCC_BLSP1_QUP4_CMD_RCGR     (CLK_CTL_BASE + 0x6000)

 

结构体其它部分仿照blsp1_qup2时钟结构体即可。

 

到目前为止i2c5的申请工作完成,总结起来主要是对代码的跟踪,仿照i2c0(QUP2)对应的GPIO和时钟进行配置。但是寄存器的值就需要查找msm8916有关BLSP相关寄存器文档了!

3、下面介绍LK 如何使用i2c.

读写函数如下:

static int qrd_icn_i2c_read(uint8_taddr) 
{ 
   int ret = 0;
         intval = 0 ;
   /* Create a i2c_msg buffer, that is used to put the controller into read
      mode and then to read some data. */ 
   struct i2c_msg msg_buf[] = { 
       {Slave_addr, I2C_M_WR, 1, &addr}, 
       {Slave_addr, I2C_M_RD, 1, &val} 
   }; 
 
   ret = qup_i2c_xfer(i2c_dev_6202, msg_buf, 2);
         dprintf(CRITICAL,"eliot qrd_lcd_i2c_read addr = %d, val = 0x%x\n",addr,val);
   if(ret < 0) { 
       dprintf(CRITICAL, "qup_i2c_xfer error %d\n", ret); 
       return ret; 
   } 
   return val;  
} 
static int qrd_icn_i2c_write(uint8_t addr,uint8_t val)
{
         intret = 0;
         uint8_tdata_buf[] = { addr, val };
 
         /*Create a i2c_msg buffer, that is used to put the controller into write
            mode and then to write some data. */
         structi2c_msg msg_buf[] = { {Slave_addr,
                                           I2C_M_WR, 2, data_buf}
         };
 
         ret= qup_i2c_xfer(i2c_dev_6202, msg_buf, 1);
         if(ret< 0) {
                   dprintf(CRITICAL,"eliot qup_i2c_xfer error %d\n", ret);
                   returnret;
         }
         return0;
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180422.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Linux抓包命令tcpdump「建议收藏」

    Linux抓包命令tcpdump「建议收藏」tcpdump是一个抓包工具,用于抓取互联网上传输的数据包tcpdump是一个用于截取网络分组,并输出分组内容的工具。凭借强大的功能和灵活的截取策略,使其成为类UNIX系统下用于网络分析和问题排查的首选工具tcpdump支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息#常用选项-i#监听哪一个网卡-n #不把ip解析成主机名-nn #不把端口解析成应用层协议-c #指定抓包的数量-S #不把随机序

  • 卸载python会删除pip安装的包吗_pip更新软件包

    卸载python会删除pip安装的包吗_pip更新软件包

    2022年10月17日
  • QT的基本知识「建议收藏」

    QT的基本知识「建议收藏」QT是一个跨平台应用程序和UI开发框架。具体的安装以及源文件的下载这里不详细介绍。要在QT界面上添加一个按钮,可以有两种方法:一个是直接拖放一个按钮即可;另一种则是通过程序来添加一种按钮。QT提供的信号和槽机制,可以让任意两个对象之间进行消息处理,其作用就是让一个对象产生的信号能够被另一个对象接受并处理。QT基本所有的对象都集成在QObject对象中,在这个对象中有一个静态函数connect…

  • 数据仓库之电商数仓– 3.1、电商数据仓库系统(ODS层、DIM层、DWD层)

    数据仓库之电商数仓– 3.1、电商数据仓库系统(ODS层、DIM层、DWD层)目录一、数仓分层1.1为什么要分层1.2数据集市与数据仓库概念1.3数仓命名规范1.3.1表命名1.3.2脚本命名1.3.3表字段类型二、数仓理论2.1范式理论2.1.1范式概念2.1.2函数依赖2.1.3三范式区分2.2关系建模与维度建模2.2.1关系建模2.2.2维度建模⭐️2.3维度表和事实表⭐️2.3.1维度表2.3.2事实表2.4维度模型分类2.5数据仓库建模⭐️????2.5.1ODS层2.5.2DIM层和DWD层2.5.3DWS层与DWT层2.5.4

  • -2147467259数据库操作错误!

    -2147467259数据库操作错误!没事说搭建个asp的网站,下载了个aspcms源码系统。搭建出现的主要问题是:登录后台的时候提示:-2147467259数据库操作错误!怎么解决?搜索了一下,有些说得是那么个意思,可是我的电脑环境也有些特殊情况。(比如:文件夹属性中没有“安全”选项卡)下面整理下:-21474672

  • 逻辑运算指令和移位指令

    逻辑运算指令和移位指令ANDXORTESTSHLSALROLRCLOR

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号