#define NUM_CHARGE_FULL_DELAY_TIMES ((CHARGE_FULL_DELAY_TIMES * 1000) / TIMER_MS_COUNTS) //³äµçÂú״̬³ÖÐøʱ¼ä³¤¶È
#define NUM_USBCHARGE_IDENTIFY_TIMES ((USBCHARGE_IDENTIFY_TIMES * 1000) / TIMER_MS_COUNTS) //³äµçÂú״̬³ÖÐøʱ¼ä³¤¶È
-#define BAT_2V5_VALUE 2500
+#define CHARGE_IS_OK 1
+#define INVALID_CHARGE_CHECK -1
+
+#if defined(CONFIG_ARCH_RK3066B)
+
+#define BAT_DEFINE_VALUE 1800
+#elif defined(CONFIG_ARCH_RK2928)
+#define BAT_DEFINE_VALUE 3300
+#else
+#define BAT_DEFINE_VALUE 2500
+
+
+#endif
-#define BATT_NUM 52
#define BATT_FILENAME "/data/bat_last_capacity.dat"
static struct wake_lock batt_wake_lock;
#define BATT_NOMAL_VOL_VALUE 3800
//divider resistance
#define BAT_PULL_UP_R 200
+#if defined(CONFIG_ARCH_RK3066B)
+#define BAT_PULL_DOWN_R 100
+#else
#define BAT_PULL_DOWN_R 200
-
-static struct batt_vol_cal batt_table[BATT_NUM] = {
+#endif
+static struct batt_vol_cal batt_table[] = {
{0,3400,3520},{1,3420,3525},{2,3420,3575},{3,3475,3600},{5,3505,3620},{7,3525,3644},
{9,3540,3662},{11,3557,3670},{13,3570,3684},{15,3580,3700},{17,3610,3715},
{19,3630,3720},{21,3640,3748},{23,3652,3756},{25,3662,3775},{27,3672,3790},
#define BAT_PULL_UP_R 300
#define BAT_PULL_DOWN_R 100
-static struct batt_vol_cal batt_table[BATT_NUM] = {
- {0,6800,7400}, {1,6840,7440}, {2,6880,7480}, {3,6950,7450}, {5,7010,7510}, {7,7050,7550},
+static struct batt_vol_cal batt_table[] = {
+ {0,6800,7400}, {1,6840,7440}, {2,6880,7480}, {3,6950,7450}, {5,7010,7510}, {7,7050,7550},
{9,7080,7580}, {11,7104,7604}, {13,7140,7640}, {15,7160,7660}, {17,7220,7720},
{19,7260,7760}, {21,7280,7780}, {23,7304,7802}, {25,7324,7824}, {27,7344,7844},
{29,7360,7860}, {31,7374,7874}, {33,7386,7886}, {35,7398,7898}, {37,7410,7910},//500
};
#endif
-#define adc_to_voltage(adc_val) ((adc_val * BAT_2V5_VALUE * (BAT_PULL_UP_R + BAT_PULL_DOWN_R)) / (1024 * BAT_PULL_DOWN_R))
+
+#define BATT_NUM ARRAY_SIZE(batt_table)
+
+#define adc_to_voltage(adc_val) ((adc_val * BAT_DEFINE_VALUE * (BAT_PULL_UP_R + BAT_PULL_DOWN_R)) / (1024 * BAT_PULL_DOWN_R))
/********************************************************************************/
charge_on = 1;
}
}
+ else{
+ if(pdata->is_dc_charging)
+ charge_on =pdata->is_dc_charging();
+ }
+
+
#endif
+#if 1
+ if (pdata->spport_usb_charging) //is usb charging
+ if(pdata->is_usb_charging)
+ charge_on = pdata->is_usb_charging();
-#if defined (CONFIG_BATTERY_RK30_USB_CHARGE)
- if (charge_on == 0){
- if (suspend_flag)
- return;
- if (1 == dwc_vbus_status()) { //¼ì²âµ½USB²åÈ룬µ«ÊÇÎÞ·¨Ê¶±ðÊÇ·ñÊdzäµçÆ÷
- //ͨ¹ýÑÓʱ¼ì²âPCʶ±ð±êÖ¾£¬Èç¹û³¬Ê±¼ì²â²»µ½£¬ËµÃ÷Êdzäµç
- if (0 == get_msc_connect_flag()){ //²åÈë³äµçÆ÷ʱ¼ä´óÓÚÒ»¶¨Ê±¼äÖ®ºó£¬¿ªÊ¼½øÈë³äµç״̬
- if (++gBatUsbChargeCnt >= NUM_USBCHARGE_IDENTIFY_TIMES){
- gBatUsbChargeCnt = NUM_USBCHARGE_IDENTIFY_TIMES + 1;
- charge_on = 1;
- }
- } //·ñÔò£¬²»½øÈë³äµçģʽ
- }
- else{
- gBatUsbChargeCnt = 0;
- if (2 == dwc_vbus_status()) {
- charge_on = 1;
- }
- }
- }
#endif
return charge_on;
}
+static int is_charge_ok(struct rk30_adc_battery_data *bat)
+{
+ int charge_is_ok = 0;
+ struct rk30_adc_battery_platform_data *pdata = bat->pdata;
+
+ if((pdata->charge_ok_pin == INVALID_GPIO)&& ( pdata->charging_ok == NULL))
+ return -1;
+
+ if (pdata->charge_ok_pin != INVALID_GPIO){
+ if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level)
+ {
+ charge_is_ok =1;
+ }
+ }else if( pdata->charging_ok)
+ {
+ charge_is_ok = pdata->charging_ok();
+ }
+ return charge_is_ok;
+
+
+}
//int old_charge_level;
static int rk30_adc_battery_status_samples(struct rk30_adc_battery_data *bat)
{
int charge_level;
-
- struct rk30_adc_battery_platform_data *pdata = bat->pdata;
-
+// struct rk30_adc_battery_platform_data *pdata = bat->pdata;
charge_level = rk30_adc_battery_get_charge_level(bat);
//¼ì²â³äµç״̬±ä»¯Çé¿ö
bat->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
}
else{
- //CHARGE
- if (pdata->charge_ok_pin == INVALID_GPIO){ //no charge_ok_pin
+ //CHARGE
+ if( is_charge_ok(bat) == INVALID_CHARGE_CHECK){
+ //if (pdata->charge_ok_pin == INVALID_GPIO){ //no charge_ok_pin
if (bat->bat_capacity == 100){
if (bat->bat_status != POWER_SUPPLY_STATUS_FULL){
}
}
else{ // pin of charge_ok_pin
- if (gpio_get_value(pdata->charge_ok_pin) != pdata->charge_ok_level){
+ if (is_charge_ok(bat) != CHARGE_IS_OK ){
bat->full_times = 0;
bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
bat->full_times = NUM_CHARGE_FULL_DELAY_TIMES + 1;
}
- if ((bat->full_times >= NUM_CHARGE_FULL_DELAY_TIMES) && (bat->bat_capacity >= 99)){
+ if ((bat->full_times >= NUM_CHARGE_FULL_DELAY_TIMES) && (bat->bat_capacity >= 95)){
if (bat->bat_status != POWER_SUPPLY_STATUS_FULL){
bat->bat_status = POWER_SUPPLY_STATUS_FULL;
bat->bat_capacity = 100;
return charge_level;
}
+//#define adc_to_voltage(adc_val) ((adc_val * BAT_DEFINE_VALUE * (BAT_PULL_UP_R + BAT_PULL_DOWN_R)) / (1024 * BAT_PULL_DOWN_R))
+
+static int rk_adc_voltage(int value)
+{
+ int voltage;
+
+ int ref_voltage; //reference_voltage
+ int pullup_res;
+ int pulldown_res;
+
+ ref_voltage = gBatteryData ->pdata->reference_voltage;
+ pullup_res = gBatteryData ->pdata->pull_up_res;
+ pulldown_res = gBatteryData ->pdata->pull_down_res;
+
+ if(ref_voltage && pullup_res && pulldown_res){
+
+ voltage = ((value * ref_voltage * (pullup_res + pulldown_res)) / (1024 * pulldown_res));
+
+ }else{
+ voltage = adc_to_voltage(value);
+ }
+
+
+ return voltage;
+
+}
static int *pSamples;
static void rk30_adc_battery_voltage_samples(struct rk30_adc_battery_data *bat)
value = bat->adc_val;
adc_async_read(bat->client);
- *pSamples++ = adc_to_voltage(value);
+ *pSamples++ = rk_adc_voltage(value);
bat->bat_status_cnt++;
if (bat->bat_status_cnt > NUM_VOLTAGE_SAMPLE) bat->bat_status_cnt = NUM_VOLTAGE_SAMPLE + 1;
if (rk30_adc_battery_get_charge_level(bat)){ //charge
if(BatVoltage >= (p[BATT_NUM - 1].charge_vol)){
- capacity = 100;
+ capacity = 99;
}
else{
if(BatVoltage <= (p[0].charge_vol)){
for(i = 0; i < BATT_NUM - 1; i++){
if(((p[i].charge_vol) <= BatVoltage) && (BatVoltage < (p[i+1].charge_vol))){
- capacity = p[i].disp_cal ;
+ capacity = p[i].disp_cal + ((BatVoltage - p[i].charge_vol) * (p[i+1].disp_cal -p[i].disp_cal ))/ (p[i+1].charge_vol- p[i].charge_vol);
break;
}
}
else{
for(i = 0; i < BATT_NUM - 1; i++){
if(((p[i].dis_charge_vol) <= BatVoltage) && (BatVoltage < (p[i+1].dis_charge_vol))){
- capacity = p[i].disp_cal ;
+ capacity = p[i].disp_cal+ ((BatVoltage - p[i].dis_charge_vol) * (p[i+1].disp_cal -p[i].disp_cal ) )/ (p[i+1].dis_charge_vol- p[i].dis_charge_vol) ;
break;
}
}
}
return capacity;
-}
+ }
+
static void rk30_adc_battery_capacity_samples(struct rk30_adc_battery_data *bat)
{
int capacity = 0;
- struct rk30_adc_battery_platform_data *pdata = bat->pdata;
+// struct rk30_adc_battery_platform_data *pdata = bat->pdata;
+ int timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE;
+ int timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE;
//³ä·Åµç״̬±ä»¯ºó£¬BufferÌîÂú֮ǰ£¬²»¸üÐÂ
if (bat->bat_status_cnt < NUM_VOLTAGE_SAMPLE) {
if (rk30_adc_battery_get_charge_level(bat)){
if (capacity > bat->bat_capacity){
+ if(capacity > bat->bat_capacity + 10 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -10; //5s
+ else if(capacity > bat->bat_capacity + 7 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -5; //10s
+ else if(capacity > bat->bat_capacity + 3 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE - 2; // 13
//ʵ¼Ê²ÉÑùµ½µÄÈÝÁ¿±ÈÏÔʾµÄÈÝÁ¿´ó£¬Öð¼¶ÉÏÉý
- if (++(bat->gBatCapacityDisChargeCnt) >= NUM_CHARGE_MIN_SAMPLE){
+ if (++(bat->gBatCapacityDisChargeCnt) >= timer_of_charge_sample){
bat->gBatCapacityDisChargeCnt = 0;
if (bat->bat_capacity < 99){
bat->bat_capacity++;
else{ // ʵ¼ÊµÄÈÝÁ¿±È²ÉÑù±È ÏÔʾµÄÈÝÁ¿Ð¡
bat->gBatCapacityDisChargeCnt = 0;
(bat->gBatCapacityChargeCnt)++;
-
- if (pdata->charge_ok_pin != INVALID_GPIO){
- if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level){
+ pr_bat("------------- is_charge_ok(bat)=%d\n", is_charge_ok(bat));
+ if( is_charge_ok(bat) != INVALID_CHARGE_CHECK){
+ //if (pdata->charge_ok_pin != INVALID_GPIO){
+ //if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level){
+ if( is_charge_ok(bat) == CHARGE_IS_OK){
+ if(capacity > bat->bat_capacity + 10 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -13; // 2s
+ else if(capacity > bat->bat_capacity + 7 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -10; //10s
+ else if(capacity > bat->bat_capacity + 2 )
+ timer_of_charge_sample = NUM_CHARGE_MIN_SAMPLE -8; //7s
//¼ì²âµ½µç³Ø³äÂú±êÖ¾£¬Í¬Ê±³¤Ê±¼äÄÚ³äµçµçѹÎޱ仯£¬¿ªÊ¼Æô¶¯¼Æʱ³äµç£¬¿ìËÙÉÏÉýÈÝÁ¿
- if (bat->gBatCapacityChargeCnt >= NUM_CHARGE_MIN_SAMPLE){
+ if (bat->gBatCapacityChargeCnt >= timer_of_charge_sample){
bat->gBatCapacityChargeCnt = 0;
if (bat->bat_capacity < 99){
bat->bat_capacity++;
if ((bat->bat_capacity >= 85) &&(bat->gBatCapacityChargeCnt > NUM_CHARGE_MAX_SAMPLE)){
bat->gBatCapacityChargeCnt = (NUM_CHARGE_MAX_SAMPLE - NUM_CHARGE_MID_SAMPLE);
- if (bat->bat_capacity < 99){
+ if (bat->bat_capacity <= 99){
bat->bat_capacity++;
bat->bat_change = 1;
}
else{
//·Åµçʱ,Ö»ÔÊÐíµçѹϽµ
if (capacity < bat->bat_capacity){
- if (++(bat->gBatCapacityDisChargeCnt) >= NUM_DISCHARGE_MIN_SAMPLE){
+ if(capacity + 10 > bat->bat_capacity )
+ timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE -10; //5s
+ else if(capacity + 7 > bat->bat_capacity )
+ timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE -5; //10s
+ else if(capacity + 3> bat->bat_capacity )
+ timer_of_discharge_sample = NUM_CHARGE_MIN_SAMPLE - 2; // 13
+
+ if (++(bat->gBatCapacityDisChargeCnt) >= timer_of_discharge_sample){
bat->gBatCapacityDisChargeCnt = 0;
if (bat->bat_capacity > 0){
bat->bat_capacity-- ;
new_capacity = gBatteryData->bat_capacity;
old_capacity = rk30_adc_battery_load_capacity();
+
+ pr_bat("------------old_capacity---%d\n",old_capacity);
if ((old_capacity <= 0) || (old_capacity >= 100)){
old_capacity = new_capacity;
}
}
- //printk("capacity = %d, new_capacity = %d, old_capacity = %d\n",gBatteryData->bat_capacity, new_capacity, old_capacity);
+ pr_bat("capacity = %d, new_capacity = %d, old_capacity = %d\n",gBatteryData->bat_capacity, new_capacity, old_capacity);
gBatteryData->bat_change = 1;
}
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
if (psy->type == POWER_SUPPLY_TYPE_USB)
- val->intval = get_msc_connect_flag();
+ // val->intval = get_msc_connect_flag();
+ if (gBatteryData->pdata->spport_usb_charging) //is usb charging
+ if(gBatteryData->pdata->is_usb_charging)
+ val->intval = gBatteryData ->pdata->is_usb_charging();
+
printk("%s:%d\n",__FUNCTION__,val->intval);
break;
static int rk30_adc_battery_suspend(struct platform_device *dev, pm_message_t state)
{
+ int irq;
gBatteryData->suspend_capacity = gBatteryData->bat_capacity;
cancel_delayed_work(&gBatteryData->delay_work);
+
+ if( gBatteryData->pdata->batt_low_pin != INVALID_GPIO){
+
+ irq = gpio_to_irq(gBatteryData->pdata->batt_low_pin);
+ enable_irq(irq);
+ enable_irq_wake(irq);
+ }
+
return 0;
}
static int rk30_adc_battery_resume(struct platform_device *dev)
{
+ int irq;
gBatteryData->resume = true;
- queue_delayed_work(gBatteryData->wq, &gBatteryData->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS));
+ queue_delayed_work(gBatteryData->wq, &gBatteryData->delay_work, msecs_to_jiffies(100));
+ if( gBatteryData->pdata->batt_low_pin != INVALID_GPIO){
+
+ irq = gpio_to_irq(gBatteryData->pdata->batt_low_pin);
+ disable_irq_wake(irq);
+ disable_irq(irq);
+ }
return 0;
}
#else
gBatteryData->resume = false;
}
#endif
-
-
+
rk30_adc_battery_status_samples(gBatteryData);
if (gBatteryData->poweron_check){
rk30_adc_battery_voltage_samples(gBatteryData);
rk30_adc_battery_capacity_samples(gBatteryData);
- if( 1 == rk30_adc_battery_get_charge_level(gBatteryData)){ // charge
- if(0 == gBatteryData->status_lock ){
- wake_lock(&batt_wake_lock); //lock
- gBatteryData->status_lock = 1;
- }
- }
- else{
- if(1 == gBatteryData->status_lock ){
- wake_unlock(&batt_wake_lock); //unlock
- gBatteryData->status_lock = 0;
+ if( 0 == gBatteryData ->pdata ->charging_sleep){
+ if( 1 == rk30_adc_battery_get_charge_level(gBatteryData)){ // charge
+ if(0 == gBatteryData->status_lock ){
+ wake_lock(&batt_wake_lock); //lock
+ gBatteryData->status_lock = 1;
+ }
}
+ else{
+ if(1 == gBatteryData->status_lock ){
+ wake_unlock(&batt_wake_lock); //unlock
+ gBatteryData->status_lock = 0;
+ }
+ }
}
-
/*update battery parameter after adc and capacity has been changed*/
if(gBatteryData->bat_change){
gBatteryData->bat_change = 0;
rk30_adc_battery_put_capacity(gBatteryData->bat_capacity);
power_supply_changed(&rk30_battery_supply);
+#if defined (CONFIG_BATTERY_RK30_AC_CHARGE)
+ if (gBatteryData->pdata->dc_det_pin == INVALID_GPIO){
+ power_supply_changed(&rk30_ac_supply);
+ }
+#endif
}
if (rk30_battery_dbg_level){
{
AdcTestCnt = 0;
- printk("Status = %d, RealAdcVal = %d, RealVol = %d,gBatVol = %d, gBatCap = %d, RealCapacity = %d, dischargecnt = %d, chargecnt = %d\n",
- gBatteryData->bat_status, gBatteryData->adc_val, adc_to_voltage(gBatteryData->adc_val),
+ pr_bat("Status = %d, RealAdcVal = %d, RealVol = %d,gBatVol = %d, gBatCap = %d, RealCapacity = %d, dischargecnt = %d, chargecnt = %d\n",
+ gBatteryData->bat_status, gBatteryData->adc_val, rk_adc_voltage(gBatteryData->adc_val),
gBatteryData->bat_voltage, gBatteryData->bat_capacity, gBatteryData->capacitytmp, gBatteryData->gBatCapacityDisChargeCnt,gBatteryData-> gBatCapacityChargeCnt);
}
if (pdata->io_init) {
pdata->io_init();
+ return 0;
}
//charge control pin
return -1;
}
-//extern void kernel_power_off(void);
+extern void kernel_power_off(void);
static void rk30_adc_battery_check(struct rk30_adc_battery_data *bat)
{
int i;
}
-
+#if 0
#if 1
rk30_adc_battery_poweron_capacity_check();
#else
gBatteryData->poweron_check = 1;
#endif
gBatteryData->poweron_check = 0;
-
+#endif
/*******************************************
//¿ª»ú²ÉÑùµ½µÄµçѹºÍÉϴιػú±£´æµçѹÏà²î½Ï´ó£¬Ôõô´¦Àí£¿
if (bat->bat_capacity > old_capacity)
if (bat->bat_capacity == 0) bat->bat_capacity = 1;
-#if 0
- if ((bat->bat_voltage <= batt_table[0].dis_charge_vol+ 50)&&(bat->bat_status != POWER_SUPPLY_STATUS_CHARGING)){
- kernel_power_off();
- }
-#endif
+ if(1==gBatteryData -> pdata->low_voltage_protection)
+
+ if ((bat->bat_voltage <= batt_table[0].dis_charge_vol+ 50)&&(bat->bat_status != POWER_SUPPLY_STATUS_CHARGING)){
+ kernel_power_off();
+ }
+
}
static void rk30_adc_battery_callback(struct adc_client *client, void *param, int result)
return;
}
-#if 0
+#if 1
static void rk30_adc_battery_lowerpower_delaywork(struct work_struct *work)
{
- struct rk30_adc_battery_platform_data *pdata;
int irq;
+ if( gBatteryData->pdata->batt_low_pin != INVALID_GPIO){
+ irq = gpio_to_irq(gBatteryData->pdata->batt_low_pin);
+ disable_irq(irq);
+ }
+
printk("lowerpower\n");
rk28_send_wakeup_key(); // wake up the system
return;
static irqreturn_t rk30_adc_battery_low_wakeup(int irq,void *dev_id)
{
-
- schedule_work(&gBatteryData->lowerpower_work);
+ queue_work(gBatteryData->wq, &gBatteryData->lowerpower_work);
return IRQ_HANDLED;
}
struct adc_client *client;
struct rk30_adc_battery_data *data;
struct rk30_adc_battery_platform_data *pdata = pdev->dev.platform_data;
-
+
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL) {
ret = -ENOMEM;
goto err_data_alloc_failed;
}
+
+ memset(data, 0, sizeof(struct rk30_adc_battery_data));
gBatteryData = data;
-
platform_set_drvdata(pdev, data);
data->pdata = pdata;
memset(data->adc_samples, 0, sizeof(int)*(NUM_VOLTAGE_SAMPLE + 2));
//register adc for battery sample
- client = adc_register(0, rk30_adc_battery_callback, NULL); //pdata->adc_channel = ani0
+ if(0 == pdata->adc_channel)
+ client = adc_register(0, rk30_adc_battery_callback, NULL); //pdata->adc_channel = ani0
+ else
+ client = adc_register(pdata->adc_channel, rk30_adc_battery_callback, NULL);
if(!client)
goto err_adc_register_failed;
data->wq = create_singlethread_workqueue("adc_battd");
INIT_DELAYED_WORK(&data->delay_work, rk30_adc_battery_timer_work);
+
//Power on Battery detect
rk30_adc_battery_check(data);
- queue_delayed_work(data->wq, &data->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS));
+ if(1 == pdata->save_capacity ){
+ queue_delayed_work(data->wq, &data->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS*10));
+ gBatteryData->poweron_check = 1;
+ }else{
+ queue_delayed_work(data->wq, &data->delay_work, msecs_to_jiffies(TIMER_MS_COUNTS));
+ gBatteryData->poweron_check = 0;
+ }
#if defined (CONFIG_BATTERY_RK30_AC_CHARGE)
ret = power_supply_register(&pdev->dev, &rk30_ac_supply);
}
#endif
-#if 0
+#if 1
// batt low irq lowerpower_work
if( pdata->batt_low_pin != INVALID_GPIO){
INIT_WORK(&data->lowerpower_work, rk30_adc_battery_lowerpower_delaywork);
printk("failed to request batt_low_irq irq\n");
goto err_lowpowerirq_failed;
}
- enable_irq_wake(irq);
+ disable_irq(irq);
+
}
#endif
err_dcirq_failed:
free_irq(gpio_to_irq(pdata->dc_det_pin), data);
-#if 0
+#if 1
err_lowpowerirq_failed:
free_irq(gpio_to_irq(pdata->batt_low_pin), data);
#endif
platform_driver_unregister(&rk30_adc_battery_driver);
}
-subsys_initcall(rk30_adc_battery_init);//subsys_initcall(rk30_adc_battery_init);
+//subsys_initcall(rk30_adc_battery_init);//subsys_initcall(rk30_adc_battery_init);
+module_init(rk30_adc_battery_init);//subsys_initcall(rk30_adc_battery_init);
+
module_exit(rk30_adc_battery_exit);
MODULE_DESCRIPTION("Battery detect driver for the rk30");