当前位置:网站首页>Qcom--lk phase I2C interface configuration scheme -i2c6
Qcom--lk phase I2C interface configuration scheme -i2c6
2022-06-25 06:44:00 【Ah @ potato】
In the project I2C6 The corresponding gpio The mouth is 22 and 23
The following information can be determined from the above table :
a) QUP ID:BLSP6
b) QUP BASE Addr:7AF6000
c) IRQ:300
d) src clk:clk_gcc_blsp2_qup2_i2c_apps_clk
1、 Qualcomm in lk Stage already exists I2C Initialization code
route :bootable/bootloader/lk/platform/msm_shard/i2c_qup.c

In the initialization code qup_blsp_i2c_init by i2c The interface function , Two important functions are called gpio_config_blsp_i2c and clock_config_blsp_i2c, for i2c Of gpio And the clock clock Set up ,BLSP_QUP_IRQ This macro is used to assign values to interrupt numbers .
2、 Add interrupt number definition code :
diff --git a/platform/msm8952/include/platform/irqs.h b/platform/msm8952/include/platform/irqs.h
index 59408bd87..388be802a 100644
--- a/platform/msm8952/include/platform/irqs.h
+++ b/platform/msm8952/include/platform/irqs.h
@@ -60,6 +60,7 @@
#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + \
NR_BOARD_IRQS)
-
+//#define BLSP_QUP_IRQ(blsp_id, qup_id) (GIC_SPI_START + 101 + qup_id)
+#define BLSP_QUP_IRQ(blsp_id, qup_id) (GIC_SPI_START + 95 + (blsp_id-1)*204 + qup_id)
#define SMD_IRQ (GIC_SPI_START + 168)
#endif /* __IRQS_MSM8952_H */
among GIC_SPI_START For an offset ,blsp_id by 2,qup_id by 1, That is, the interrupt number is 300
3、I2C Call... On initialization gpio And clock configuration functions are added as follows
gpio Set file to add function code :
diff --git a/platform/msm8952/gpio.c b/platform/msm8952/gpio.c
old mode 100644
new mode 100755
index 05b4977ec..72a3f6919
--- a/platform/msm8952/gpio.c
+++ b/platform/msm8952/gpio.c
@@ -70,3 +70,46 @@ void gpio_config_uart_dm(uint8_t id)
gpio_tlmm_config(4, 2, GPIO_OUTPUT, GPIO_NO_PULL,
GPIO_8MA, GPIO_DISABLE);
}
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
+{
+ if(blsp_id == BLSP_ID_1) {
+ switch (qup_id) {
+ case QUP_ID_1:
+ /* configure I2C SDA gpio */
+ gpio_tlmm_config(6, 3, GPIO_OUTPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+
+ /* configure I2C SCL gpio */
+ gpio_tlmm_config(7, 3, GPIO_OUTPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+ break;
+ case QUP_ID_3:
+ /* configure I2C SDA gpio */
+ gpio_tlmm_config(14, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+
+ /* configure I2C SCL gpio */
+ gpio_tlmm_config(15, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+ break;
+ default:
+ dprintf(CRITICAL, "Incorrect QUP id %d\n",qup_id);
+ ASSERT(0);
+ }
+ } else if (blsp_id == BLSP_ID_2){
+ switch (qup_id) {
+ case QUP_ID_1:
+ gpio_tlmm_config(22, 3, GPIO_OUTPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+ gpio_tlmm_config(23, 3, GPIO_OUTPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+ break;
+ default:
+ dprintf(CRITICAL, "Incorrect QUP id %d\n",qup_id);
+ ASSERT(0);
+ }
+ } else {
+ dprintf(CRITICAL, "Incorrect BLSP id %d\n",blsp_id);
+ ASSERT(0);
+ }
+}
\ No newline at end of file
diff --git a/platform/msm8952/include/platform/gpio.h b/platform/msm8952/include/platform/gpio.h
index b4d12e818..4d4dcd1cf 100644
--- a/platform/msm8952/include/platform/gpio.h
+++ b/platform/msm8952/include/platform/gpio.h
@@ -69,4 +69,5 @@ void gpio_tlmm_config(uint32_t gpio,
uint8_t pull,
uint8_t drvstr,
uint32_t enable);
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);
#endif
Add function code to the clock setting file :
diff --git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
old mode 100644
new mode 100755
index 9efe09b4f..7c9315ba2
--- a/platform/msm8952/acpuclock.c
+++ b/platform/msm8952/acpuclock.c
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include
#define MAX_LOOPS 500
@@ -507,3 +508,86 @@ void clock_config_ce(uint8_t instance)
clock_ce_enable(instance);
}
+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(((qup_id != QUP_ID_1) && (qup_id != QUP_ID_3))) {
+ dprintf(CRITICAL, "Incorrect BLSP-%d or QUP-%d configuration\n", blsp_id, qup_id);
+ ASSERT(0);
+ }
+ if(blsp_id == BLSP_ID_1){
+ if (qup_id == QUP_ID_1) {
+ snprintf(clk_name, sizeof(clk_name), "blsp1_qup2_ahb_iface_clk");
+ }
+ else if (qup_id == QUP_ID_3) {
+ snprintf(clk_name, sizeof(clk_name), "blsp1_qup4_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;
+ }
+
+ if (qup_id == QUP_ID_1) {
+ snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup2_i2c_apps_clk");
+ }
+ else if (qup_id == QUP_ID_3) {
+ snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup4_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;
+ }
+ } else if (blsp_id == BLSP_ID_2){
+ if (qup_id == QUP_ID_1) {
+ snprintf(clk_name, sizeof(clk_name), "blsp2_qup2_ahb_iface_clk");
+ }
+ else if (qup_id == QUP_ID_3) {
+ snprintf(clk_name, sizeof(clk_name), "blsp2_qup4_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;
+ }
+
+ if (qup_id == QUP_ID_1) {
+ snprintf(clk_name, sizeof(clk_name), "gcc_blsp2_qup2_i2c_apps_clk");
+ }
+ else if (qup_id == QUP_ID_3) {
+ snprintf(clk_name, sizeof(clk_name), "gcc_blsp2_qup4_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;
+ }
+ }
+}
diff --git a/platform/msm8952/include/platform/clock.h b/platform/msm8952/include/platform/clock.h
index e6734cb27..cbd1ba46f 100644
--- a/platform/msm8952/include/platform/clock.h
+++ b/platform/msm8952/include/platform/clock.h
@@ -99,4 +99,5 @@ void gcc_dsi_hs_clocks_enable(uint32_t flags, bool use_dsi1_pll, uint8_t pclk0_
uint8_t pclk0_n, uint8_t pclk0_d);
void gcc_dsi_lp_clock_enable(uint32_t flags);
void gcc_dsi_clocks_disable(uint32_t flags);
+void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);
#endif
Add clock configuration and sequence , Three clock related structures are added
diff --git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
old mode 100644
new mode 100755
index 85d506987..f9bebfe9f
--- a/platform/msm8952/msm8952-clock.c
+++ b/platform/msm8952/msm8952-clock.c
@@ -206,6 +206,19 @@ static struct rcg_clk sdcc1_apps_clk_src =
},
};
+/* BLSP2_QUP2 Clocks */
+static struct clk_freq_tbl ftbl_gcc_blsp1_qup2_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,gpll0,1,0,0),
+ F(25000000,gpll0,16,1,2),
+ F(50000000,gpll0,16,0,0),
+ F_END
+};
+
static struct branch_clk gcc_sdcc1_apps_clk =
{
.cbcr_reg = (uint32_t *) SDCC1_APPS_CBCR,
@@ -594,6 +607,37 @@ static struct vote_clk gcc_ce1_axi_clk = {
},
};
+static struct vote_clk gcc_blsp2_ahb_clk = {
+ .cbcr_reg = (uint32_t *) BLSP2_AHB_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(20),
+
+ .c = {
+ .dbg_name = "gcc_blsp2_ahb_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+static struct rcg_clk gcc_blsp2_qup2_i2c_apps_clk_src =
+{
+ .cmd_reg = (uint32_t *) GCC_BLSP2_QUP2_CMD_RCGR,
+ .cfg_reg = (uint32_t *) GCC_BLSP2_QUP2_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_blsp2_qup2_i2c_apps_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+static struct branch_clk gcc_blsp2_qup2_i2c_apps_clk = {
+ .cbcr_reg = (uint32_t *) GCC_BLSP2_QUP2_APPS_CBCR,
+ .parent = &gcc_blsp2_qup2_i2c_apps_clk_src.c,
+ .c = {
+ .dbg_name = "gcc_blsp2_qup2_i2c_apps_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
Add the following function code to the clock lookup list :
/* Clock lookup table */
static struct clk_lookup msm_clocks_8952[] =
{
@@ -621,6 +665,9 @@ static struct clk_lookup msm_clocks_8952[] =
CLK_LOOKUP("ce1_axi_clk", gcc_ce1_axi_clk.c),
CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
CLK_LOOKUP("ce1_src_clk", ce1_clk_src.c),
+ CLK_LOOKUP("blsp2_qup2_ahb_iface_clk", gcc_blsp2_ahb_clk.c),
+ CLK_LOOKUP("gcc_blsp2_qup2_i2c_apps_clk_src", gcc_blsp2_qup2_i2c_apps_clk_src.c),
+ CLK_LOOKUP("gcc_blsp2_qup2_i2c_apps_clk", gcc_blsp2_qup2_i2c_apps_clk.c),
};
void msm8956_clock_override()
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index c64acf027..57f833189 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -634,6 +634,7 @@ DEFINES += DISPLAY_NONE_LK_MENU=1
$(LOCAL_DIR)/crypto_hash.o \
$(LOCAL_DIR)/crypto5_eng.o \
$(LOCAL_DIR)/crypto5_wrapper.o \
+ $(LOCAL_DIR)/i2c_qup.o \
$(LOCAL_DIR)/mdp5.o \
$(LOCAL_DIR)/display.o \
$(LOCAL_DIR)/mipi_dsi.o \
To configure I2C Clock parameters for :
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
old mode 100644
new mode 100755
index 057d909f2..3e016fcff
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -101,6 +101,15 @@
#define GCC_CRYPTO_CBCR (CLK_CTL_BASE + 0x1601C)
#define GCC_CRYPTO_AXI_CBCR (CLK_CTL_BASE + 0x16020)
#define GCC_CRYPTO_AHB_CBCR (CLK_CTL_BASE + 0x16024)
+#define BLSP_QUP_BASE(blsp_id, qup_id) ((blsp_id == 1) ? (PERIPH_SS_BASE + 0xB5000 \
+ + (qup_id * 0x1000)) :\
+ (PERIPH_SS_BASE + 0x2f5000 + \
+ (qup_id * 0x1000)))
+
+#define BLSP2_AHB_CBCR (CLK_CTL_BASE + 0xB008) //0x0B008
+#define GCC_BLSP2_QUP2_APPS_CBCR (CLK_CTL_BASE + 0xD010)
+#define GCC_BLSP2_QUP2_CFG_RCGR (CLK_CTL_BASE + 0xD004)
+#define GCC_BLSP2_QUP2_CMD_RCGR (CLK_CTL_BASE + 0xD000)
4、 add to I2C The test program
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 16717dee5..87375893e 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -95,6 +95,12 @@
#include
#include
#include "fastboot_test.h"
+#include
+#include
+#include
+#include
+#include
+#include
extern bool target_use_signed_kernel(void);
extern void platform_uninit(void);
@@ -326,6 +332,8 @@ struct getvar_partition_info {
#define EXT_MAGIC_OFFSET_SB 0x38
#define F2FS_MAGIC 0xF2F52010 // F2FS Magic Number
#define F2FS_MAGIC_OFFSET_SB 0x0
+#define EXTERNCHG_SLAVE_ADDR 0x3b
+#define EXTERNCHG_I2C_VOLTAGE 0x08
typedef enum fs_signature_type {
EXT_FS_SIGNATURE = 1,
@@ -372,6 +380,79 @@ extern int emmc_recovery_init(void);
extern int fastboot_trigger(void);
#endif
+static struct qup_i2c_dev *i2c_dev;
+int externchg_lk_i2c_read(uint8_t addr, uint8_t *reg, uint8_t *buf, uint8_t len)
+{
+ if (!buf)
+ return ERR_INVALID_ARGS;
+ if(!i2c_dev)
+ return ERR_NOT_VALID;
+ struct i2c_msg rd_buf[] = {
+ {addr, I2C_M_WR, 1, reg},
+ {addr, I2C_M_RD, len, buf}
+ };
+ dprintf(CRITICAL, "#### qup_i2c_xfer\n");
+ int err = qup_i2c_xfer(i2c_dev, rd_buf, 2);
+
+ if (err < 0) {
+ dprintf(CRITICAL, "Read reg %x failed err %d\n", *reg,err);
+ return err;
+ }
+ return NO_ERROR;
+}
+
+int externchg_lk_adapter_present(void)
+{
+ unsigned char buf;
+ unsigned char register_addr = EXTERNCHG_I2C_VOLTAGE;
+ unsigned char slave_addr = EXTERNCHG_SLAVE_ADDR;
+ int ret=-1;
+
+ if(!i2c_dev) {
+ return ERR_NOT_VALID;
+ }
+ ret = externchg_lk_i2c_read(slave_addr, ister_addr, &buf, 1);
+ if(ret < 0) {
+ dprintf(CRITICAL, "read externchg adapter_present error\n");
+ return ret;
+ }
+ dprintf(CRITICAL, "#### read reg[0x8]=%x\n",buf);
+ return (buf && 0x04) ? 0 : -1;
+}
+int externchg_lk_read_voltage(void)
+{
+ return target_get_battery_voltage();
+}
+
+void check_low_batt_start_system(void){
+ uint32_t is_batt_volt = 0;
+ uint32_t cutoff_volt = 3600000;
+
+ i2c_dev = qup_blsp_i2c_init(BLSP_ID_2, QUP_ID_1, 100000, 19200000);
+ is_batt_volt = externchg_lk_read_voltage();
+ if(is_batt_volt < cutoff_volt) {
+ dprintf(CRITICAL,"low battery(%d),forbidy boot\n",is_batt_volt);
+ mdelay(20);
+ //display_image_on_screen();
+ /* Determine whether the charger is inserted , If yes, pre charge , If not, turn it off
+ * externchg_lk_adapter_present();
+ */
+ if(!externchg_lk_adapter_present()){
+ // Charge IC initialization
+ while(is_batt_volt < cutoff_volt){
+ dprintf(CRITICAL, "charging: batt_volt =%d\n",is_batt_volt);
+ mdelay(1000);
+ is_batt_volt = externchg_lk_read_voltage();
+ }
+ }else {
+ shutdown_device();
+ }
+
+ }else{
+ dprintf(CRITICAL,"not low-volt battery(%d)\n",is_batt_volt);
+ }
+}
+
void target_get_pmic_info(char *pmic_info)
{
dprintf(INFO, "PMIC 0 is %d\n", board_pmic_target(0));
@@ -632,8 +713,9 @@ unsigned char *update_cmdline(const char * cmdline)
cmdline_len += strlen(loglevel);
} else if (boot_reason_alarm) {
cmdline_len += strlen(alarmboot_cmdline);
- } else if ((target_build_variant_user() || device.charger_screen_enabled)
- && target_pause_for_battery_charge() && !boot_into_recovery) {
+ } else if (!externchg_lk_adapter_present()){
+ //} else if ((target_build_variant_user() || device.charger_screen_enabled)
+ // && target_pause_for_battery_charge() && !boot_into_recovery) {
pause_at_bootup = 1;
cmdline_len += strlen(battchg_pause);
}
@@ -964,6 +1046,7 @@ unsigned char *update_cmdline(const char * cmdline)
if (have_cmdline) --dst;
while ((*dst++ = *src++));
} else if (pause_at_bootup) {
+ dprintf(INFO, "#### enter poweroff `charger\n");
src = battchg_pause;
if (have_cmdline) --dst;
while ((*dst++ = *src++));
@@ -5427,6 +5510,7 @@ retry_boot:
goto fastboot;
}
+ check_low_batt_start_system();
boot_err_type = boot_linux_from_mmc();
switch (boot_err_type)
{
边栏推荐
- Unity获取资源路径
- Cs8126t 3.1w mono ultra low EMI unfiltered class D audio power amplifier IC
- In depth inventory: 23 vscode plug-in artifacts that improve development efficiency and aesthetics
- ACWING2013. 三条线
- [ros2] Why use ros2? Introduction to ros2 system characteristics
- Face++ realizes face detection by flow
- Fastadmin cascade clear data
- Cs4344/ht5010 stereo d/a digital to analog converter
- Sleep quality today 67 points
- Bcrypt password encryption kalrry
猜你喜欢

Uncaught TypeError: Cannot read properties of undefined (reading ‘prototype‘)

Flask 的入门级使用

DNS domain name system

Hongmeng learning notes: creating layouts using XML

Cs8683 (120W mono class D power amplifier IC)

Keil debug view variable prompt not in scope

Query process of MySQL secondary index

How to realize hierarchical management of application and hardware in embedded projects

The process of making wooden barrels with 3DMAX software: a three-step process

How two hosts in different network segments directly connected communicate
随机推荐
Analysis of China's food cold chain logistics, output of quick-frozen noodles and rice products and operation of major enterprises in 2021 [figure]
Power representation in go language
燕京啤酒何以至此?
Cs8683 (120W mono class D power amplifier IC)
'how do I create an enumeration with constant values in rust?'- How can I create enums with constant values in Rust?
sin(a+b)=sina*cosb+sinb*cosa的推导过程
Are you still doing the dishes yourself? Teach you how to make dishwasher controller with single chip microcomputer
[learn FPGA programming from scratch -43]: vision chapter - technology evolution of chip design in the post Moore era -2- evolution direction
[轻松学会shell编程]-5、计划任务
Is the number of indexes in a table the more the better?
mysql 表查询json数据
Viewing Chinese science and technology from the Winter Olympics (V): the Internet of things
Uncaught TypeError: Cannot read properties of undefined (reading ‘prototype‘)
joda.time获取日期总结
R & D thinking 07 - embedded intelligent product safety certification required
How to find happiness in programming and get lasting motivation?
CTFHub-Web-信息泄露-目录遍历
Missing libgmp-10 dll - libgmp-10. dll is missing
Ht8513 single lithium battery power supply with built-in Dynamic Synchronous Boost 5W mono audio power amplifier IC solution
How to realize the stable output of 3.3v/3.6v (1.2-5v) voltage of lithium battery by using the voltage rise and fall chip cs5517