当前位置:首页 > 芯闻号 > 充电吧
[导读]作者: arunboy在原有展讯平台下面的bq25601的基础上编写mtk平台下的bq25601代码,参考mtk平台下的.并进行相关调试. 充电IC的移植是在kernel和lk里面,lk里面是mt_b

作者: arunboy

在原有展讯平台下面的bq25601的基础上编写mtk平台下的bq25601代码,参考mtk平台下的.并进行相关调试.
充电IC的移植是在kernel和lk里面,lk里面是mt_battery.c中调用了以下几个函数

#if defined(MTK_BQ25601_SUPPORT)
    bq25601_hw_init();
    bq25601_charging_enable(bEnable);
    bq25601_dump_register();
#endif

kernel里面在power/mt6735/Makefile中

ifeq ($(CONFIG_MTK_BQ25601_SUPPORT),y)
                    obj-$(CONFIG_MTK_SMART_BATTERY) += bq25601.o charging_hw_bq25601.o

首先参考两个代码新建了一个文件,把一些接口函数进行了替换.然后查看数据手册修改数组,寄存器的值.

图中的数组都是查看数据手册然后进行填充,下面那些使用字母的因为在别的文件中定义了数字.

电池充电有三个阶段:预充电阶段,恒流充电,恒压充电.
预充电阶段:设置充电电流一般为500mA以下
恒流充电阶段:电压一般在3.2~4.1v左右,充电器的输入电压会越来越高
恒压充电阶段:4.2v左右,充电ic输出电压不变,电流逐渐减小.

驱动代码分析

1.bq25601.c

/**********************************************************
  *
  *   [I2C Slave Setting]
  *
  *********************************************************/
#define bq25601_SLAVE_ADDR_WRITE   0xD6//根据数据手册i2c的地址是0x6b,左移一位以后得到0xd6
#define bq25601_SLAVE_ADDR_READ    0xD7

static struct i2c_client *new_client;
static const struct i2c_device_id bq25601_i2c_id[] = { {"bq25601", 0}, {} };

kal_bool chargin_hw_init_done = KAL_FALSE;
static int bq25601_driver_probe(struct i2c_client *client, const struct i2c_device_id *id);

#ifdef CONFIG_OF
static const struct of_device_id bq25601_of_match[] = {
    {.compatible = "bq25601",},
    {},
};

MODULE_DEVICE_TABLE(of, bq25601_of_match);
#endif

static struct i2c_driver bq25601_driver = {
    .driver = {
           .name = "bq25601",
#ifdef CONFIG_OF
           .of_match_table = bq25601_of_match,
#endif
           },
    .probe = bq25601_driver_probe,
    .id_table = bq25601_i2c_id,
};

2.charging_hw_bq25601.c

//充电的一些初始化的值,根据数据手册的某个寄存的的某位代表的什么意思进行设值.
static unsigned int charging_hw_init(void *data)
{
    unsigned int status = STATUS_OK;
    battery_log(BAT_LOG_CRTI, "charging_hw_init!n");
    bq25601_set_en_hiz(0x0);
    bq25601_set_vindpm(0x8);    /* VIN DPM check 4.70V */
    //bq25601_set_vindpm(0x0);
    bq25601_set_reg_rst(0x0);
    bq25601_set_wdt_rst(0x1);   /* Kick watchdog */
    bq25601_set_sys_min(0x5);   /* Minimum system voltage 3.5V */
    bq25601_set_iprechg(0x7);   /* Precharge current 480mA */
    bq25601_set_iterm(0x1); /* Termination current 120mA */

    bq25601_set_vreg(0x0B); /* VREG 4.208V */

    bq25601_set_min_vbat_sel(0x0);  /* BATLOWV 2.8V */
    bq25601_set_vrechg(0x0);    /* VRECHG 0.1V (4.108V) */
    bq25601_set_en_term(0x1);   /* Enable termination */
    bq25601_set_watchdog(0x1);  /* WDT 40s */
    bq25601_set_en_timer(0x0);  /* Disable charge timer */
    bq25601_set_vindpm_int(0x0);    /* Disable fault vindpm interrupt */
    bq25601_set_iindpm_int(0x0);    /* Disable fault iindpm interrupt */
    bq25601_set_ovp(0x3);
    return status;
}

然后把这几个函数进行填充完整就行,根据项目需求,有的不需要.

charging_func[CHARGING_CMD_INIT] = charging_hw_init;
        charging_func[CHARGING_CMD_DUMP_REGISTER] = charging_dump_register;
        charging_func[CHARGING_CMD_ENABLE] = charging_enable;
        charging_func[CHARGING_CMD_SET_CV_VOLTAGE] = charging_set_cv_voltage;
        charging_func[CHARGING_CMD_GET_CURRENT] = charging_get_current;
        charging_func[CHARGING_CMD_SET_CURRENT] = charging_set_current;
        charging_func[CHARGING_CMD_SET_INPUT_CURRENT] = charging_set_input_current;
        charging_func[CHARGING_CMD_GET_CHARGING_STATUS] =  charging_get_charging_status;
        charging_func[CHARGING_CMD_RESET_WATCH_DOG_TIMER] = charging_reset_watch_dog_timer;
        charging_func[CHARGING_CMD_SET_HV_THRESHOLD] = charging_set_hv_threshold;
        charging_func[CHARGING_CMD_GET_HV_STATUS] = charging_get_hv_status;
        charging_func[CHARGING_CMD_GET_BATTERY_STATUS] = charging_get_battery_status;
        charging_func[CHARGING_CMD_GET_CHARGER_DET_STATUS] = charging_get_charger_det_status;
        charging_func[CHARGING_CMD_GET_CHARGER_TYPE] = charging_get_charger_type;
        charging_func[CHARGING_CMD_SET_PLATFORM_RESET] = charging_set_platform_reset;
        charging_func[CHARGING_CMD_GET_PLATFORM_BOOT_MODE] = charging_get_platform_boot_mode;
        charging_func[CHARGING_CMD_SET_POWER_OFF] = charging_set_power_off;
        charging_func[CHARGING_CMD_SET_TA_CURRENT_PATTERN] = charging_set_ta_current_pattern;
        charging_func[CHARGING_CMD_SET_ERROR_STATE] = charging_set_error_state;
        charging_func[CHARGING_CMD_DISO_INIT] = charging_diso_init;
        charging_func[CHARGING_CMD_GET_DISO_STATE] = charging_get_diso_state;
        charging_func[CHARGING_CMD_SET_VBUS_OVP_EN] = charging_set_vbus_ovp_en;
        charging_func[CHARGING_CMD_SET_VINDPM] = charging_set_vindpm;

主要记录两个函数,i2c的读写数据的函数:

int bq25601_read_byte(unsigned char cmd, unsigned char *returnData)
{
    char cmd_buf[1] = { 0x00 };
    char readData = 0;
    int ret = 0;

    mutex_lock(&bq25601_i2c_access);

    /* new_client->addr = ((new_client->addr) & I2C_MASK_FLAG) | I2C_WR_FLAG; */
    new_client->ext_flag =
        ((new_client->ext_flag) & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_DIRECTION_FLAG;

    cmd_buf[0] = cmd;
    ret = i2c_master_send(new_client, &cmd_buf[0], (1 << 8 | 1));
    if (ret < 0) {
        /* new_client->addr = new_client->addr & I2C_MASK_FLAG; */
        new_client->ext_flag = 0;

        mutex_unlock(&bq25601_i2c_access);
        return 0;
    }

    readData = cmd_buf[0];
    *returnData = readData;

    /* new_client->addr = new_client->addr & I2C_MASK_FLAG; */
    new_client->ext_flag = 0;

    mutex_unlock(&bq25601_i2c_access);
    return 1;
}

int bq25601_write_byte(unsigned char cmd, unsigned char writeData)
{
    char write_data[2] = { 0 };
    int ret = 0;

    mutex_lock(&bq25601_i2c_access);

    write_data[0] = cmd;
    write_data[1] = writeData;

    new_client->ext_flag = ((new_client->ext_flag) & I2C_MASK_FLAG) | I2C_DIRECTION_FLAG;

    ret = i2c_master_send(new_client, write_data, 2);
    if (ret < 0) {
        new_client->ext_flag = 0;
        mutex_unlock(&bq25601_i2c_access);
        return 0;
    }

    new_client->ext_flag = 0;
    mutex_unlock(&bq25601_i2c_access);
    return 1;
}

3.对于lk里面,就是实现   bq25601_hw_init(),bq25601_charging_enable(bEnable),bq25601_dump_register()这三个函数,基本上和kernel里面的差不多.
4.参考数据手册几个有关充电IC的参数
Termination Current     截止电流,一般设置为200mA以下
Charge Voltage              充电IC的输出电压
Precharge current          预充电电流,一般设置为500mA以下
VAG OVP 最高电压,bq25601可以支持到14v
Absolute VINDPM Threshold 充电IC的最高输出

总结

编写调试驱动代码一定要认真,特别注意宏定义,加上了没,有没有把以前的宏定义注释掉,而且要查看一下有没有在Makefile,Kconfig中添加修改,报错的话要看错误提示,然后去查错误类型,有的报的这个地方的错误但是错误不在这个文件当中.
kernel-3.18/arch/arm64/boot/dts/project_bat_setting.dtsi可以配置电池曲线,充电属性等相关配置.注意还有一个电阻值的配置,如果与硬件不匹配,会导致误差较大.

问题

pmic检测充电器状态不对,改用了通过读取充电IC的寄存器的状态来判断是否在充电.查寻datasheet后可以看到在REG08里面读取.

添加如下检测代码:

    stat = bq25601_get_vbus_stat();
    if (stat == 0x1 || stat == 0x2)
        val = KAL_TRUE;
    else
        val = KAL_FALSE;

充电IC的配置

1 device下面的配置
2 kernel 里面的config和dts(i2c地址)   PS:尽量保证user版和debug版一块修改.
3 lk里面的config
4 preloader里面的config  
END

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

  现在深圳产业链消息人士爆料称,代号武松的MTK 28nm双核处理器6572即将开始量产,最快5月份大家就能见到搭载该平台的终端了。   消息人士透露称,除了双核版本外,MT6572还

关键字: mtk 28nm mt6572

  我们从英特尔、高通、联发科等芯片大商的动作就可以看出智能穿戴产业的火爆程度, 不仅仅国际大厂纷纷推出智能平台与针对智能穿戴的元器件、产品与服务,越来越多的电子信息行业以外的厂商也都积极跨界可

关键字: mtk 可穿戴设备 物联网

  移动互联网时代已经来临,伴随其而来的智能穿戴物联网设备技术也日新月异,作为国内首屈一指的一个聚积物联网时代的智能穿戴及智能硬件高度专业的平台——深圳穿戴物联网设备技术

关键字: mtk 智能硬件 智能穿戴

  如今智能手机芯片市场竞争日趋激烈,各个厂商都在推出新品,各家都号称自己的产品如何优秀,那么我们应该如何分辨智能手机芯片的优劣,应该如何选择适合自己的产品呢。   一、手机芯

关键字: 8890 exynos mtk 骁龙820 麒麟955 x25

移动设备发展缓慢,让SoC大厂联发科和高通寻找更好的增长市场,物联网和汽车电子成为他们的下一个目标。 物联网商机惊人,促使两大手机芯片龙头厂商大厂纷纷跨界淘金到其他领域,例如联发科便宣布

关键字: mtk 汽车电子 物联网

自2015年起,北上广深等一线城市的街边,陆续出现了很多漆着统一色彩图案的橙色,黄色,蓝色,绿色的自行车,“共享单车”这个词语也随之应运而生。使用者只需通过智能手机的Ap

关键字: 2017iot大会 mtk NB-IoT 共享单车

在MWC 2018上,联发科不仅展示了最新一代智能手机芯片平台曦力P60,5G不同频段的产品进程及规划,联发科技总经理陈冠州更首次带队MWC,向包括集微网在内的媒体讲述了联发科未来1年、3年甚至

关键字: 5G 5g商用 mtk 物联网

3月7日消息,联发科技与腾讯游戏双方共同宣布成立联合创新实验室,围绕手机游戏及其他互娱产品的开发与优化达成战略合作。 双方将充分发挥各自在软硬件方面的互补优势,深化协同创新,基于联发科技

关键字: AI mtk 腾讯

什么是搭载电流通路功能的锂离子电池充电IC?它有什么作用?特瑞仕半导体株式会社(日本东京都中央区 董事总经理:芝宫 孝司 第二东京证券交易所:6616) 开发了搭载了电流通路功能、用于1节锂离子/聚合物2次电池(以下称锂...

关键字: 充电ic 电流通路 锂离子

充电ic必不可少,缺少充电ic,移动设备将无法正常运转。对于充电ic,在往期文章中已做诸多分析。为增进大家对充电ic的了解,本文将更为深入地解析充电ic相关内容。如果你对充电ic具有一定兴趣,不妨阅读下文对于充电ic动态...

关键字: 充电ic 指数 动态路径
关闭
关闭