#if defined (CONFIG_BATTERY_BQ27541)
#define DC_CHECK_PIN RK29_PIN4_PA1
#define LI_LION_BAT_NUM 1
+#define CHG_OK RK29_PIN4_PA3
+#define BAT_LOW RK29_PIN4_PA2
+
static int bq27541_init_dc_check_pin(void){
if(gpio_request(DC_CHECK_PIN,"dc_check") != 0){
gpio_free(DC_CHECK_PIN);
.init_dc_check_pin = bq27541_init_dc_check_pin,
.dc_check_pin = DC_CHECK_PIN,
.bat_num = LI_LION_BAT_NUM,
+ .chgok_check_pin = CHG_OK,
+ .bat_check_pin = BAT_LOW,
};
#endif
static struct android_pmem_platform_data android_pmem_pdata = {
{ .frequency = CPUFREQ_TABLE_END },
};
-#define BAT_LOW RK29_PIN4_PA2
-#define POWER_ON_PIN RK29_PIN4_PA4
+
static void __init machine_rk29_board_init(void)
{
- int val =0;
- gpio_request(BAT_LOW, NULL);
- gpio_direction_input(BAT_LOW);
- val = gpio_get_value(BAT_LOW);
- if (val == 0){
- printk("no battery, no power up\n");
- gpio_request(POWER_ON_PIN, "poweronpin");
- gpio_direction_output(POWER_ON_PIN, GPIO_LOW);
- while(1){
- gpio_set_value(POWER_ON_PIN, GPIO_LOW);
- mdelay(100);
- }
- }
- gpio_free(BAT_LOW);
rk29_board_iomux_init();
board_power_init();
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <mach/board.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
#define DRIVER_VERSION "1.1.0"
#define BQ27510_SPEED 100 * 1000
#define POWER_ON_PIN RK29_PIN4_PA4
+//#define CHG_OK RK29_PIN4_PA3
-#define BAT_LOW RK29_PIN4_PA2
+//#define BAT_LOW RK29_PIN4_PA2
int virtual_battery_enable = 0;
extern int dwc_vbus_status(void);
static void bq27541_set(void);
+
#if 0
#define DBG(x...) printk(KERN_INFO x)
#else
struct power_supply bat;
struct power_supply ac;
struct delayed_work work;
+ struct delayed_work wakeup_work;
struct i2c_client *client;
+ int wake_irq;
unsigned int interval;
unsigned int dc_check_pin;
+ unsigned int bat_check_pin;
unsigned int bat_num;
int power_down;
};
* Return the battery temperature in tenths of degree Celsius
* Or < 0 if something fails.
*/
+
+static irqreturn_t bq27541_bat_wakeup(int irq, void *dev_id)
+{
+ struct bq27541_device_info *di = (struct bq27541_device_info *)dev_id;
+
+ printk("!!! bq27541 bat_low irq low vol !!!\n\n\n");
+ disable_irq_wake(di->wake_irq);
+
+ schedule_delayed_work(&di->wakeup_work, msecs_to_jiffies(0));
+ return IRQ_HANDLED;
+}
+
+static void bq27541_battery_wake_work(struct work_struct *work)
+{
+ int ret;
+ struct bq27541_device_info *di =
+ (struct bq27541_device_info *)container_of(work, struct bq27541_device_info, wakeup_work.work);
+
+ rk28_send_wakeup_key();
+
+ free_irq(di->wake_irq, di);
+ di->wake_irq = gpio_to_irq(di->bat_check_pin);
+
+ ret = request_irq(di->wake_irq, bq27541_bat_wakeup, IRQF_TRIGGER_FALLING, "bq27541_battery", di);
+ if (ret) {
+ printk("request faild!\n");
+ return;
+ }
+ enable_irq_wake(di->wake_irq);
+}
static int bq27541_battery_temperature(struct bq27541_device_info *di)
* Return the battery Voltage in milivolts
* Or < 0 if something fails.
*/
+
+
+
static int bq27541_battery_voltage(struct bq27541_device_info *di)
{
int ret;
ret = bq27541_read(di->client,BQ27x00_REG_VOLT,buf,2);
if (ret<0) {
dev_err(di->dev, "error reading voltage\n");
- printk("vol smaller then 3.4V, shutdown");
// gpio_set_value(POWER_ON_PIN, GPIO_LOW);
return ret;
}
volt = volt * 1000;
}
+
+
- if ((volt <= 3400000) && (volt > 0)){
- printk("vol smaller then 3.4V, shutdown");
+ if ((volt <= 3400000) && (volt > 0) && gpio_get_value(di->dc_check_pin)){
+ printk("vol smaller then 3.4V, report to android!");
di->power_down = 1;
}else{
di->power_down = 0;
}
-
DBG("Enter:%s %d--volt = %d\n",__FUNCTION__,__LINE__,volt);
return volt;
union power_supply_propval *val)
{
int ret = 0;
- int vals=0;
struct bq27541_device_info *di = to_bq27541_device_info(psy);
DBG("Enter:%s %d psp= %d\n",__FUNCTION__,__LINE__,psp);
val->intval = bq27541_battery_current(di);
break;
case POWER_SUPPLY_PROP_CAPACITY:
- if (!(di->power_down)){ // < 3.4V power down ,capacity = 0;
- val->intval = bq27541_battery_rsoc(di);
- }else{
+ if (di->power_down == 1){ // < 3.4V power down ,capacity = 0;
val->intval = 0;
+ }else {
+ val->intval = bq27541_battery_rsoc(di);
}
break;
int retval = 0;
struct bq27541_platform_data *pdata;
int val =0;
-
-
+ char buf[2];
+ int volt;
DBG("********** bq27541_battery_probe************** ");
pdata = client->dev.platform_data;
di->bat_num = pdata->bat_num;
di->dc_check_pin = pdata->dc_check_pin;
+ di->bat_check_pin = pdata->bat_check_pin;
if (pdata->init_dc_check_pin)
pdata->init_dc_check_pin( );
INIT_DELAYED_WORK(&di->work, bq27541_battery_work);
schedule_delayed_work(&di->work, di->interval);
dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
+
+#if !defined (CONFIG_NO_BATTERY_IC)
+
+ // no battery , no power up
+ gpio_request(POWER_ON_PIN, "poweronpin");
+ gpio_request(pdata->bat_check_pin, NULL);
+ gpio_direction_input(pdata->bat_check_pin);
+ gpio_request(pdata->chgok_check_pin, "CHG_OK");
+ gpio_direction_input(pdata->chgok_check_pin);
+
+ val = gpio_get_value(pdata->bat_check_pin);
+ if (val == 1){
+ printk("\n\n!!! bat_low high !!!\n\n");
+ val = bq27541_read(di->client,BQ27x00_REG_VOLT,buf,2);
+ if (val < 0){
+ printk("\n\n!!! bq i2c err! no battery, power down\n!!!\n\n");
+ gpio_direction_output(POWER_ON_PIN, GPIO_LOW);
+ while(1){
+ gpio_set_value(POWER_ON_PIN, GPIO_LOW);
+ mdelay(100);
+ }
+ }
+
+ }else{
+
+ printk("\n\n!!! bat_low low !!!\n\n");
+ val = gpio_get_value(pdata->chgok_check_pin);
+ if (val == 1){
+ printk("no battery, power down \n");
+ gpio_direction_output(POWER_ON_PIN, GPIO_LOW);
+ while(1){
+ gpio_set_value(POWER_ON_PIN, GPIO_LOW);
+ mdelay(100);
+ }
+ }else{
+ mdelay(1000);
+ val = gpio_get_value(pdata->chgok_check_pin);
+ if (val == 1){
+ printk("no battery, power down \n");
+ gpio_direction_output(POWER_ON_PIN, GPIO_LOW);
+ while(1){
+ gpio_set_value(POWER_ON_PIN, GPIO_LOW);
+ mdelay(100);
+ }
+ }
+ }
+
+ }
+
+// gpio_free(POWER_ON_PIN);
+// gpio_free(pdata->bat_check_pin);
+ gpio_free(pdata->chgok_check_pin);
+
+
+ //smaller 3.4V , no power up
+ if (gpio_get_value(di->dc_check_pin) && (gpio_get_value(pdata->bat_check_pin) == 0)){
+ printk("no AC && battery low ,so power down \n");
+ gpio_direction_output(POWER_ON_PIN, GPIO_LOW);
+ while(1){
+ printk("no AC && battery low ,so power down \n");
+ gpio_set_value(POWER_ON_PIN, GPIO_LOW);
+ mdelay(100);
+ }
+ }
+
+
+ // battery low irq
+ di->wake_irq = gpio_to_irq(pdata->bat_check_pin);
+ retval = request_irq(di->wake_irq, bq27541_bat_wakeup, IRQF_TRIGGER_FALLING, "bq27541_battery", di);
+ if (retval) {
+ printk("failed to request bat det irq\n");
+ goto err_batirq_failed;
+ }
+
+ INIT_DELAYED_WORK(&di->wakeup_work, bq27541_battery_wake_work);
+ enable_irq_wake(di->wake_irq);
+
+
+#endif
+
return 0;
batt_failed_4:
kfree(di);
batt_failed_2:
+
+err_batirq_failed:
+ gpio_free(pdata->bat_check_pin);
+
return retval;
}
}
//module_init(bq27541_battery_init);
+//fs_initcall_sync(bq27541_battery_init);
+
fs_initcall(bq27541_battery_init);
//arch_initcall(bq27541_battery_init);