• LK是little kernel的缩写
  • 高通平台android普遍采用LK作为其bootloader,LK是一个开源项目。但是,LK只是整个系统的引导部分,所以它不是独立存在。LK是一个功能极其强大的bootloader,但只支持arm和x86平台。
  • LK的一个显著的特点就是它实现了一个简单的线程机制(thread),和对高通处理器的深度定制和使用。

一、LK部分代码修改

开机电压检测,关机充电使能
1.1、bootable/bootloader/lk/app/aboot/aboot.c

#include <display_menu.h>#include "fastboot_test.h"+#include <i2c_qup.h>
+#include <blsp_qup.h>
+static struct qup_i2c_dev *i2c_dev;void *info_buf;void write_device_info_mmc(device_info *dev);
     } 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, &reg_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 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_sysmin = 0x03;uint8_t reg_wdt = 0x07;uint8_t reg_chip_id = 0x14;uint8_t reg_vbat = 0x0E;uint8_t reg_charger_online = 0x0B;uint8_t reg_adc_convert = 0x02;uint8_t chip_id, sysmin, wdt, adc_convert, vbat, charger_online;uint32_t vbat_voltage, power_on_voltage = 3500;gpio_tlmm_config(2, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);//gpio_tlmm_config(137, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);gpio_set_dir(2, 0); // enable charge chip enable//gpio_set_dir(137, 2); // connect usb dpdm to sc60 modulei2c_dev = qup_blsp_i2c_init(BLSP_ID_1, QUP_ID_2, 100000, 19200000);thread_sleep(100);ret = blsp_i2c_read_reg(0x6A, reg_chip_id, &chip_id);if (ret < 0 || ((chip_id >> 3) & 7) != 3) {dprintf(CRITICAL, "get ba25890 chip id failed\n");return;}// reset chipret = blsp_i2c_write_reg(0x6A, 0x14, 0x80);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "reset chip failed\n");return;}thread_sleep(100);ret = blsp_i2c_read_reg(0x6A, reg_wdt, &wdt);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "get wdt reg failed\n");return;}wdt &= ~(3 << 4);ret = blsp_i2c_write_reg(0x6A, reg_wdt, wdt);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "disable wdt failed\n");return;}ret = blsp_i2c_read_reg(0x6A, reg_sysmin, &sysmin);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "get sysmin reg failed\n");return;}sysmin &= ~(7 << 1);ret = blsp_i2c_write_reg(0x6A, reg_sysmin, sysmin);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "set sysmin reg failed\n");return;}ret = blsp_i2c_read_reg(0x6A, reg_adc_convert, &adc_convert);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "get adc convert reg failed\n");return;}adc_convert |= 3 << 6;ret = blsp_i2c_write_reg(0x6A, reg_adc_convert, adc_convert);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "enable adc convert failed\n");return;}// wait adc start convertthread_sleep(100);while (1) {ret = blsp_i2c_read_reg(0x6A, reg_vbat, &vbat);if (ret < 0) {dprintf(CRITICAL, "get vbat reg failed\n");break;}ret = blsp_i2c_read_reg(0x6A, reg_charger_online, &charger_online);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "get charger_online reg failed\n");break;}charger_online = (charger_online >> 2) & 1;vbat_voltage = 2304 + (vbat & 0x7f) * 20;// if charger online, decrease 50mV from battery voltageif (charger_online)vbat_voltage -= 50;dprintf(CRITICAL, "battery voltage %d\n", vbat_voltage);// if battery is absent, ntc will report cold, boot into androidif (vbat_voltage >= power_on_voltage)break; // exit battery voltage checkelse {// sleep 1 minute, then recheck battery voltageif (charger_online)thread_sleep(3000);else {dprintf(CRITICAL, "battery voltage too low, shutdown device\n");ret = blsp_i2c_write_reg(0x6A, 0x14, 0x80);if (ret < 0) { // any error will exit battery voltage checkdprintf(CRITICAL, "reset chip failed\n");break;}shutdown_device();}}}
}

以下文件关于 I2C-2 使能
1.2、bootable/bootloader/lk/platform/msm8953/acpuclock.c

 #include <clock.h>#include <platform/clock.h>#include <platform.h>
+#include <blsp_qup.h>
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_qup3_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;}
}

1.3、bootable/bootloader/lk/platform/msm8953/gpio.c

+
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
+{+  /* configure I2C SDA gpio */
+  gpio_tlmm_config(10, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+      GPIO_2MA, GPIO_DISABLE);
+
+  /* configure I2C SCL gpio */
+  gpio_tlmm_config(11, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+      GPIO_2MA, GPIO_DISABLE);
+}
+

1.4、bootable/bootloader/lk/platform/msm8953/include/platform/clock.h

 void clock_usb30_init(void);void clock_reset_usb_phy();
+void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);#endif

1.5、bootable/bootloader/lk/platform/msm8953/include/platform/gpio.h

 void gpio_config_uart_dm(uint8_t id);
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);uint32_t gpio_status(uint32_t gpio);

1.6、bootable/bootloader/lk/platform/msm8953/include/platform/iomap.h

 #define USB2_PHY_SEL                       0x01937000#define QUSB2_PHY_BASE                     0X79000+#define BLSP_QUP_BASE(blsp_id, qup_id)     (PERIPH_SS_BASE + 0xB5000 + 0x1000 * qup_id)
+#define GCC_BLSP1_QUP3_APPS_CBCR           (CLK_CTL_BASE + 0x04020)
+#define GCC_BLSP1_QUP3_CMD_RCGR           (CLK_CTL_BASE + 0x04000)
+#define GCC_BLSP1_QUP3_CFG_RCGR           (CLK_CTL_BASE + 0x04004)/* SS QMP (Qulacomm Multi Protocol) */#define QMP_PHY_BASE                0x78000

1.7、bootable/bootloader/lk/platform/msm8953/include/platform/irqs.h

 #define SMD_IRQ                                (GIC_SPI_START + 168)+#define BLSP_QUP_IRQ(blsp_id, qup_id)          (GIC_SPI_START + 95 + qup_id)#endif /* __IRQS_MSM8953_H */

1.8、bootable/bootloader/lk/platform/msm8953/msm8953-clock.c

/* I2C Clocks */
static struct clk_freq_tbl ftbl_gcc_blsp1_qup3_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 rcg_clk gcc_blsp1_qup3_i2c_apps_clk_src =
{.cmd_reg      = (uint32_t *) GCC_BLSP1_QUP3_CMD_RCGR,.cfg_reg      = (uint32_t *) GCC_BLSP1_QUP3_CFG_RCGR,.set_rate     = clock_lib2_rcg_set_rate_hid,.freq_tbl     = ftbl_gcc_blsp1_qup3_i2c_apps_clk_src,.current_freq = &rcg_dummy_freq,.c = {.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk_src",.ops      = &clk_ops_rcg,},
};static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {.cbcr_reg = (uint32_t *)GCC_BLSP1_QUP3_APPS_CBCR,.parent   = &gcc_blsp1_qup3_i2c_apps_clk_src.c,.c = {.dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",.ops      = &clk_ops_branch,},
};/* UART Clocks */
static struct clk_lookup msm_clocks_8953[] =
{CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),CLK_LOOKUP("ce1_src_clk",  ce1_clk_src.c),+    CLK_LOOKUP("blsp1_ahb_clk", gcc_blsp1_ahb_clk.c),
+  CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk_src", gcc_blsp1_qup3_i2c_apps_clk_src.c),
+  CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk", gcc_blsp1_qup3_i2c_apps_clk.c),
};

1.9、bootable/bootloader/lk/platform/msm_shared/rules.mk

             $(LOCAL_DIR)/mipi_dsc.o \$(LOCAL_DIR)/mipi_dsi_phy.o \
+          $(LOCAL_DIR)/i2c_qup.o \$(LOCAL_DIR)/mipi_dsi_autopll_thulium.oendif

二、sys目录权限添加

2.1、device/qcom/sepolicy/vendor/msm8953/genfs_contexts

 #PMI pathgenfscon sysfs /devices/soc/qpnp-haptic-24/leds/vibrator u:object_r:sysfs_leds:s0genfscon sysfs /devices/soc/qpnp-vadc-14/usbin u:object_r:sysfs_battery_supply:s0+genfscon sysfs /devices/platform/soc/78b7000.i2c/i2c-3/3-0062/power_supply/bms u:object_r:sysfs_battery_supply:s0
+genfscon sysfs /devices/platform/soc/78b7000.i2c/i2c-3/3-006a/power_supply/pc_port u:object_r:sysfs_battery_supply:s0
+genfscon sysfs /devices/platform/soc/78b7000.i2c/i2c-3/3-006a/power_supply/usb u:object_r:sysfs_usb_supply:s0
+genfscon sysfs /devices/platform/soc/78b7000.i2c/i2c-3/3-006a/power_supply/main u:object_r:sysfs_usb_supply:s0

三、kernel内核驱动

3.1、添加 ChargerIC 和电量计配置
/kernel/msm-4.9/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi

 bq25890: bq25890@6a {compatible = "ti,bq25890";reg = <0x6a>;ti,otg-charge = <1>;ti,otg-sw-supply = <&pm8953_l5>;ti,charge-enable-gpio = <&tlmm 2 0x00>;ti,interrupt-gpio = <&tlmm 137 0x00>;pinctrl-names = "default";pinctrl-0 = <&bq25980_gpio_default>;};cw2015: cw2015@62 {compatible = "cellwise,cw2015";reg = <0x62>;};

3.2、配置 ChargerIC 中断脚
kernel/msm-4.9/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi

bq25980_gpio_default: bq25980_gpio_default {mux {pins = "gpio137";function = "gpio";};config {pins = "gpio137";drive-strength = <2>;bias-pull-up;};};

3.3、配置编译宏开关
kernel/msm-4.9/arch/arm64/configs/msm8953_defconfig

 CONFIG_CRYPTO_CRC32_ARM64=yCONFIG_QMI_ENCDEC=yCONFIG_KEYBOARD_TCA8418=y
+CONFIG_CHARGER_BQ25890=y
+CONFIG_BATTERY_CW2015=y

3.4、配置编译宏开关
kernel/msm-4.9/drivers/power/supply/Makefile

 obj-$(CONFIG_CHARGER_BQ24735)   += bq24735-charger.oobj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o
+obj-$(CONFIG_BATTERY_CW2015)  += cw2015_battery.oobj-$(CONFIG_CHARGER_SMB347)   += smb347-charger.oobj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o

3.5、ChargerIC 驱动
kernel/msm-4.9/drivers/power/supply/bq25890_charger.c
3.6、电量计驱动
kernel/msm-4.9/drivers/power/supply/xxxx_battery.c

四、关机充电显示电量百分比

4.1、/system/core/healthd/healthd_draw.cpp

#define STR_LEN 8
void HealthdDraw::draw_percent(const animation* anim) {int cur_level = anim->cur_level;if (anim->cur_status == BATTERY_STATUS_FULL) {cur_level = 100;}if (cur_level <= 0) return;const animation::text_field& field = anim->text_percent;if (field.font == nullptr || field.font->char_width == 0 ||field.font->char_height == 0) {char cap_str[STR_LEN];int x, y;int str_len_px;static int char_height = -1, char_width = -1;if (char_height == -1 && char_width == -1)gr_font_size(gr_sys_font(), &char_width, &char_height);snprintf(cap_str, (STR_LEN - 1), "%d%%", cur_level);str_len_px = gr_measure(gr_sys_font(), cap_str);x = (gr_fb_width() - str_len_px) / 2;y = (gr_fb_height() + char_height) / 2;gr_color(0xa4, 0xc6, 0x39, 255);gr_text(gr_sys_font(), x, y, cap_str, 0);LOGE("draw_percent use default\n");} else {std::string str = base::StringPrintf("%d%%", cur_level);int x, y;determine_xy(field, str.size(), &x, &y);LOGV("drawing percent %s %d %d\n", str.c_str(), x, y);gr_color(field.color_r, field.color_g, field.color_b, field.color_a);draw_text(field.font, x, y, str.c_str());}
}

充电IC和电量计的驱动调试相关推荐

  1. android电池(五):电池 充电IC(PM2301)驱动分析篇

    android电池(五):电池 充电IC(PM2301)驱动分析篇 关键词:android 电池  电量计  PL2301任务初始化宏 power_supply 中断线程化 平台信息: 内核:linu ...

  2. android电池(五):电池 充电IC(PM2301)驱动分析篇【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/8970363 android充电这块,有的电源管理芯片内部包含充电管理,如s5pv210 ...

  3. 【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

    关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply 平台信息: 内核:linux2.6/linux3.0 系统:android/android4.0  ...

  4. 高通平台power_supply 框架下添加第三方充电IC的驱动方法

    1.power_supply电源框架介绍: power supply framework在kernel/drivers/power/下.内核抽象出来power supply子系统为驱动提供了统一的框架 ...

  5. PD快充 - fusb302驱动调试笔记

    一.fusb302介绍 Fusb302是可编程的USB Type-C控制器,支持识别各种USB 设备和对应的状态;且支持最高100W的PD协议. Fusb302用CC1/CC2引脚与typeC电源适配 ...

  6. max17040C语言,电池 电量计(MAX17040)驱动分析篇

    关键词:android 电池  电量计  MAX17040 任务初始化宏power_supply 平台信息: 内核:linux2.6/linux3.0 系统:android/android4.0 平台 ...

  7. TOREX | 如何延长设备的电池寿命?——充电IC

    适用于支持无线电力传输的锂离子电池 XC6810系列是用于锂离子电池的超小型充电IC,适用于小型的可穿戴设备.可听设备和物联网设备.具有充放电控制.无线供电支持等多种功能. 充电电流为1mA~25mA ...

  8. 全志A64触摸屏驱动调试

    一.前言 linux的触摸屏驱动一般要经历一下几个步骤(以4412为例):1.移植驱动到linux源码"driver/input/touchscreen/"目录下,在Kconfig ...

  9. linux 设备树 otg,linux下充电IC OTG设备供电控制

    linux下充电IC OTG设备供电控制 备注:下面提到的充电IC 用charger表示 1.     OTG VBUS 5V供电 接入OTG设备,比如U盘,具体是怎么通过charger驱动来给U盘供 ...

最新文章

  1. 如何解决:“ UnicodeDecodeError:#39;ascii#39;编解码器无法解码字节”
  2. Xamarin iOS编写第一个应用程序创建工程
  3. 学妹问H哥:你是如何平衡工作和生活的?
  4. php显示玩家,php.取得玩家IP
  5. vscode 经过跳板机,连接到内网服务器
  6. Sum of Log(2020上海C)
  7. 计算机硬件系统的构成教学设计,2.1 计算机硬件系统教学设计思路
  8. 软考中级-软件设计师涉及的知识点和笔记
  9. ThinkPHP自动匹配CP端移动端模板
  10. 中外互免签证协定一览表(普通护照与公务普通护照)
  11. asciidoc_如何使用AsciiDoc创建博客
  12. AP微观经济学课程知识点总结
  13. Python 实时盯盘并在股价突破时通过微信通知(tushare的使用)
  14. JAVA MemCache 史无前例的详细讲解!看完包精通MEMCACHE!
  15. Linux下pl与ps端的通信,Overlay设计方法篇之第四章PS与PL的交互
  16. 确定账号登录和密码确认
  17. 解决问题:onreadystatechange只触发一次
  18. c语言建立二维坐标,C语言 坐标移动详解及实例代码
  19. 联想微型计算机启动项的键,联想电脑如何设置u盘启动项
  20. ERP服务器端安装及配置

热门文章

  1. 外盘期货策略|9月17日美原油期货日内操盘策略
  2. 冒烟测试(smoke test)、可用性测试(sanity test)和回归测试(regression test)
  3. iOS 送审浅谈:1.4.1、2.1、2.5.2、2.5.4、4.2.3、5.2.5
  4. 虚拟机san存储服务器,VMware SAN介绍
  5. html5的基本工作原理,HTML5基础开发教程
  6. 点阵字python_Python点阵字玩转动态歌词
  7. 京东容器集群建设之路
  8. Python爬虫实战四 | 盘搜搜1.2-网盘搜索神器开源
  9. 【十二】Python全栈之路--推导式_生成器
  10. 爬虫实战 | 爬取东方财富网股票数据