Exemplo n.º 1
0
void NvBatteryEventHandlerThread(void *args)
{
	NvU8	BatteryState = 0, BatteryEvent = 0;
	NvBool  suspend_flag;

	for (;;) {
        NvOsSemaphoreWaitTimeout(batt_dev->hOdmSemaphore, 
		                         batt_dev->batt_status_poll_period);
		
		if (batt_dev->exitThread)
			break;

		if (!batt_dev->hOdmBattDev)
			continue;
        
        NvOsMutexLock(batt_dev->hBattEventMutex);
	    suspend_flag = batt_dev->inSuspend;
        NvOsMutexUnlock(batt_dev->hBattEventMutex);
		if (suspend_flag)
			continue;

	    pr_info("\tBATTERY: polling battery information! --->>>\n");
		
		NvOdmBatteryGetBatteryStatus(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main,
			&BatteryState);

		NvOdmBatteryGetEvent(batt_dev->hOdmBattDev, &BatteryEvent);

		if ((BatteryState == NVODM_BATTERY_STATUS_UNKNOWN) ||
			(BatteryEvent == NvOdmBatteryEventType_Num)) {
			/* Do nothing */
		} else {
			if (BatteryEvent & NvOdmBatteryEventType_RemainingCapacityAlarm) {
				if (BatteryState == (NVODM_BATTERY_STATUS_CRITICAL |
					NVODM_BATTERY_STATUS_VERY_CRITICAL |
					NVODM_BATTERY_STATUS_DISCHARGING)) {
					pr_info("nvec_battery:calling kernel_power_off...\n");
					kernel_power_off();
				}
			} else {
				/* Update the battery and power supply info for other events */
				power_supply_changed(&tegra_power_supplies[NvCharger_Type_Battery]);
				//power_supply_changed(&tegra_power_supplies[NvCharger_Type_USB]); //
				power_supply_changed(&tegra_power_supplies[NvCharger_Type_AC]);
			}
		}
	}
}
Exemplo n.º 2
0
void NvBatteryEventHandlerThread(void *args)
{
	NvU8	BatteryState = 0, BatteryEvent = 0;

	for (;;) {
		NvOsSemaphoreWait(batt_dev->hOdmSemaphore);

		if (batt_dev->exitThread)
			break;

		if (!batt_dev->hOdmBattDev)
			continue;

		NvOdmBatteryGetBatteryStatus(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main,
			&BatteryState);

		NvOdmBatteryGetEvent(batt_dev->hOdmBattDev, &BatteryEvent);
NvOsDebugPrintf("ec_rs BatteryEvent = 0x%x\n", BatteryEvent);
		if ((BatteryState == NVODM_BATTERY_STATUS_UNKNOWN) ||
			(BatteryEvent == NvOdmBatteryEventType_Num)) {
			/* Do nothing */
		} else {
			//if (BatteryEvent & NvOdmBatteryEventType_RemainingCapacityAlarm) {
			if (BatteryEvent & NvOdmBatteryEventType_LowBatteryIntr) {
				//Daniel 20100701, just force off while receive LOW_BAT# interrupt(not low capacity alarm).
				//if (BatteryState == (NVODM_BATTERY_STATUS_CRITICAL |
				//	NVODM_BATTERY_STATUS_VERY_CRITICAL |
				//	NVODM_BATTERY_STATUS_DISCHARGING)) {
				//	pr_info("nvec_battery:calling kernel_power_off...\n");
NvOsDebugPrintf("ec_rs batt low battery interrupt.\r\n");
				//	kernel_power_off();
				//}
			} else {
				/* Update the battery and power supply info for other events */
				power_supply_changed(&tegra_power_supplies[NvPowerSupply_TypeBattery]);
				power_supply_changed(&tegra_power_supplies[NvPowerSupply_TypeAC]);
			}
		}
	}
}
Exemplo n.º 3
0
static int tegra_battery_get_property(struct power_supply *psy,
	enum power_supply_property psp, union power_supply_propval *val)
{
	NvU8 name[BATTERY_INFO_NAME_LEN] = {0};
	int technology = 0;
	NvU8 state = 0;
    static NvU8 prop_state = 0; //

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		if (!NvOdmBatteryGetBatteryStatus(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main, &state))
			return -ENODEV;

        prop_state = state; //
		
		if (state == NVODM_BATTERY_STATUS_UNKNOWN) {
			batt_dev->present = NV_FALSE;
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		} else if (state == NVODM_BATTERY_STATUS_NO_BATTERY) {
			batt_dev->present = NV_FALSE;
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		} else if (state & NVODM_BATTERY_STATUS_CHARGING) {
			batt_dev->present = NV_TRUE;
			val->intval = POWER_SUPPLY_STATUS_CHARGING;
		} else if (state & NVODM_BATTERY_STATUS_DISCHARGING) {
			batt_dev->present = NV_TRUE;
			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
		} else if (state & NVODM_BATTERY_STATUS_IDLE) {
			batt_dev->present = NV_TRUE;
			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
		}

		if (!batt_dev->present ) {
			batt_dev->voltage = 0;
			batt_dev->current_ma = 0;
			batt_dev->current_avg  = 0;
			batt_dev->temp = 0;
			batt_dev->percent_remain = 0;
			batt_dev->lifetime = 0;
			batt_dev->consumed = 0;
			batt_dev->capacity = 0;
			batt_dev->capacity_crit = 0;
			batt_dev->capacity_remain = 0;
		}
		else {
			/*
			 * Getting the battery info once here so for the other property
			 * requests there will not be lot of ec req
			 */
			if (tegra_battery_data(NvOdmBatteryInst_Main)) {
				if (batt_dev->percent_remain == 100) {
					val->intval = POWER_SUPPLY_STATUS_FULL;
				}
				else if (batt_dev->capacity == 0) {
				    val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
				}
			}
		}
		break;

	case POWER_SUPPLY_PROP_HEALTH:
		if (batt_dev->present)
			val->intval = POWER_SUPPLY_HEALTH_GOOD;
		else
			val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
		break;

	case POWER_SUPPLY_PROP_PRESENT:
		//if (!NvOdmBatteryGetBatteryStatus(batt_dev->hOdmBattDev,
		//	NvOdmBatteryInst_Main, &state))
		//	return -EINVAL; //
        state = prop_state; //

		if (state == NVODM_BATTERY_STATUS_UNKNOWN) {
			batt_dev->present = NV_FALSE;
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		} else {
			if (state == NVODM_BATTERY_STATUS_NO_BATTERY) {
				 batt_dev->present = NV_FALSE;
				 val->intval = NV_FALSE;
			}

			if (state & (NVODM_BATTERY_STATUS_HIGH |
					NVODM_BATTERY_STATUS_LOW |
					NVODM_BATTERY_STATUS_CRITICAL |
					NVODM_BATTERY_STATUS_CHARGING |
					NVODM_BATTERY_STATUS_DISCHARGING |
					NVODM_BATTERY_STATUS_IDLE)) {
				batt_dev->present = NV_TRUE;
				val->intval = NV_TRUE;
			}
		}
		break;

	case POWER_SUPPLY_PROP_TECHNOLOGY:
		tegra_get_battery_tech(&technology, NvOdmBatteryInst_Main);
		val->intval = technology;
		break;

	case POWER_SUPPLY_PROP_CAPACITY:
		val->intval = batt_dev->percent_remain;
		break;

	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = batt_dev->voltage*1000;
		break;

	case POWER_SUPPLY_PROP_CURRENT_NOW:
		val->intval = batt_dev->current_ma;
		break;

	case POWER_SUPPLY_PROP_CURRENT_AVG:
		val->intval = batt_dev->current_avg;
		break;

	case POWER_SUPPLY_PROP_CHARGE_NOW:
		val->intval = batt_dev->capacity_remain;
		break;

	case POWER_SUPPLY_PROP_CHARGE_FULL:
		val->intval = batt_dev->capacity;
		break;

	case POWER_SUPPLY_PROP_CHARGE_EMPTY:
		val->intval = batt_dev->capacity_crit;
		break;

	case POWER_SUPPLY_PROP_TEMP:
		/* returned value is degrees C * 10 */
		val->intval = batt_dev->temp/10;
		break;

	case POWER_SUPPLY_PROP_MODEL_NAME:
		if (!NvOdmBatteryGetModel(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main, name))
			return -EINVAL;

		strncpy((char *)val->strval, name, strlen(name));
		break;

	case POWER_SUPPLY_PROP_MANUFACTURER:
		if (!NvOdmBatteryGetManufacturer(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main, name))
			return -EINVAL;

		strncpy((char *)val->strval, name, strlen(name));
		break;

	default:
		return -EINVAL;
	}

	return 0;
}
Exemplo n.º 4
0
static int tegra_battery_get_property(struct power_supply *psy,
	enum power_supply_property psp, union power_supply_propval *val)
{
	NvU8 name[BATTERY_INFO_NAME_LEN] = {0};
	int technology = 0;
	NvU8 state = 0;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		if (!NvOdmBatteryGetBatteryStatus(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main, &state))
			return -ENODEV;

		if (state == NVODM_BATTERY_STATUS_UNKNOWN) {
			batt_dev->present = NV_FALSE;
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		} else if (state == NVODM_BATTERY_STATUS_NO_BATTERY) {
			batt_dev->present = NV_FALSE;
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		} else if (state & NVODM_BATTERY_STATUS_CHARGING) {
			batt_dev->present = NV_TRUE;
			val->intval = POWER_SUPPLY_STATUS_CHARGING;
		} else if (state & NVODM_BATTERY_STATUS_DISCHARGING) {
			batt_dev->present = NV_TRUE;
			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
		} else if (state & NVODM_BATTERY_STATUS_IDLE) {
			batt_dev->present = NV_TRUE;
			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
		}

		if (!batt_dev->present ) {
			batt_dev->voltage = 0;
			batt_dev->current_ma = 0;
			batt_dev->current_avg  = 0;
			batt_dev->temp = 0;
			batt_dev->percent_remain = 0;
			batt_dev->lifetime = 0;
			batt_dev->consumed = 0;
			batt_dev->capacity = 0;
			batt_dev->capacity_crit = 0;
			batt_dev->capacity_remain = 0;
		}
		else {
			/*
			 * Getting the battery info once here so for the other property
			 * requests there will not be lot of ec req
			 */
			if (tegra_battery_data(NvOdmBatteryInst_Main)) {
				if (batt_dev->percent_remain == 100) {
					val->intval = POWER_SUPPLY_STATUS_FULL;
				}
				//Daniel 20100903, if (batt<=5%) and batt present and discharging, lock suspend.
				if((batt_dev->percent_remain <= 5) && (val->intval == POWER_SUPPLY_STATUS_DISCHARGING)) {
					if(mylock_flag == NV_FALSE) {
						wake_lock(&mylock);
						mylock_flag = NV_TRUE;
						NvOsDebugPrintf("ec_rs batt 5% wake_lock\n");
					}
					//Daniel 20100918, if (batt<=4%) and send batt=0% to trigger shutdown or just call kernel_power_off();.
					if(batt_dev->percent_remain <= 4) {
						NvOsDebugPrintf("ec_rs low_batt_cnt = %d\n", low_batt_cnt);
						batt_dev->percent_remain = 0; //to trigger APP shutdown procedure (workaround, app 5% shutdown isn't ready).
						low_batt_cnt++;
						if(low_batt_cnt > 8) {
							//do it on next battery polling
							NvOsDebugPrintf("ec_rs kernel_power_off.\r\n");
							msleep(500);
							kernel_power_off();
						}
					}
					else
						low_batt_cnt = 0;
				}
				else if(((batt_dev->percent_remain > 5) || (val->intval != POWER_SUPPLY_STATUS_DISCHARGING))) {
					if(mylock_flag == NV_TRUE) {
						wake_unlock(&mylock);
						mylock_flag = NV_FALSE;
						NvOsDebugPrintf("ec_rs batt 5% wake_unlock\n");
					}
				}
			}
		}
		break;

	case POWER_SUPPLY_PROP_HEALTH:
		if (batt_dev->present)
			val->intval = POWER_SUPPLY_HEALTH_GOOD;
		else
			val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
		break;

	case POWER_SUPPLY_PROP_PRESENT:
		if (!NvOdmBatteryGetBatteryStatus(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main, &state))
			return -EINVAL;

		if (state == NVODM_BATTERY_STATUS_UNKNOWN) {
			batt_dev->present = NV_FALSE;
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		} else {
			if (state == NVODM_BATTERY_STATUS_NO_BATTERY) {
				 batt_dev->present = NV_FALSE;
				 val->intval = NV_FALSE;
			}

			if (state & (NVODM_BATTERY_STATUS_HIGH |
					NVODM_BATTERY_STATUS_LOW |
					NVODM_BATTERY_STATUS_CRITICAL |
					NVODM_BATTERY_STATUS_CHARGING |
					NVODM_BATTERY_STATUS_DISCHARGING |
					NVODM_BATTERY_STATUS_IDLE)) {
				batt_dev->present = NV_TRUE;
				val->intval = NV_TRUE;
			}
		}
		break;

	case POWER_SUPPLY_PROP_TECHNOLOGY:
		tegra_get_battery_tech(&technology, NvOdmBatteryInst_Main);
		val->intval = technology;
		break;

	case POWER_SUPPLY_PROP_CAPACITY:
		val->intval = batt_dev->percent_remain;
		break;

	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = batt_dev->voltage*1000;
		break;

	case POWER_SUPPLY_PROP_CURRENT_NOW:
		val->intval = batt_dev->current_ma;
		break;

	case POWER_SUPPLY_PROP_CURRENT_AVG:
		val->intval = batt_dev->current_avg;
		break;

	case POWER_SUPPLY_PROP_CHARGE_NOW:
		val->intval = batt_dev->capacity_remain;
		break;

	case POWER_SUPPLY_PROP_CHARGE_FULL:
		val->intval = batt_dev->capacity;
		break;

	case POWER_SUPPLY_PROP_CHARGE_EMPTY:
		val->intval = batt_dev->capacity_crit;
		break;

	case POWER_SUPPLY_PROP_TEMP:
		/* returned value is degrees C * 10 */
		//Daniel 20100706, its unit is 0.1 degree-K, not 0.01 degree-C.
		//Daniel 20100707, convert from tenths of a degree-K to tenths of a degree-C.
		//val->intval = batt_dev->temp/10;
		val->intval = batt_dev->temp - 2730;
		break;

	case POWER_SUPPLY_PROP_MODEL_NAME:
		if (!NvOdmBatteryGetModel(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main, name))
			return -EINVAL;

		strncpy((char *)val->strval, name, strlen(name));
		break;

	case POWER_SUPPLY_PROP_MANUFACTURER:
		if (!NvOdmBatteryGetManufacturer(batt_dev->hOdmBattDev,
			NvOdmBatteryInst_Main, name))
			return -EINVAL;

		strncpy((char *)val->strval, name, strlen(name));
		break;

	default:
		return -EINVAL;
	}

	return 0;
}