高通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, &reg},
+ {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的更多相关文章

  1. 高通lk屏幕向kernel传参

    LK把相关参数报存到cmdline上: 在Bootable\bootloader\lk\dev\gcdb\display\gcdb_display_param.c上gcdb_display_cmdli ...

  2. 高通(QCOM)sensor bring up

    高通7150平台 1.添加驱动文件 2.添加编译 3.配置json文件 4.高通默认配置 5.部分sensor外挂电源 6.遇到的问题 1.添加驱动文件 路径:adsp_proc/ssc/sensor ...

  3. 高通spi 屏幕 -lk代码分析

    lk SPI驱动 1. 初始化时钟 在lk中,我们是从kmain开始执行下来的,而执行顺序则是先初始化时钟,也就是在platform_early_init函数中开始执行的: 在这里我们需要修改这个函数 ...

  4. 高通APQ8074 spi 接口配置

    高通APQ8074 spi 接口配置 8074 平台含有两个BLSP(BAM Low-Speed Peripheral) , 每一个BLSP含有两个QUP, 每一个QUP可以被配置为I2C, SPI, ...

  5. 【转】高通平台android 环境配置编译及开发经验总结

    原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...

  6. 高通移植mipi LCD的过程LK代码

    lk部分:(实现LCD兼容) 1. 函数定位 aboot_init()来到target_display_init(): 这就是高通原生lk LCD 兼容的关键所在.至于你需要兼容多少LCD 就在whi ...

  7. 最新内核3.4)Linux 设备树加载I2C client adapter 的流程(内核3.4 高通)【转】

    转自:https://blog.csdn.net/lsn946803746/article/details/52515225 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转 ...

  8. 高通平台msm8909 LK 实现LCD 兼容

    前段时间小米出现红米note2 换屏门,现在我们公司也要上演了:有两个供应商提供不同IC 的LCD panel. 软件区分的办法是读取LCD IC 的ID 寄存器,下面解析高通平台LK中LCD兼容的过 ...

  9. 高通平台 lcd driver 调试小结

    一.概述 1.1 简介 本文档主要包括LCD模块的驱动流程分析.Framebuffer相关知识.Gralloc等相关内容,以及LCD调试的一些经验和相关bug的分析和讲解. 1.2  开发环境 And ...

  10. Linux加载DTS设备节点的过程(以高通8974平台为例)

    DTS是Device Tree Source的缩写,用来描述设备的硬件细节.在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码, ...

随机推荐

  1. 二进制安装多master节点的k8s集群(2)

    1.环境准备 k8s集群角色 IP 主机名 安装的组件 控制节点 192.168.1.10 master apiserver.controller-manager.scheduler.etcd.doc ...

  2. mosquitto的安装与使用

      一款实现了消息推送协议 MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,比如现在应用广泛的低功耗传感器,手机.嵌入式 ...

  3. webpack调优技巧

    webpack优化主要有三个方面:1.提高构建速度,2.减少打包体积,3.优化用户体验 提高构建速度: 启用多线程 thread-loader 使用thread-loader插件可以启用多线程进行构建 ...

  4. CF1800F Dasha and Nightmares

    F.Dasha and Nightmares 题意:\(n\) 个字符串 \(s_i\),问有多少对不同的 \((i, j) \ (1 \le i \le j \le n)\),使得 \(s_i\) ...

  5. JUC并发编程学习笔记(一)认知进程和线程

    进程和线程 进程 一个程序,如QQ.exe,是程序的集合 一个进程往往可以包含多个线程,至少包含一个 java默认有两个线程,GC垃圾回收线程和Main线程 线程:一个进程中的各个功能 java无法真 ...

  6. 一、Doris演进史

    Apache Doris -- 为分析而生 Doris发展历程: Doris发展比较重要的关键节点与事件 #2008 - Doris1 :「筑巢引凤」的重要基石 早年,百度最主要的收入来源是广告.广告 ...

  7. 如何阅读 Paper

    前言 论文(Paper)通常是新技术.算法.编程方法或软件工具的首次公布.通过阅读论文,我们可以了解最新的技术进展,保持自己的技能和知识是最新的. 同时,论文提供了对特定主题深入理解的机会.它们通常包 ...

  8. google账户配置foxmail和使用foxmail

    最近想把邮件分门别类,创建一些个人文件夹,更好的筛选邮件,可以尝试使用foxmail 1. 如果你有google账户,在配置foxmail之前需打开google账户的安全设置 https://myac ...

  9. 3种方法实现图片瀑布流的效果(纯JS,Jquery,CSS)

    最近在慕课网上听如何实现瀑布流的效果:介绍了3种方法. 1.纯JS代码实现: HTML代码部分: <!DOCTYPE html> <html> <head> < ...

  10. 关于SQL数据库Varchar字符串类型长度设计问题(转载)

    为什么要合理的设计数据库字段数据类型的长度?个人观点:一个是降低物理上的存储空间,一个是提高数据库的处理速度,还有一个附带功能是能校验数据是否合法.   现代数据库一般都支持CHAR与VARCHAR字 ...