3.1、修改aboot.c文件:
修改/bootable/bootloader/lk/app/aboot/aboot.c,增加:
+#include
+#include
#include
extern int get_target_boot_params(const char *cmdline, const char *part,
char **buf);
+static struct qup_i2c_dev *i2c_dev;
void *info_buf;
} 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 (/*(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);
}
+static int blsp_i2c_read_reg(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data)
+{
+ int ret = 0;
+
+ struct i2c_msg msg_buf[] = {
+ {i2c_addr, I2C_M_WR, 1, ®_addr},
+ {i2c_addr, I2C_M_RD, 1, reg_data}
+ };
+
+ ret = qup_i2c_xfer(i2c_dev, msg_buf, 2);
+ if (ret < 0) {
+ dprintf(CRITICAL, "qup_i2c_xfer read error %d, slave addr: %02x\n",
+ ret, i2c_addr);
+ return ret;
+ }
+
+ return ret;
+}
+static int cw_read_word(uint8_t i2c_addr, uint8_t reg_addr, unsigned char buf[])
+{
+ int ret = 0;
+
+ struct i2c_msg msg_buf[] = {
+ {i2c_addr, I2C_M_WR, 1, ®_addr},
+ {i2c_addr, I2C_M_RD, 1, buf}
+ };
+
+ ret = qup_i2c_xfer(i2c_dev, msg_buf, 2);
+ if (ret < 0) {
+ dprintf(CRITICAL, "qup_i2c_xfer read error %d, slave addr: %02x\n",
+ ret, i2c_addr);
+ return ret;
+ }
+
+ return ret;
+}
+static int blsp_i2c_write_reg(uint8_t i2c_addr, uint8_t reg_addr, uint8_t reg_data)
+{
+ int ret = 0;
+ uint8_t buf[2];
+
+ buf[0] = reg_addr;
+ buf[1] = reg_data;
+
+ struct i2c_msg msg_buf[] = {
+ {i2c_addr, I2C_M_WR, sizeof(buf), buf},
+ };
+
+ ret = qup_i2c_xfer(i2c_dev, msg_buf, 1);
+ if (ret < 0) {
+ dprintf(CRITICAL, "qup_i2c_xfer write error %d, slave addr: %02x\n",
+ ret, i2c_addr);
+ return ret;
+ }
+
+ return ret;
+}
+
+static void battery_voltage_check_loop(void)
+{
+ int ret;
+ uint8_t reg_vbat = 0x02;
+// uint8_t reg_adc_convert = 0x02;
+ uint8_t adc_convert;
+ uint32_t vbat_voltage, power_on_voltage = 3500;
+ unsigned char vbat[2] = {0 , 0};
+ gpio_tlmm_config(2, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);
+// gpio_tlmm_config(138, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);
+ gpio_set_dir(2, 0); // enable charge chip enable
+// gpio_set_dir(138, 2); // connect usb dpdm to sc60 module
+
+ i2c_dev = qup_blsp_i2c_init(BLSP_ID_1, QUP_ID_1, 100000, 19200000);
+/* ret = blsp_i2c_read_reg(0x6B, reg_chip_id, &chip_id);
+ if (ret < 0 || ((chip_id >> 3) & 15) != 2) {
+ dprintf(CRITICAL, "get ba25890 chip id failed\n");
+ return;
+ }
+ // reset chip
+ ret = blsp_i2c_write_reg(0x6B, reg_chip_id, 0x80);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "reset chip failed\n");
+ return;
+ }
+ thread_sleep(100);
+ ret = blsp_i2c_read_reg(0x6B, reg_wdt, &wdt);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "get wdt reg failed\n");
+ return;
+ }
+ wdt &= ~(3 << 4);
+ ret = blsp_i2c_write_reg(0x6B, reg_wdt, wdt);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "disable wdt failed\n");
+ return;
+ }
+ ret = blsp_i2c_read_reg(0x6B, reg_sysmin, &sysmin);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "get sysmin reg failed\n");
+ return;
+ }
+ sysmin &= ~(7 << 1);
+ sysmin |= (6 << 1);
+ ret = blsp_i2c_write_reg(0x6B, reg_sysmin, sysmin);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "set sysmin reg failed\n");
+ return;
+ }*/
+/*
+ ret = blsp_i2c_read_reg(0x6B, reg_adc_convert, &adc_convert);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "get adc convert reg failed\n");
+ return;
+ }
+ adc_convert |= 3 << 6;
+ ret = blsp_i2c_write_reg(0x6B, reg_adc_convert, adc_convert);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "enable adc convert failed\n");
+ return;
+ }
+*/ // wait adc start convert
+ thread_sleep(100);
+ while (1) {
+ ret = blsp_i2c_write_reg(0x62, 0x0A, 0x00);
+ ret = blsp_i2c_read_reg(0x62, 0x0A, &adc_convert);
+ dprintf(CRITICAL, "star %x\n", adc_convert);
+ ret = cw_read_word(0x62, reg_vbat, vbat);
+ if (ret < 0) {
+ dprintf(CRITICAL, "get vbat reg failed\n");
+ break;
+ }
+ /* ret = blsp_i2c_read_reg(0x6B, reg_charger_online, &charger_online);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "get charger_online reg failed\n");
+ break;
+ }*/
+ // charger_online = (charger_online >> 2) & 1;
+ vbat_voltage =(vbat[0] << 8) + vbat[1];
+ vbat_voltage = vbat_voltage * 625 / 2048;//* 5 / 16;
+ // if charger online, decrease 50mV from battery voltage
+ // if (charger_online)
+ // vbat_voltage -= 50;
+ dprintf(CRITICAL, "battery voltage %d\n", vbat_voltage);
+ // if battery is absent, ntc will report cold, boot into android
+ if (vbat_voltage >= power_on_voltage)
+ break; // exit battery voltage check
+ else {
+ // sleep 1 minute, then recheck battery voltage
+ /* if (charger_online)
+ {
+ dprintf(CRITICAL, "battery voltage too low, charging\n");
+ thread_sleep(3000);
+ }*/
+ // else {
+ dprintf(CRITICAL, "battery voltage too low, shutdown device\n");
+ /* ret = blsp_i2c_write_reg(0x6B, 0x0B, 0x80);
+ if (ret < 0) { // any error will exit battery voltage check
+ dprintf(CRITICAL, "reset chip failed\n");
+ break;
+ }*/
+ shutdown_device();
+ // }
+ }
+ }
+}
3.2、修改acpuclock.c:
修改/bootable/bootloader/lk/platform/msm8953/acpuclock.c,增加:
#include
+#include
#define MAX_LOOPS 500
+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;
+
+ snprintf(clk_name, sizeof(clk_name), "blsp1_ahb_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_qup2_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