From 820d0e43492111527b824ab33b49d2f7d6f292d4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E7=BD=97=E4=BC=9F?= Date: Wed, 9 Jun 2010 13:24:05 +0000 Subject: [PATCH] modify adckey and battery driver for A7 --- drivers/input/keyboard/rk2818_adckey.c | 50 +++++--- drivers/power/rk2818_battery.c | 166 ++++++++++++++----------- 2 files changed, 128 insertions(+), 88 deletions(-) diff --git a/drivers/input/keyboard/rk2818_adckey.c b/drivers/input/keyboard/rk2818_adckey.c index 445b370871b4..45bc7ccb24eb 100644 --- a/drivers/input/keyboard/rk2818_adckey.c +++ b/drivers/input/keyboard/rk2818_adckey.c @@ -55,7 +55,7 @@ #define ADKEYNUM 10 #define ADKEYCH 1 //ADͨµÀ - +#define KEYPLAY_ON 0 //°´¼ü½ÓͨʱµÄµçƽֵ #define KEY_PHYS_NAME "rk2818_adckey/input0" volatile int gADSampleTimes = 0; @@ -118,15 +118,12 @@ unsigned int rk28_get_keycode(unsigned int advalue,pADC_keyst ptab) return 0; } -#if 0 +#if 1 static irqreturn_t rk28_playkey_irq(int irq, void *handle) { - input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,1); - input_sync(pRk28AdcKey->input_dev); - input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,0); - input_sync(pRk28AdcKey->input_dev); - gFlagPlay = 1; - DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS); + + //gFlagPlay = 1; + //DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS); return IRQ_HANDLED; } @@ -134,10 +131,11 @@ static irqreturn_t rk28_playkey_irq(int irq, void *handle) #endif void rk28_send_wakeup_key( void ) { - input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,1); - input_sync(pRk28AdcKey->input_dev); - input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,0); - input_sync(pRk28AdcKey->input_dev); + input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,1); + input_sync(pRk28AdcKey->input_dev); + input_report_key(pRk28AdcKey->input_dev,KEY_WAKEUP,0); + input_sync(pRk28AdcKey->input_dev); + DBG("Wake up system\n"); } static int rk28_adckey_open(struct input_dev *dev) @@ -184,9 +182,10 @@ static void rk28_adkeyscan_timer(unsigned long data) add_timer(&pRk28AdcKey->timer); /*handle long press of play key*/ - if(gpio_get_value(KEY_PLAYON_PIN) == 0) + if(gpio_get_value(KEY_PLAYON_PIN) == KEYPLAY_ON) { - ++gPlayCount; + if(++gPlayCount > 20000) + gPlayCount = 101; if((2 == gPlayCount) && (0 == gFlagShortPlay)) { gFlagShortPlay = 1; @@ -204,6 +203,12 @@ static void rk28_adkeyscan_timer(unsigned long data) { if (1 == gFlagShortPlay) { + input_report_key(pRk28AdcKey->input_dev,ENDCALL,1); + input_sync(pRk28AdcKey->input_dev); + input_report_key(pRk28AdcKey->input_dev,ENDCALL,0); + input_sync(pRk28AdcKey->input_dev); + DBG("Wake up system,ENDCALL=%d\n",ENDCALL); + input_report_key(pRk28AdcKey->input_dev,KEY_PLAY_SHORT_PRESS,1); input_sync(pRk28AdcKey->input_dev); DBG("Enter::%s,LINE=%d,KEY_PLAY_SHORT_PRESS=%d,1\n",__FUNCTION__,__LINE__,KEY_PLAY_SHORT_PRESS); @@ -355,16 +360,25 @@ static int __devinit rk28_adckey_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to request play key gpio\n"); goto free_gpio; } - - gpio_pull_updown(KEY_PLAYON_PIN,GPIOPullUp); -#if 0 - error = request_irq(gpio_to_irq(KEY_PLAYON_PIN),rk28_playkey_irq,IRQF_TRIGGER_FALLING,NULL,NULL); +#if KEYPLAY_ON + gpio_pull_updown(KEY_PLAYON_PIN,GPIOPullDown); + error = request_irq(gpio_to_irq(KEY_PLAYON_PIN),rk28_playkey_irq,IRQF_TRIGGER_RISING,NULL,NULL); if(error) { printk("unable to request play key irq\n"); goto free_gpio_irq; } #else + gpio_pull_updown(KEY_PLAYON_PIN,GPIOPullUp); + error = request_irq(gpio_to_irq(KEY_PLAYON_PIN),rk28_playkey_irq,IRQF_TRIGGER_FALLING,NULL,NULL); + if(error) + { + printk("unable to request play key irq\n"); + goto free_gpio_irq; + } +#endif + +#if 0 error = gpio_direction_input(KEY_PLAYON_PIN); if (error) { diff --git a/drivers/power/rk2818_battery.c b/drivers/power/rk2818_battery.c index 969f45f60354..e66e8e2fdd4a 100644 --- a/drivers/power/rk2818_battery.c +++ b/drivers/power/rk2818_battery.c @@ -37,13 +37,13 @@ /*******************ÒÔϲÎÊý¿ÉÒÔÐÞ¸Ä******************************/ #define TIMER_MS_COUNTS 50 //¶¨Ê±Æ÷µÄ³¤¶Èms #define SLOPE_SECOND_COUNTS 120 //ͳ¼ÆµçѹбÂʵÄʱ¼ä¼ä¸ôs -#define TIME_UPDATE_STATUS 3000 //¸üеç³Ø״̬µÄʱ¼ä¼ä¸ôms -#define BATT_MAX_VOL_VALUE 4100 //ÂúµçʱµÄµç³Øµçѹ +#define TIME_UPDATE_STATUS 5000 //¸üеç³Ø״̬µÄʱ¼ä¼ä¸ôms +#define BATT_MAX_VOL_VALUE 4180 //ÂúµçʱµÄµç³Øµçѹ FOR A7 #define BATT_ZERO_VOL_VALUE 3400 //¹Ø»úʱµÄµç³Øµçѹ #define BATT_NOMAL_VOL_VALUE 3800 -#define THRESHOLD_VOLTAGE_LEVEL0 4000 -#define THRESHOLD_VOLTAGE_LEVEL1 3800 -#define THRESHOLD_VOLTAGE_LEVEL2 3600 +#define THRESHOLD_VOLTAGE_LEVEL0 4050 +#define THRESHOLD_VOLTAGE_LEVEL1 3950 +#define THRESHOLD_VOLTAGE_LEVEL2 3850 #define THRESHOLD_VOLTAGE_LEVEL3 BATT_ZERO_VOL_VALUE #define THRESHOLD_SLOPE_HIGH 10 //бÂÊÖµ = µçѹ½µµÍµÄËÙ¶È #define THRESHOLD_SLOPE_MID 5 //< THRESHOLD_SLOPE_HIGH @@ -55,7 +55,7 @@ #define BATT_LEVEL_EMPTY 0 #define BATT_PRESENT_TRUE 1 #define BATT_PRESENT_FALSE 0 -#define BAT_1V2_VALUE 1418 +#define BAT_1V2_VALUE 1330 #define CHARGEOK_PIN RK2818_PIN_PH6 #define BAT_LOADER_STATUS 0 //Óõç״̬ @@ -74,11 +74,14 @@ #define NUM_VOLTAGE_SAMPLE ((1000*SLOPE_SECOND_COUNTS) / TIMER_MS_COUNTS) //´æ´¢µÄ²ÉÑùµã¸öÊý +int gBatLastStatus = 0; int gBatStatus = POWER_SUPPLY_STATUS_UNKNOWN; int gBatHealth = POWER_SUPPLY_HEALTH_GOOD; -int gBatLastCapacity = 0; +int gBatLastPresent = 0; int gBatPresent = BATT_PRESENT_TRUE; +int gBatLastVoltage = 0; int gBatVoltage = BATT_NOMAL_VOL_VALUE; +int gBatLastCapacity = 0; int gBatCapacity = ((BATT_NOMAL_VOL_VALUE-BATT_ZERO_VOL_VALUE)*100/(BATT_MAX_VOL_VALUE-BATT_ZERO_VOL_VALUE)); int gBatVoltageSamples[NUM_VOLTAGE_SAMPLE]; @@ -99,6 +102,7 @@ int gBatUseStatus = BAT_LOADER_STATUS; extern int dwc_vbus_status(void); +extern int get_msc_connect_flag(void); struct rk2818_battery_data { int irq; @@ -138,15 +142,13 @@ typedef enum { static int rk2818_get_charge_status(void) { -#if 0 - return dwc_vbus_status(); -#else //DBG("gAdcValue[CHN_USB_ADC]=%d\n",gAdcValue[CHN_USB_ADC]); - if(gAdcValue[CHN_USB_ADC] > 50) + if(gAdcValue[CHN_USB_ADC] > 250) //about 0.5V + return 1; + else if((1 == dwc_vbus_status())&& (0 == get_msc_connect_flag())) return 1; else return 0; -#endif } static void rk2818_get_bat_status(struct rk2818_battery_data *bat) @@ -154,7 +156,10 @@ static void rk2818_get_bat_status(struct rk2818_battery_data *bat) if(rk2818_get_charge_status() == 1) { if(gpio_get_value (CHARGEOK_PIN) == 1) //CHG_OK ==0 - gBatStatus = POWER_SUPPLY_STATUS_FULL; + { + gBatStatus = POWER_SUPPLY_STATUS_FULL; + DBG("Battery is Full!\n"); + } else gBatStatus = POWER_SUPPLY_STATUS_CHARGING; } @@ -178,7 +183,7 @@ static void rk2818_get_bat_present(struct rk2818_battery_data *bat) static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat) { unsigned long value; - int i,*pSamp,*pStart = &gBatVoltageSamples[0]; + int i,*pSamp,*pStart = &gBatVoltageSamples[0],num = 0; int temp[2] = {0,0}; value = gAdcValue[CHN_BAT_ADC]; if(0 != gAdcValue[3]) @@ -190,15 +195,34 @@ static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat) gBatVoltage = BATT_ZERO_VOL_VALUE - 10; *pSamples = gBatVoltage; - if((++pSamples - pStart) > NUM_VOLTAGE_SAMPLE) + num = ++pSamples - pStart; + if(num > NUM_VOLTAGE_SAMPLE) { pSamples = pStart; gFlagLoop = 1; } + + if(gFlagLoop != 1) //δ²É¼¯µ½ NUM_VOLTAGE_SAMPLE¸öµçѹֵ + { + for(i=(num>>1); i>1); + gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min); + if(gBatCapacity >= 100) + gBatCapacity = 100; + else if(gBatCapacity < 0) + gBatCapacity = 0; + } + //DBG("gBatVoltage=%d,gBatCapacity=%d,num=%d\n",gBatVoltage,gBatCapacity,num); + } + else { + //compute the average voltage after samples-count is larger than NUM_VOLTAGE_SAMPLE pSamp = pSamples; for(i=0; i<(NUM_VOLTAGE_SAMPLE >> 1); i++) { @@ -217,6 +241,8 @@ static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat) gBatVoltageValue[1] = temp[1] / (NUM_VOLTAGE_SAMPLE >> 1); + gBatVoltage = gBatVoltageValue[1]; + gBatSlopeValue = gBatVoltageValue[0] - gBatVoltageValue[1]; //DBG("gBatSlopeValue=%d,gBatVoltageValue[1]=%d\n",gBatSlopeValue,gBatVoltageValue[1]); @@ -232,17 +258,17 @@ static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat) //Á¬Ðø¶à´Îµçѹ½µµÍÂÊΪ¸º±íʾ³äµç״̬ if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL0) - gMaxCharge = 6; + gMaxCharge = 2; else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL1) - gMaxCharge = 8; + gMaxCharge = 3; else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL2) - gMaxCharge = 8; + gMaxCharge = 4; else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL3) - gMaxCharge = 6; - if(++gNumCharge >= gMaxCharge) + gMaxCharge = 2; + if((++gNumCharge >= gMaxCharge) && (gBatStatus != POWER_SUPPLY_STATUS_NOT_CHARGING)) { gBatUseStatus = BAT_CHARGE_STATUS; //³äµç״̬ - gNumCharge = gMaxCharge - 2; + gNumCharge = gMaxCharge ; } else { @@ -255,18 +281,18 @@ static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat) gNumCharge = 0; //Á¬Ðø¶à´Îµçѹ½µµÍÂÊΪÕý±íʾÓõç״̬ if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL0) - gMaxCharge = 4; + gMaxCharge = 2; else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL1) - gMaxCharge = 6; + gMaxCharge = 3; else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL2) - gMaxCharge = 6; + gMaxCharge = 4; else if(gBatVoltageValue[1] >= THRESHOLD_VOLTAGE_LEVEL3) - gMaxLoader = 4; + gMaxLoader = 2; - if(++gNumLoader >= gMaxLoader) + if((++gNumLoader >= gMaxLoader) && (gBatStatus == POWER_SUPPLY_STATUS_NOT_CHARGING)) { gBatUseStatus = BAT_LOADER_STATUS; - gNumLoader = gMaxLoader - 2; + gNumLoader = gMaxLoader; } else { @@ -276,6 +302,7 @@ static void rk2818_get_bat_voltage(struct rk2818_battery_data *bat) } } } + } @@ -286,33 +313,35 @@ static void rk2818_get_bat_capacity(struct rk2818_battery_data *bat) if(gBatUseStatus == BAT_LOADER_STATUS) { //Óõç״̬ϳöÏÖ¸ºÔرäСÈÝÁ¿±ä´óʱ£¬²»¸üÐÂÈÝÁ¿Öµ - if((gBatLastCapacity ==0) || (gBatCapacity <= gBatLastCapacity)) + if((gBatLastVoltage == 0) || (gBatVoltage <= gBatLastVoltage)) { - gBatCapacity = ((gBatVoltageValue[1] - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min); + gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min); if(gBatCapacity >= 100) gBatCapacity = 100; else if(gBatCapacity < 0) gBatCapacity = 0; - gBatLastCapacity = gBatCapacity; + gBatLastVoltage = gBatVoltage; } } else if(gBatUseStatus == BAT_CHARGE_STATUS) { //³äµç״̬ÏÂÈÝÁ¿½µµÍʱ£¬²»¸üÐÂÈÝÁ¿Öµ - if((gBatCapacity >= gBatLastCapacity) || (gBatLastCapacity ==0)) + if((gBatLastVoltage == 0) || (gBatVoltage >= gBatLastVoltage)) { - gBatCapacity = ((gBatVoltageValue[1] - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min); + gBatCapacity = ((gBatVoltage - bat->bat_min) * 100) / (bat->bat_max - bat->bat_min); if(gBatCapacity >= 100) gBatCapacity = 100; else if(gBatCapacity < 0) gBatCapacity = 0; - gBatLastCapacity = gBatCapacity; + gBatLastVoltage = gBatVoltage; + //DBG("BAT_CHARGE_STATUS\n"); } } //±ä»¯×´Ì¬²»¸üÐÂÈÝÁ¿ + //DBG("BAT_CHANGE_STATUS\n"); } else { @@ -326,41 +355,38 @@ static void rk2818_get_bat_capacity(struct rk2818_battery_data *bat) static void rk2818_battery_timer_work(struct work_struct *work) -{ +{ rk2818_get_bat_status(gBatteryData); rk2818_get_bat_health(gBatteryData); rk2818_get_bat_present(gBatteryData); rk2818_get_bat_voltage(gBatteryData); rk2818_get_bat_capacity(gBatteryData); - - if(++gNumSamples > TIME_UPDATE_STATUS/TIMER_MS_COUNTS) + + /*update battery parameter after adc and capacity has been changed*/ + if((gBatStatus != gBatLastStatus) || (gBatPresent != gBatLastPresent) || (gBatCapacity != gBatLastCapacity)) { - gNumSamples = 0; - if(gBatVoltage != 0) //update battery parameter after adc + //gNumSamples = 0; + gBatLastStatus = gBatStatus; + gBatLastPresent = gBatPresent; + gBatLastCapacity = gBatCapacity; + + if(!( strstr(saved_command_line,"nfsroot=") ) ) { - if(!( strstr(saved_command_line,"nfsroot=") ) ) - { - power_supply_changed(&gBatteryData->battery); - power_supply_changed(&gBatteryData->usb); - power_supply_changed(&gBatteryData->ac); - } + power_supply_changed(&gBatteryData->battery); + } + else + { + DBG("voltage has changed\n"); + DBG("gBatStatus=%d,gBatHealth=%d,gBatPresent=%d\n",gBatStatus,gBatHealth,gBatPresent); + if(gBatVoltageValue[1] == 0) + DBG("gBatVoltage=%d\n",gBatVoltage); else - { - DBG("voltage has changed\n"); - DBG("gBatStatus=%d,gBatHealth=%d,gBatPresent=%d\n",gBatStatus,gBatHealth,gBatPresent); - if(gBatVoltageValue[1] == 0) - DBG("gBatVoltage=%d\n",gBatVoltage); - else - DBG("gBatVoltage=%d\n",gBatVoltageValue[1]); - if(gBatLastCapacity == 0) - DBG("gBatCapacity=%d%%\n",gBatCapacity); - else - DBG("gBatCapacity=%d%%\n",gBatLastCapacity); - } - + DBG("gBatVoltage=%d\n",gBatVoltageValue[1]); + DBG("gBatCapacity=%d%%\n",gBatCapacity); } } + } @@ -382,10 +408,10 @@ static int rk2818_usb_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_ONLINE: if (psy->type == POWER_SUPPLY_TYPE_USB) - val->intval = (charger == CHARGER_AC ? 1 : 0); - else - val->intval = 0; + val->intval = dwc_vbus_status(); + DBG("%s:%d\n",__FUNCTION__,val->intval); break; + default: return -EINVAL; } @@ -407,12 +433,15 @@ static int rk2818_ac_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_ONLINE: if (psy->type == POWER_SUPPLY_TYPE_MAINS) - val->intval = (charger == CHARGER_AC ? 1 : 0); - else if (psy->type == POWER_SUPPLY_TYPE_USB) - val->intval = (charger == CHARGER_USB ? 1 : 0); - else - val->intval = 0; + { + if(gAdcValue[CHN_USB_ADC] > 250) + val->intval = 1; + else + val->intval = 0; + } + DBG("%s:%d\n",__FUNCTION__,val->intval); break; + default: ret = -EINVAL; break; @@ -452,10 +481,7 @@ static int rk2818_battery_get_property(struct power_supply *psy, val->intval = POWER_SUPPLY_TECHNOLOGY_LION; break; case POWER_SUPPLY_PROP_CAPACITY: - if(gBatLastCapacity == 0) val->intval = gBatCapacity; - else - val->intval = gBatLastCapacity; DBG("gBatCapacity=%d%%\n",val->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: -- 2.34.1