Merge branch 'develop-3.0' of ssh://10.10.10.29/rk/kernel into develop-3.0

This commit is contained in:
zwp
2012-01-05 11:40:31 +08:00
12 changed files with 1640 additions and 1 deletions

View File

@@ -775,6 +775,27 @@ struct bq27541_platform_data bq27541_info = {
.bat_check_pin = BAT_LOW,
};
#endif
#ifdef CONFIG_BATTERY_RK29_ADC
static struct rk29_adc_battery_platform_data rk29_adc_battery_platdata = {
.dc_det_pin = RK29_PIN4_PA1,
.batt_low_pin = RK29_PIN4_PA2,
.charge_set_pin = INVALID_GPIO,
.charge_ok_pin = RK29_PIN4_PA3,
.dc_det_level = GPIO_LOW,
.charge_ok_level = GPIO_HIGH,
};
static struct platform_device rk29_device_adc_battery = {
.name = "rk2918-battery",
.id = -1,
.dev = {
.platform_data = &rk29_adc_battery_platdata,
},
};
#endif
static struct android_pmem_platform_data android_pmem_pdata = {
.name = "pmem",
.start = PMEM_UI_BASE,
@@ -2629,6 +2650,9 @@ static struct platform_device *devices[] __initdata = {
#ifdef CONFIG_ADC_RK29
&rk29_device_adc,
#endif
#ifdef CONFIG_BATTERY_RK29_ADC
&rk29_device_adc_battery,
#endif
#ifdef CONFIG_I2C0_RK29
&rk29_device_i2c0,
#endif

View File

@@ -44,6 +44,23 @@ struct hdmi_platform_data {
int (*io_init)(void);
int (*io_deinit)(void);
};
/* adc battery */
struct rk29_adc_battery_platform_data {
int (*io_init)(void);
int (*io_deinit)(void);
int dc_det_pin;
int batt_low_pin;
int charge_ok_pin;
int charge_set_pin;
int dc_det_level;
int batt_low_level;
int charge_ok_level;
int charge_set_level;
};
struct irda_info{
u32 intr_pin;
int (*iomux_init)(void);

View File

@@ -292,4 +292,19 @@ config CHARGER_GPIO
This driver can be build as a module. If so, the module will be
called gpio-charger.
config BATTERY_RK29_ADC
tristate "RK29 ADC Battery"
depends on ADC_RK29
help
Say Y to enable support for the battery on the RK2918.
config BATTERY_RK29_AC_CHARGE
tristate "RK29 AC CHARGE"
depends on BATTERY_RK29_ADC
help
say Y to enable suspport for the AC battery charge
config POWER_ON_CHARGER_DISPLAY
bool "Support charger display"
endif # POWER_SUPPLY

View File

@@ -41,3 +41,5 @@ obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_BATTERY_RK29_ADC) += rk29_adc_battery.o
obj-$(CONFIG_POWER_ON_CHARGER_DISPLAY) += rk29_charger_display.o

View File

@@ -19,6 +19,9 @@
#include <linux/power_supply.h>
#include "power_supply.h"
#ifdef CONFIG_POWER_ON_CHARGER_DISPLAY
extern struct list_head rk_psy_head;
#endif
/* exported for the APM Power driver, APM emulation */
struct class *power_supply_class;
EXPORT_SYMBOL_GPL(power_supply_class);
@@ -181,6 +184,10 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
device_initialize(dev);
#ifdef CONFIG_POWER_ON_CHARGER_DISPLAY
list_add(&psy->rk_psy_node, &rk_psy_head);
#endif
dev->class = power_supply_class;
dev->type = &power_supply_dev_type;
dev->parent = parent;

1234
drivers/power/rk29_adc_battery.c Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,137 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/power_supply.h>
#include <linux/workqueue.h>
#include <asm/unaligned.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
#include <mach/board.h>
#include <asm/uaccess.h>
#include <linux/power_supply.h>
#if 0
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...)
#endif
//#define RK29_PLAY_ON_PIN RK29_PIN6_PA7
//#define MAX_PRE_CNT 2
//#define DET_CNT 5
#define PWR_ON_THRESHD 5 //power on threshd of capacity
//unsigned int pre_cnt = 0; //for long press counter
//int charge_disp_mode = 0;
int pwr_on_thrsd = 5; //power on capcity threshold
//extern int board_boot_mode(void);
//extern int boot_mode_init(char * s);
extern void kernel_power_off(void);
static int __init pwr_on_thrsd_setup(char *str)
{
pwr_on_thrsd = simple_strtol(str,NULL,10);
printk(KERN_INFO "power on threshold:%d",pwr_on_thrsd);
return 0;
}
__setup("pwr_on_thrsd=", pwr_on_thrsd_setup);
LIST_HEAD(rk_psy_head); //add by yxj for charge logo display boot_command_line
//int charger_mode=0; //1:charge,0:not charge
static void add_bootmode_charger_to_cmdline(void)
{
char *pmode=" androidboot.mode=charger";
//int off = strlen(saved_command_line);
char *new_command_line = kzalloc(strlen(saved_command_line) + strlen(pmode) + 1, GFP_KERNEL);
sprintf(new_command_line, "%s%s", saved_command_line, pmode);
saved_command_line = new_command_line;
//strcpy(saved_command_line+off,pmode);
//int off = strlen(boot_command_line);
//strcpy(boot_command_line+off,pmode);
printk("Kernel command line: %s\n", saved_command_line);
}
//display charger logo in kernel CAPACITY
static int __init start_charge_logo_display(void)
{
union power_supply_propval val_status = {POWER_SUPPLY_STATUS_DISCHARGING};
union power_supply_propval val_capacity ={ 100} ;
struct power_supply *psy;
int online = 0;
printk("start_charge_logo_display\n");
if(board_boot_mode() == BOOT_MODE_RECOVERY) //recovery mode
{
printk("recovery mode \n");
return 0;
}
list_for_each_entry(psy, &rk_psy_head, rk_psy_node)
{
psy->get_property(psy,POWER_SUPPLY_PROP_ONLINE,&val_status);
online += val_status.intval;
psy->get_property(psy,POWER_SUPPLY_PROP_CAPACITY,&val_capacity);
}
if(online >= 1)
val_status.intval = POWER_SUPPLY_STATUS_CHARGING;
// low power and discharging
if((val_capacity.intval < pwr_on_thrsd )&&(val_status.intval != POWER_SUPPLY_STATUS_CHARGING))
{
printk("low power\n");
kernel_power_off();
while(1);
return 0;
}
/*
//low power and charging
if((val_capacity.intval < pwr_on_thrsd )&&(val_status.intval == POWER_SUPPLY_STATUS_CHARGING))
{
while((val_capacity.intval < pwr_on_thrsd ))
{
list_for_each_entry(psy, &rk_psy_head, rk_psy_node)
{
psy->get_property(psy,POWER_SUPPLY_PROP_CAPACITY,&val_capacity);
}
//printk("charging ... \n");
}
}
*/
if(val_status.intval == POWER_SUPPLY_STATUS_CHARGING)
{
if(board_boot_mode() != BOOT_MODE_REBOOT) //do not enter power on charge mode when soft reset
{
add_bootmode_charger_to_cmdline();
//boot_mode_init("charge");
printk("power in charge mode\n");
}
}
return 0;
}
subsys_initcall_sync(start_charge_logo_display);

View File

@@ -104,6 +104,7 @@ struct wm831x_power *g_wm831x_power;
static int power_test_sysfs_init(void);
extern void wm831x_batt_vol_level(struct wm831x_power *power, int batt_vol, int *level);
static DEFINE_MUTEX(charging_mutex);
static struct wake_lock batt_wake_lock;
int wm831x_read_on_pin_status(void)
{
@@ -614,7 +615,7 @@ static int wm831x_bat_get_prop(struct power_supply *psy,
//val->intval = wm831x_power->batt_info.status;
break;
case POWER_SUPPLY_PROP_PRESENT:
case POWER_SUPPLY_PROP_ONLINE:
//case POWER_SUPPLY_PROP_ONLINE:
//ret = wm831x_power_check_online(wm831x, WM831X_PWR_SRC_BATT, val);
val->intval = wm831x_power->batt_info.online;
break;
@@ -710,6 +711,7 @@ static irqreturn_t wm831x_pwr_src_irq(int irq, void *data)
struct wm831x_power *wm831x_power = data;
struct wm831x *wm831x = wm831x_power->wm831x;
wake_lock_timeout(&batt_wake_lock, 30 * HZ);
dev_dbg(wm831x->dev, "Power source changed\n");
WM_BATT_DBG("%s:Power source changed\n", __FUNCTION__);
/* Just notify for everything - little harm in overnotifying. */
@@ -1004,6 +1006,56 @@ static void wm831x_batt_work(struct work_struct *work)
}
#ifdef CONFIG_POWER_ON_CHARGER_DISPLAY
static void wm831x_batt_check(struct wm831x_power *power)
{
int online, status,health,level, ret;
union power_supply_propval val;
// struct wm831x_power *power = container_of(work, struct wm831x_power, batt_work);
ret = wm831x_power_check_online(power->wm831x, WM831X_PWR_SRC_BATT, &val);
if (ret < 0) {
printk("%s: check bat online failer... err = %d\n", __FUNCTION__, ret);
return;
}
online = val.intval;
ret = wm831x_bat_check_status(power->wm831x, &status);
if (ret < 0) {
printk("%s: check bat status failer... err = %d\n", __FUNCTION__, ret);
return;
}
ret = wm831x_bat_check_health(power->wm831x, &health);
if (ret < 0) {
printk("%s: check bat health failer... err = %d\n", __FUNCTION__, ret);
return;
}
ret = wm831x_power_read_voltage(power->wm831x, WM831X_AUX_BATT, &val);
if (ret < 0) {
printk("%s: read bat voltage failer...err = %d\n", __FUNCTION__, ret);
return;
}
power->batt_info.voltage = val.intval;
wm831x_batt_vol_level(power, val.intval / 1000, &level);
//mod_timer(&power->timer, jiffies + msecs_to_jiffies(power->interval));
if (online != power->batt_info.online || status != power->batt_info.status
|| health != power->batt_info.health || level != power->batt_info.level)
{
power->batt_info.online = online;
power->batt_info.status = status;
power->batt_info.health = health;
power->batt_info.level = level;
power_supply_changed(&power->battery);
}
}
#endif
static __devinit int wm831x_power_probe(struct platform_device *pdev)
{
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
@@ -1028,6 +1080,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
* the status without enabling the charger.
*/
wm831x_config_battery(wm831x);
wake_lock_init(&batt_wake_lock, WAKE_LOCK_SUSPEND, "batt_lock");
wall->name = "wm831x-wall";
wall->type = POWER_SUPPLY_TYPE_MAINS;
@@ -1107,6 +1160,10 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev)
add_timer(&power->timer);
g_wm831x_power = power;
#ifdef CONFIG_POWER_ON_CHARGER_DISPLAY
wm831x_batt_check(power);//xsf
#endif
printk("%s:wm831x_power initialized\n",__FUNCTION__);
power_test_sysfs_init();
return ret;
@@ -1192,7 +1249,11 @@ static int __init wm831x_power_init(void)
{
return platform_driver_register(&wm831x_power_driver);
}
#ifndef CONFIG_POWER_ON_CHARGER_DISPLAY
module_init(wm831x_power_init);
#else
subsys_initcall(wm831x_power_init);
#endif
static void __exit wm831x_power_exit(void)
{

View File

@@ -123,6 +123,14 @@ config RTC_INTF_ALARM_DEV
help
Exports the alarm interface to user-space.
config AUTO_WAKE_UP
tristate "Support auto wake up"
depends on RTC_INTF_ALARM_DEV
config AUTO_WAKE_UP_PERIOD
int "auto wake up period(sec)"
depends on AUTO_WAKE_UP
default 3600
config RTC_DRV_TEST
tristate "Test driver/device"

View File

@@ -15,6 +15,8 @@ rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
obj-$(CONFIG_AUTO_WAKE_UP) += auto-wake.o
# Keep the list ordered.
obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o

128
drivers/rtc/auto-wake.c Executable file
View File

@@ -0,0 +1,128 @@
#include <linux/android_alarm.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/sysdev.h>
#include <linux/wakelock.h>
#include <linux/power_supply.h>
#include <linux/suspend.h>
#include <asm/mach/time.h>
struct auto_wake
{
struct alarm alarm;
struct timespec timer;
//struct notifier_block pm_nb;
};
static struct auto_wake auto_wake;
struct timespec set_atuo_wake_time( struct timespec timer)
{
struct timespec new_time;
struct timespec tmp_time;
tmp_time =ktime_to_timespec(alarm_get_elapsed_realtime());
printk("nowtime = %ld \n",tmp_time.tv_sec);
new_time.tv_nsec = timer.tv_nsec+ tmp_time.tv_nsec;
new_time.tv_sec = timer.tv_sec+ tmp_time.tv_sec;
return new_time;
}
static void auto_wake_update(struct auto_wake *auto_wake)
{
struct timespec new_alarm_time;
// printk("auto_wake_update\n");
new_alarm_time = set_atuo_wake_time(auto_wake->timer);
alarm_start_range(&auto_wake->alarm,
timespec_to_ktime(new_alarm_time),
timespec_to_ktime(new_alarm_time));
}
static void atuo_wake_trigger(struct alarm *alarm)
{
struct auto_wake *auto_wake = container_of(alarm, struct auto_wake,
alarm);
auto_wake_update(auto_wake);
}
#if 0
static void auto_wake_cancel(struct auto_wake *auto_wake)
{
alarm_cancel(&auto_wake->alarm);
}
static int auto_wake_callback(struct notifier_block *nfb,
unsigned long action,
void *ignored)
{
struct auto_wake *auto_wake = container_of(nfb, struct auto_wake,
pm_nb);
switch (action)
{
case PM_SUSPEND_PREPARE:
{
printk("PM_SUSPEND_PREPARExsf \n");
auto_wake_update(auto_wake);
return NOTIFY_OK;
}
case PM_POST_SUSPEND:
{
printk("PM_POST_SUSPENDxsf \n");
// auto_wake_cancel(auto_wake);
return NOTIFY_OK;
}
}
return NOTIFY_DONE;
}
static struct notifier_block auto_wake_pm_notifier = {
.notifier_call = auto_wake_callback,
.priority = 0,
};
#endif
void auto_wake_init(struct auto_wake *auto_wake,struct timespec timer)
{
// auto_wake->pm_nb = auto_wake_pm_notifier;
auto_wake->timer = timer;
alarm_init(&auto_wake->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, atuo_wake_trigger);
//register_pm_notifier(&auto_wake->pm_nb);// xsf
}
static int __init start_auto_wake(void)
{
struct timespec timer;
printk("CONFIG_AUTO_WAKE_UP_PERIOD = %d\n", CONFIG_AUTO_WAKE_UP_PERIOD);
timer.tv_sec = CONFIG_AUTO_WAKE_UP_PERIOD;
timer.tv_nsec = 0;
auto_wake_init(&auto_wake,timer);
auto_wake_update(&auto_wake);
return 0;
}
late_initcall_sync(start_auto_wake);

View File

@@ -147,6 +147,10 @@ struct power_supply {
char **supplied_to;
size_t num_supplicants;
#ifdef CONFIG_POWER_ON_CHARGER_DISPLAY
struct list_head rk_psy_node;
#endif
int (*get_property)(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val);