Platform: ROCKCHIP
OS: Android 6.0
Kernel: 3.10.92

由于电池部分是用户空间Service从另外一颗MCU获取,而Android需要显示电量,
所以按照电池驱动框架做了一个伪电池驱动, 主要是使用它的充电状态和电池电量
这两个property, 代码如下:

/* drivers/power/rk3288_battery.c
 *
 * Power supply driver for the rk3288
 *
 * Copyright (C) 2008 Google, Inc.
 * Author: kris.fei<kris_fei@126.com>
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/module.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/of.h>
#include <linux/of_device.h>

//#define DEBUG

struct rk3288_battery_data {
    int status;
    int health;
    int present;
    int capacity;

struct power_supply battery;
};

static struct rk3288_battery_data *battery_data;

static enum power_supply_property rk3288_battery_props[] = {
    POWER_SUPPLY_PROP_STATUS,
    POWER_SUPPLY_PROP_HEALTH,
    POWER_SUPPLY_PROP_PRESENT,
    POWER_SUPPLY_PROP_TECHNOLOGY,
    POWER_SUPPLY_PROP_CAPACITY,
};

static int rk3288_battery_get_property(struct power_supply *psy,
                 enum power_supply_property psp,
                 union power_supply_propval *val)
{
    struct rk3288_battery_data *data = container_of(psy,
        struct rk3288_battery_data, battery);
    int ret = 0;

#ifdef DEBUG
    printk("%s : property: %d \n", __func__, psp);
#endif

switch (psp) {
    case POWER_SUPPLY_PROP_STATUS:
        val->intval = data->status;
        break;
    case POWER_SUPPLY_PROP_HEALTH:
        val->intval = data->health ;
        break;
    case POWER_SUPPLY_PROP_PRESENT:
        val->intval = data->present ;
        break;
    case POWER_SUPPLY_PROP_TECHNOLOGY:
        val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
        break;
    case POWER_SUPPLY_PROP_CAPACITY:
        val->intval = data->capacity ;
        break;
    default:
        ret = -EINVAL;
        break;
    }

return ret;
}

static int rk3288_battery_set_property(struct power_supply *psy,
            enum power_supply_property psp,
            const union power_supply_propval *val)
{
    struct rk3288_battery_data *data = container_of(psy,
        struct rk3288_battery_data, battery);
    int ret = 0;
    int value = val->intval;

#ifdef DEBUG
    printk("%s :psp:%d val:%d\n", __func__, psp, value);
#endif

switch (psp) {
    case POWER_SUPPLY_PROP_STATUS:
        if (value <= POWER_SUPPLY_STATUS_FULL) {
            data->status =value;
        } else {
            printk("Unreasonable value:%d\n", value);
            ret = 1;
        }
        break;
    case POWER_SUPPLY_PROP_HEALTH:
        if (value <= POWER_SUPPLY_HEALTH_COLD) {
            data->health = value;
        } else {
            printk("Unreasonable value:%d\n", value);
            ret = 1;
        }
        break;
    case POWER_SUPPLY_PROP_PRESENT:
        data->present = value;
        break;
    case POWER_SUPPLY_PROP_CAPACITY:
        //Capacity from 0 to 100.
        if (value > 0 && value <= 100) {
            data->capacity = value;
        } else {
            printk("Unreasonable value:%d\n", value);
            ret = 1;
        }
        break;
    default:
        ret = -EINVAL;
        break;
    }

//Send uevent.
    power_supply_changed(&battery_data->battery);

return ret;
}

static int rk3288_battery_is_writeable(struct power_supply *psy,
                 enum power_supply_property psp)
{
    switch (psp) {
    //Need to be written from medusa service.
    case POWER_SUPPLY_PROP_CAPACITY:
    case POWER_SUPPLY_PROP_STATUS:
    case POWER_SUPPLY_PROP_PRESENT:
    case POWER_SUPPLY_PROP_HEALTH:
        return 1;

default:
        break;
    }

return 0;
}

static int rk3288_battery_probe(struct platform_device *pdev)
{
    int ret;
    struct rk3288_battery_data *data;

data = kzalloc(sizeof(*data), GFP_KERNEL);
    if (data == NULL) {
        ret = -ENOMEM;
        goto err_data_alloc_failed;
    }

data->battery.properties = rk3288_battery_props;
    data->battery.num_properties = ARRAY_SIZE(rk3288_battery_props);
    data->battery.get_property = rk3288_battery_get_property;
    data->battery.name = "battery";
    data->battery.type = POWER_SUPPLY_TYPE_BATTERY;
    data->battery.set_property = rk3288_battery_set_property;
    data->battery.property_is_writeable = rk3288_battery_is_writeable;

data->present = 1;    //Present
    data->status = POWER_SUPPLY_STATUS_UNKNOWN;
    data->health = POWER_SUPPLY_HEALTH_GOOD;
    data ->capacity = 1;

ret = power_supply_register(&pdev->dev, &data->battery);
    if (ret)
        goto err_battery_failed;

platform_set_drvdata(pdev, data);
    battery_data = data;

return 0;

err_battery_failed:
    kfree(data);
err_data_alloc_failed:
    return ret;
}

static int rk3288_battery_remove(struct platform_device *pdev)
{
    struct rk3288_battery_data *data = platform_get_drvdata(pdev);

power_supply_unregister(&data->battery);

kfree(data);
    battery_data = NULL;
    return 0;
}

static const struct of_device_id rk3288_battery[] = {
    { .compatible = "rk3288,battery" },
    { /* Sentinel */ }
};

static struct platform_driver rk3288_battery_driver = {
    .probe        = rk3288_battery_probe,
    .remove        = rk3288_battery_remove,
    .driver = {
        .owner = THIS_MODULE,
        .name = "rk3288-battery",
        .of_match_table = of_match_ptr(rk3288_battery),
    }
};

static int __init rk3288_battery_init(void)
{
    return platform_driver_register(&rk3288_battery_driver);
}

static void __exit rk3288_battery_exit(void)
{
    platform_driver_unregister(&rk3288_battery_driver);
}

module_init(rk3288_battery_init);
module_exit(rk3288_battery_exit);

MODULE_AUTHOR("kris.fei");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Battery driver");

[RK3288][Android6.0] 调试笔记 --- 伪电池驱动添加相关推荐

  1. gpio驱动广播Android,[RK3288][Android6.0] 调试笔记 --- 通用GPIO驱动控制LED【转】

    Platform: ROCKCHIP OS: Android 6.0 Kernel: 3.10.92 由于板子没有lcd无法得知sd卡升级是否完成,因此使用LED显示. Recovery中升级完成后控 ...

  2. [RK3288][Android6.0] 调试笔记 --- WiFi芯片AP6356S添加

    Platform: RK3288 OS: Android 6.0 Kernel: 3.10.92 背景: RK3288 Android6.0平台对AP6356S的支持不是很完善,直接修改wifi ch ...

  3. [RK3288][Android6.0] 调试笔记 --- 电池电量一直显示100%

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 之前文章[RK3288][Android6.0] 调试笔记 - 伪电池驱动添加 阐述了如何添加一个 ...

  4. [RK3288][Android6.0] 调试笔记 --- touch无法获取坐标点

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 有网友遇到调试touch的时候能触发中断,但无法获取坐标点 具体可参考文章 [RK3288][An ...

  5. [RK3288][Android6.0] 调试笔记 --- AndroidTool低格无效问题

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 现象: 之前文章 [RK3288][Android6.0] 调试笔记 - AndroidTool两 ...

  6. [RK3288][Android6.0] 调试笔记 --- 双屏显示内核Patch

    Platform: RK3288 OS: Android 6.0 Kernel: 3.10.92 根据5.1的双屏显示patch,在android6.0上修改了下,因为没硬件环境,所以未经验证,仅供参 ...

  7. [RK3288][Android6.0] 调试笔记 --- 调试串口的更换

    Platform: ROCKCHIP OS: Android 6.0 Kernel: 3.10.92 假设项目有需求要将调试串口uart2 改成 uart1, 改动如下 (还未验证,先分享给大家,有问 ...

  8. [RK3288][Android6.0] 调试笔记 --- GPU DVFS的控制开关

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 GPU的DVFS不是在dts而是在驱动中直接控制并且默认打开的. DVFS控制核心函数是mali_ ...

  9. [RK3288][Android6.0] 调试笔记 --- RT5640的ctl name列表

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 Codec: RT5640 在查看录音通路的ctl config列表时发现有找不到的ctrl na ...

最新文章

  1. java版msn_强!Java实现MSN Messenger聊天
  2. 【深度学习笔记】关键点检测——标签(Ground Truth)构建
  3. 网站推广——网站推广专员浅析企业网站验收和交付要注意哪些问题
  4. 适合初学者快速入门的Numpy实战全集
  5. java实现登陆面试题_【Javaweb】笔面试题 ---(1)(示例代码)
  6. TIMING_02 浅谈时序约束与时序分析
  7. ANSI C and Microsoft C++中常用的预定义宏以及 宏定义中 # 和 ## 的区别
  8. 字节跳动也取消大小周了,996内卷要终结了?
  9. 铁粉看进来,surprise|湾区人工智能
  10. android获取错误原因,从http读取数据时发生OutOfMemory错误获取请求android
  11. 初学者如何学习NLP?这里有一些最棒的项目推荐
  12. 善领dsa android正式版,善领DSA Android(安卓)正式版
  13. vs 设置起始页不见了_VS2015,为什么模板不见了,请教
  14. android killer java,记录Android Killer反编译时遇到的异常
  15. python3d动图_如何在Python上制作3D图形的动画
  16. CF1320E Treeland and Viruses
  17. 100个精选Python实战项目案例,送给缺乏练手经验的你
  18. 实现表单form提交前进行确认提示 表单提交 确认对话框
  19. 信息系统项目管理师考前如何备考
  20. Guava Futures异步回调机制源码解析

热门文章

  1. java 分割一个_分割java
  2. 跨不同导向序列的Cas9结合和切割的定量描绘了靶接合的前景
  3. 微信小程序如何打开网页
  4. 好消息,发现一款知网学术不端论文检测查重助手,永久免费分享给大家使用
  5. rust有准星_Rust 流程控制
  6. wetool个人版_wetool企业版下载安装社群运营管理工具
  7. 计算机网络基础知识合集
  8. ABTEST平台建设思路与方案
  9. 职称计算机选那几科,考职称计算机哪几科容易考?
  10. QBASIC在win8-64位系统中的编译及运行