高通--PMIC修改(三)

前面的两篇PMIC相关的文章大概讲解了之前遇到的问题,目前又遇到PMIC相关的问题,又与之前的不一样,因此再做一次补充

之前我是通过修改pm.dtsi与在xbl阶段现有的功能内进行补充修改。但是出现一个问题就是我们目前的pm.dtsi修改对于一些gpio不生效,再记录一下这个解决问题的过程

首先,XBL内的PMIC的初始化入口函数为boot/QcomPkg/Drivers/PmicDxe/Pmic.c内的PmicInitialize初始化函数。这个初始化函数是由boot/QcomPkg/Drivers/PmicDxe/PmicDxeLa.inf内的ENTRY_POINT                 = PmicInitialize属性决定的,

这个入口定义与abl内的相似。abl阶段的入口函数也是由LinuxLoader.inf内的

ENTRY_POINT                    = LinuxLoaderEntry决定的

确定完入口后,就是进行各种各样的初始化

  /* Initialize the PMIC Library */
  err_flag = pm_init();

  if (err_flag == PM_ERR_FLAG_SUCCESS)
  {
    err_flag = pm_pmicdxe_init(ImageHandle, SystemTable);
  }
  else if (err_flag == PM_ERR_FLAG_FAILURE)
  {
    /*PMIC not detected*/
    err_flag = pm_pmicdxe_init_stubs(ImageHandle, SystemTable);
  }
  else
  {
    err_flag = PM_ERR_FLAG_FAILURE;
  }

pm_init内做的就只是一个赋值返回操作,这个可以不管

pm_err_flag_type pm_init( void )
{
  pm_err_flag_type err_flag = PM_ERR_FLAG_SUCCESS;
  return err_flag;
}

由pm_init返回的err_flag的值为SUCCESS,就确定我们是走

err_flag = pm_pmicdxe_init(ImageHandle, SystemTable);这个逻辑

pm_pmicdxe_init内主要是进行PWRKEY的下压检查,跟了一下代码发现就是解析设备树然后检查PWRKEY。pm_uefi_exit_init内就是进行两个事件的初始化,这个也与我们无关。

pm_post_pmic_initialization内则有平台注释,以及提供一个pm_comm_wirte_byte api,那么就尝试使用一下,首先看看这个api的三个参数表达什么意思

pm_err_flag_type pm_post_pmic_initialization(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
  pm_err_flag_type err_flag = PM_ERR_FLAG_SUCCESS;

  /*
    PON peripheral interrupts are routed to Master PMIC such that PBS can receive PON interrupts.
    Once UEFI boot reaches the point of pwr key hold check function, after the check passes,
    it needs to change the PON MID back to MSM which is 0 so that APPS can resume receiving the interrupts.
    INT is disabled at the UEFI exit. CR - 2157004
    */
   //commenting below one since it can't be written from UEFI anymore
 // err_flag = pm_comm_write_byte(PMICA_SLAVE_ID_0, PON_INT_MID_SEL_REG, INT_MID_0_VAL);

  err_flag |= pm_dead_battery_status_check();

  err_flag |= pm_i2c_sid_config();
  return err_flag;
}

第一个slave_id应该是表示我们使用的是PMIC A还是B这些,我们使用的是B所以slave_id设置为1,addr表示寄存器的地址,我们以PMIC_B GPIO 5为例子,那么就是0x8C,由于我们要进行拉高拉低操作,因此addr = 0x8C42,第三个data参照

0x0: PULLUP_30UA
0x1: PULLUP_1P5UA
0x2: PULLUP_31P5UA
0x3: PULLUP_1P5UA_30UA_BOOST
0x4: PULLDOWN_10UA
0x5: NO_PULL
0x6: RESERVED6
0x7: RESERVED7

那么data=0x4。因此我们的pm_comm_write_byte的参数应该是(1,0x8C42,0x4)

pm_err_flag_type pm_comm_write_byte(uint32 slave_id, uint16 addr, uint8 data)
{
  return pm_comm_write_byte_ex(0, slave_id, addr, data);
}

然后编译验证即可。但是验证过程又出现xbl阶段dump,对于GPIO操作出现的各种报错,要么是我们的参数写错,要么就是权限问题。这里我们假设参数是PASS的,再去看看这个GPIO 6的默认权限是啥。

在PMIC/pm_spmi_config.c内有各个GPIO的权限,我们看到这里是写着ADSP的,所以就修改为

 //{0, 3, 0x8C, SPMI_OWNER_ADSP,    SPMI_OWNER_ADSP},   /* GPIO05 Type-C Connector Insertion */
 {0, 3, 0x8C, SPMI_OWNER_ADSP,    SPMI_OWNER_APPS},

再次编译验证,发现还是失败。查阅一下文档,还有一个地方可以修改权限:PMIC/access.dtsi

那么就是在这个dtsi内进行GPIO5的权限修改

 apps = <
      /*BUSID SLAVEID PERIPH OPERATION */
      //PM_BUSID_0 1 0x89 REMOVE            /* example to remove*/
        PM_BUSID_0 1 0x8c APPEND
    >;

再次编译验证,终于pass。

Ps:验证XBL内的GPIO的操作相较于直接修改kernel内的GPIO是比较麻烦的,因为如果想要通过sys/kernel/debug/gpio进行cat查看的话,前者的修改可能会被后者的修改覆盖。那么对于XBL阶段的GPIO验证方法,我个人目前使用以下三种方法进行验证:

1.直接通过万用表、示波器查看。

2.查看kernel内是否有使用这个GPIO,没有的话直接cat sys/kernel/debug/gpio

3.如果2里面大面积的使用这个GPIO的话,那么建议直接在ABL阶段进行这个GPIO的状态判断(比较麻烦,需要写逻辑)

以上就是最近遇到的PMIC GPIO的问题。如有问题,欢迎大佬指正

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值