高通lk:配置与使用i2c
高通lk:配置与使用i2c
以msm8909为例。
背景
在lk中要去驱动一个aw9523的ic来控制指示灯。
但是现在对应的i2c没有打开。因此需要进行处理。
步骤
找到I2C对应的ID与句柄
参考文档:80-nu767-1_l_bam_low-speed_peripherals_(blsp)_user_guide.pdf

根据其他人的说法,i2c-1对应的是第一个BLSP1、QUP0、0x78B5000。
添加有关的时钟
路径:bootable/bootloader/lk/platform/msm8909/msm8909-clock.c
+
+// i2c-1
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup1_i2c_apps_clk_src[] =
+{
+	F(      96000,    cxo,  10,   1,  2),
+	F(    4800000,    cxo,   4,   0,  0),
+	F(    9600000,    cxo,   2,   0,  0),
+	F(   16000000,  gpll0,  10,   1,  5),
+	F(   19200000,  cxo,   1,   0,  0),
+	F(   25000000,  gpll0,  16,   1,  2),
+	F(   50000000,  gpll0,  16,   0,  0),
+	F_END
+};
+
+static struct rcg_clk gcc_blsp1_qup1_i2c_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP1_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP1_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_blsp1_qup1_i2c_apps_clk = {
+	.cbcr_reg = GCC_BLSP1_QUP1_APPS_CBCR,
+	.parent   = &gcc_blsp1_qup1_i2c_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_qup1_i2c_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct rcg_clk gcc_blsp1_qup2_i2c_apps_clk_src =
 {
@@ -585,6 +623,11 @@ static struct clk_lookup msm_clocks_msm8909[] =
 	CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk", gcc_blsp1_qup2_i2c_apps_clk.c),
+	// i2c-1
+	CLK_LOOKUP("blsp1_qup1_ahb_iface_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("gcc_blsp1_qup1_i2c_apps_clk_src", gcc_blsp1_qup1_i2c_apps_clk_src.c),
+	CLK_LOOKUP("gcc_blsp1_qup1_i2c_apps_clk", gcc_blsp1_qup1_i2c_apps_clk.c),
+
 	CLK_LOOKUP("mdp_ahb_clk", mdp_ahb_clk.c),
 	CLK_LOOKUP("mdss_esc0_clk", mdss_esc0_clk.c),
 	CLK_LOOKUP("mdss_axi_clk", mdss_axi_clk.c),
初始化
+static void i2c1_init(void)
+{
+    static int flag = 1;
+
+    dprintf(CRITICAL, "%s : start\n", __func__);
+    if(flag != 1)
+        goto end;
+    flag = 0;
+    // i2c-1
+   /*
+        1 arg: BLSP ID can be BLSP_ID_1 or BLSP_ID_2
+        2 arg: QUP ID can be QUP_ID_0 ~ QUP_ID_5
+        3 arg: I2C CLK. should be 100KHZ, or 400KHz
+        4 arg: Source clock, should be set @ 19.2MHz
+        */
+    i2c_dev = qup_blsp_i2c_init(BLSP_ID_1, QUP_ID_0, 100000, 19200000);
+    if(!i2c_dev)
+        dprintf(CRITICAL, "qup_blsp_i2c_init failed \n");
+end :
+    dprintf(CRITICAL, "%s : end\n", __func__);
+
+}
确保底层的调用没问题:
路径:bootable/bootloader/lk/platform/msm8909/acpuclock.c
/* Configure i2c clock */
void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
{
    uint8_t ret = 0;
    char clk_name[64];
    struct clk *qup_clk;
    if((blsp_id != BLSP_ID_1) || (qup_id > QUP_ID_5)) {
        dprintf(CRITICAL, "Incorrect BLSP-%d or QUP-%d configuration\n", blsp_id, qup_id);
        ASSERT(0);
    }
    snprintf(clk_name, sizeof(clk_name), "blsp1_qup1_ahb_iface_clk");
    ret = clk_get_set_enable(clk_name, 0 , 1);
    if (ret) {
        dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
        return;
    }
    snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup1_i2c_apps_clk");
    qup_clk = clk_get(clk_name);
    if (!qup_clk) {
        dprintf(CRITICAL, "Failed to get %s\n", clk_name);
        return;
    }
    ret = clk_enable(qup_clk);
    if (ret) {
        dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
        return;
    }
}
如果匹配不上的话,会导致下面错误:
Alert!! Requested clock "blsp1_qup1_ahb_iface_clk" is not supported![1140] [1140] Can't find clock with id: blsp1_qup1_ahb_iface_clk
读/写
+static int write_reg(uint8_t slave_addr, uint8_t reg, uint8_t val)
+{
+    int ret = 0;
+    uint8_t data_buf[] = { reg, val };
+
+    /* Create a i2c_msg buffer, that is used to put the controller into write
+       mode and then to write some data. */
+    struct i2c_msg msg_buf[] = { {slave_addr, I2C_M_WR, 2, data_buf} };
+
+    ret = qup_i2c_xfer(i2c_dev, msg_buf, 1);
+    if(ret < 0) {
+        dprintf(CRITICAL, "qup_i2c_xfer error %d\n", ret);
+        return ret;
+    }
+    return 0;
+}
+
+static int read_reg(uint8_t slave_addr, uint8_t reg, uint8_t *val)
+{
+    int ret = 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, ®},
+        {slave_addr, I2C_M_RD, 1, val}
+    };
+
+    ret = qup_i2c_xfer(i2c_dev, msg_buf, 2);
+    if(ret < 0) {
+        dprintf(CRITICAL, "qup_i2c_xfer error %d\n", ret);
+        return ret;
+    }
+    return 0;
+}
												
											高通lk:配置与使用i2c的更多相关文章
- 高通lk屏幕向kernel传参
		
LK把相关参数报存到cmdline上: 在Bootable\bootloader\lk\dev\gcdb\display\gcdb_display_param.c上gcdb_display_cmdli ...
 - 高通(QCOM)sensor bring up
		
高通7150平台 1.添加驱动文件 2.添加编译 3.配置json文件 4.高通默认配置 5.部分sensor外挂电源 6.遇到的问题 1.添加驱动文件 路径:adsp_proc/ssc/sensor ...
 - 高通spi 屏幕 -lk代码分析
		
lk SPI驱动 1. 初始化时钟 在lk中,我们是从kmain开始执行下来的,而执行顺序则是先初始化时钟,也就是在platform_early_init函数中开始执行的: 在这里我们需要修改这个函数 ...
 - 高通APQ8074 spi 接口配置
		
高通APQ8074 spi 接口配置 8074 平台含有两个BLSP(BAM Low-Speed Peripheral) , 每一个BLSP含有两个QUP, 每一个QUP可以被配置为I2C, SPI, ...
 - 【转】高通平台android 环境配置编译及开发经验总结
		
原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...
 - 高通移植mipi LCD的过程LK代码
		
lk部分:(实现LCD兼容) 1. 函数定位 aboot_init()来到target_display_init(): 这就是高通原生lk LCD 兼容的关键所在.至于你需要兼容多少LCD 就在whi ...
 - 最新内核3.4)Linux 设备树加载I2C client adapter 的流程(内核3.4 高通)【转】
		
转自:https://blog.csdn.net/lsn946803746/article/details/52515225 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转 ...
 - 高通平台msm8909 LK 实现LCD 兼容
		
前段时间小米出现红米note2 换屏门,现在我们公司也要上演了:有两个供应商提供不同IC 的LCD panel. 软件区分的办法是读取LCD IC 的ID 寄存器,下面解析高通平台LK中LCD兼容的过 ...
 - 高通平台 lcd driver 调试小结
		
一.概述 1.1 简介 本文档主要包括LCD模块的驱动流程分析.Framebuffer相关知识.Gralloc等相关内容,以及LCD调试的一些经验和相关bug的分析和讲解. 1.2 开发环境 And ...
 - Linux加载DTS设备节点的过程(以高通8974平台为例)
		
DTS是Device Tree Source的缩写,用来描述设备的硬件细节.在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码, ...
 
随机推荐
- 一个随时跟新的css库
			
1.一个选中阴影的样式 .select border: 1px solid #4d92f7; box-shadow: 0px 0px 15px rgba(0,50,122,.15); 2.一个三栏渐变 ...
 - B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能
			
B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能 @ 目录 B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa ...
 - SAP集成技术(一)历史
			
最近想读一本书<SAP Interface Management Guide>,打算边读边记录一些笔记.翻译主要由ChatGPT完成. 本文链接:https://www.cnblogs.c ...
 - DNS(7) -- 智能DNS实现
			
目录 1. 智能DNS 1.1 智能DNS概述 1.2 ACL控制列表 1.3 智能DNS实现 1.3.1 bind-view功能 1.3.2 智能DNS场景实现 1.3.3 生产场景配置示例 1. ...
 - python 日志 logging模块详解
			
1.基本使用 配置logging基本的设置,然后在控制台输出日志, import logging logging.basicConfig(level=logging.INFO, format='%(a ...
 - docker之docker-compose
			
docker-compose就是个二进制的工具,它可以单机编排,批量管理多个容器 [root@mcwk8s01 harbor]# file /usr/local/bin/docker-compose ...
 - 将自己喜欢的网页保存为单个文件包括图片(mhtml文件)
			
from selenium import webdriver driver = webdriver.Chrome(r'C:\chromedriver_win32\chromedriver.exe') ...
 - vue我自己的动态菜单思路
			
1.在router里把所有的路由都加上. 2.后端存储路由path和其他设计需要的信息. 3.登录后,后端返回菜单树,根据权限不同,返回的菜单不同,并且还要返回每个path代表的页面具有的权限数组.可 ...
 - 详解RocketMQ消息存储原理
			
本文基于RocketMQ 4.6.0进行源码分析 一. 存储概要设计 RocketMQ存储的文件主要包括CommitLog文件.ConsumeQueue文件.Index文件.RocketMQ将所有to ...
 - 平衡二叉树(AVL)插入结点后的再平衡思路
			
理解平衡二叉树 在解决平衡二叉树动平衡问题,我们先来明确什么是平衡二叉树: 平衡二叉树是二叉搜索树的一种特殊情况,所以在二叉搜索树的基础上加上了如下定义: 平衡因子:我们将二叉树中各个结点的左右子树的 ...