/*
* linux/drivers/power/s3c6410_battery.c
*
* Battery measurement code for S3C6410 platform.
*
* based on palmtx_battery.c
*
* Copyright (C) 2009 Samsung Electronics.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/power_supply.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/irq.h>
#include <linux/wakelock.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <plat/gpio-cfg.h>
#include "s3c6410_battery.h"
static struct wake_lock vbus_wake_lock;
/* Prototypes */
extern int s3c_adc_get_adc_data(int channel);
static ssize_t s3c_bat_show_property(struct device *dev,
struct device_attribute *attr,
char *buf);
static ssize_t s3c_bat_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count);
#define FAKE_BAT_LEVEL 80
static struct device *dev;
static int s3c_battery_initial;
static int force_update;
static char *status_text[] = {
[POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown",
[POWER_SUPPLY_STATUS_CHARGING] = "Charging",
[POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
[POWER_SUPPLY_STATUS_NOT_CHARGING] = "Not Charging",
[POWER_SUPPLY_STATUS_FULL] = "Full",
};
typedef enum {
CHARGER_BATTERY = 0,
CHARGER_USB,
CHARGER_AC,
CHARGER_DISCHARGE
} charger_type_t;
struct battery_info {
u32 batt_id; /* Battery ID from ADC */
u32 batt_vol; /* Battery voltage from ADC */
u32 batt_vol_adc; /* Battery ADC value */
u32 batt_vol_adc_cal; /* Battery ADC value (calibrated)*/
u32 batt_temp; /* Battery Temperature (C) from ADC */
u32 batt_temp_adc; /* Battery Temperature ADC value */
u32 batt_temp_adc_cal; /* Battery Temperature ADC value (calibrated) */
u32 batt_current; /* Battery current from ADC */
u32 level; /* formula */
u32 charging_source; /* 0: no cable, 1:usb, 2:AC */
u32 charging_enabled; /* 0: Disable, 1: Enable */
u32 batt_health; /* Battery Health (Authority) */
u32 batt_is_full; /* 0 : Not full 1: Full */
};
/* lock to protect the battery info */
static DEFINE_MUTEX(work_lock);
struct s3c_battery_info {
int present;
int polling;
unsigned long polling_interval;
struct battery_info bat_info;
};
static struct s3c_battery_info s3c_bat_info;
static int s3c_get_bat_level(struct power_supply *bat_ps)
{
return FAKE_BAT_LEVEL;
}
static int s3c_get_bat_vol(struct power_supply *bat_ps)
{
int bat_vol = 0;
return bat_vol;
}
static u32 s3c_get_bat_health(void)
{
return s3c_bat_info.bat_info.batt_health;
}
static int s3c_get_bat_temp(struct power_supply *bat_ps)
{
int temp = 0;
return temp;
}
static int s3c_bat_get_charging_status(void)
{
charger_type_t charger = CHARGER_BATTERY;
int ret = 0;
charger = s3c_bat_info.bat_info.charging_source;
switch (charger) {
case CHARGER_BATTERY:
ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
break;
case CHARGER_USB:
case CHARGER_AC:
if (s3c_bat_info.bat_info.level == 100
&& s3c_bat_info.bat_info.batt_is_full) {
ret = POWER_SUPPLY_STATUS_FULL;
}else {
ret = POWER_SUPPLY_STATUS_CHARGING;
}
break;
case CHARGER_DISCHARGE:
ret = POWER_SUPPLY_STATUS_DISCHARGING;
break;
default:
ret = POWER_SUPPLY_STATUS_UNKNOWN;
}
dev_dbg(dev, "%s : %s\n", __func__, status_text[ret]);
return ret;
}
static int s3c_bat_get_property(struct power_supply *bat_ps,
enum power_supply_property psp,
union power_supply_propval *val)
{
dev_dbg(bat_ps->dev, "%s : psp = %d\n", __func__, psp);
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = s3c_bat_get_charging_status();
break;
case POWER_SUPPLY_PROP_HEALTH:
val->intval = s3c_get_bat_health();
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = s3c_bat_info.present;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = s3c_bat_info.bat_info.level;
dev_dbg(dev, "%s : level = %d\n", __func__,
val->intval);
break;
case POWER_SUPPLY_PROP_TEMP:
val->intval = s3c_bat_info.bat_info.batt_temp;
dev_dbg(bat_ps->dev, "%s : temp = %d\n", __func__,
val->intval);
break;
default:
return -EINVAL;
}
return 0;
}
static int s3c_power_get_property(struct power_supply *bat_ps,
enum power_supply_property psp,
union power_supply_propval *val)
{
charger_type_t charger;
dev_dbg(bat_ps->dev, "%s : psp = %d\n", __func__, psp);
charger = s3c_bat_info.bat_info.charging_source;
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
if (bat_ps->type == POWER_SUPPLY_TYPE_MAINS)
val->intval = (charger == CHARGER_AC ? 1 : 0);
else if (bat_ps->type == POWER_SUPPLY_TYPE_USB)
val->intval = (charger == CHARGER_USB ? 1 : 0);
else
val->intval = 0;
break;
default:
return -EINVAL;
}
return 0;
}
#define SEC_BATTERY_ATTR(_name) \
{ \
.attr = { .name = #_name, .mode = S_IRUGO | S_IWUGO, .owner = THIS_MODULE }, \
.show = s3c_bat_show_property, \
.store = s3c_bat_store, \
}
static struct device_attribute s3c_battery_attrs[] = {
SEC_BATTERY_ATTR(batt_vol),
SEC_BATTERY_ATTR(batt_vol_adc),
SEC_BATTERY_ATTR(batt_vol_adc_cal),
SEC_BATTERY_ATTR(batt_temp),
SEC_BATTERY_ATTR(batt_temp_adc),
SEC_BATTERY_ATTR(batt_temp_adc_cal),
};
enum {
BATT_VOL = 0,
BATT_VOL_ADC,
BATT_VOL_ADC_CAL,
BATT_TEMP,
BATT_TEMP_ADC,
BATT_TEMP_ADC_CAL,
};
static int s3c_bat_create_attrs(struct device * dev)
{
int i, rc;
for (i = 0; i < ARRAY_SIZE(s3c_battery_attrs); i++) {
rc = device_create_file(dev, &s3c_battery_attrs[i]);
if (rc)
goto s3c_attrs_failed;
}
goto succeed;
s3c_attrs_failed:
while (i--)
device_remove_file(dev, &s3c_battery_attrs[i]);
succeed:
return rc;
}
static ssize_t s3c_bat_show_property(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int i = 0;
const ptrdiff_t off = attr - s3c_battery_attrs;
switch (off) {
case BATT_VOL:
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
s3c_bat_info.bat_info.batt_vol);
break;
case BATT_VOL_ADC:
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
s3c_bat_info.bat_info.batt_vol_adc);
break;
case BATT_VOL_ADC_CAL:
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
s3c_bat_info.bat_info.batt_vol_adc_cal);
break;
case BATT_TEMP:
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
s3c_bat_info.bat_info.batt_temp);
break;
case BATT_TEMP_ADC:
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
s3c_bat_info.bat_info.batt_temp_adc);
break;
case BATT_TEMP_ADC_CAL:
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
s3c_bat_info.bat_info.batt_temp_adc_cal);
break;
default:
i = -EINVAL;
}
return i;
}
static ssize_t s3c_b
android系统电池驱动之内核驱动(6410)
5星 · 超过95%的资源 需积分: 32 166 浏览量
2011-08-16
23:15:12
上传
评论 3
收藏 4KB RAR 举报
凉拌菜
- 粉丝: 54
- 资源: 8
最新资源
- Q1.py
- 企业政府灵智电子政务网站系统-lingzhi.rar
- Thinkphp内核开发Lsky Pro兰空图床网站源码.rar
- 基于FPGA(XC6SLX9)+SDRAM+AD7829多通道数据采集板硬件(原理图+PCB)工程文件.zip
- 阿里巴巴精准测试体系:基于代码链路分析的性能优化方案
- mmexport1714217773503.jpg
- 【图片网盘外链系统5.0】全新前端UI界面设计 支持图片违规检测网站自适应H5源码.rar
- jsp+sql的BBS论坛系统.zip
- 网盘外链PHP开发彩虹网盘外链程序源码.rar
- 2023年最新文件快递柜系统网站源码 保护用户隐私的匿名口令分享和临时文件分享功能.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页