⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sharpsl_pm.c

📁 linux2.6.16版本
💻 C
📖 第 1 页 / 共 2 页
字号:
	return 0;}static int sharpsl_check_battery_voltage(void){	int val, i, buff[5];	/* disable charge, enable discharge */	sharpsl_pm.machinfo->charge(0);	sharpsl_pm.machinfo->discharge(1);	mdelay(SHARPSL_WAIT_DISCHARGE_ON);	if (sharpsl_pm.machinfo->discharge1)		sharpsl_pm.machinfo->discharge1(1);	/* Check battery voltage */	for (i=0; i<5; i++) {		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);	}	if (sharpsl_pm.machinfo->discharge1)		sharpsl_pm.machinfo->discharge1(0);	sharpsl_pm.machinfo->discharge(0);	val = get_select_val(buff);	dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);	if (val < SHARPSL_CHARGE_ON_VOLT)		return -1;	return 0;}static int sharpsl_ac_check(void){	int temp, i, buff[5];	for (i=0; i<5; i++) {		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);	}	temp = get_select_val(buff);	dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);	if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) {		dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");		return -1;	}	return 0;}#ifdef CONFIG_PMstatic int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state){	sharpsl_pm.flags |= SHARPSL_SUSPENDED;	flush_scheduled_work();	if (sharpsl_pm.charge_mode == CHRG_ON)		sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;	else		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;	return 0;}static int sharpsl_pm_resume(struct platform_device *pdev){	/* Clear the reset source indicators as they break the bootloader upon reboot */	RCSR = 0x0f;	sharpsl_average_clear();	sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;	sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;	return 0;}static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state){	dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);	dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);	/* not charging and AC-IN! */	if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) {		dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");		sharpsl_pm.charge_mode = CHRG_OFF;		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;		sharpsl_off_charge_battery();	}	sharpsl_pm.machinfo->presuspend();	PEDR = 0xffffffff; /* clear it */	sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;	if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {		RTSR &= RTSR_ALE;		RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;		dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);		sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;	} else if (alarm_enable) {		RTSR &= RTSR_ALE;		RTAR = alarm_time;		dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);	} else {		dev_dbg(sharpsl_pm.dev, "No alarms set.\n");	}	pxa_pm_enter(state);	sharpsl_pm.machinfo->postsuspend();	dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);}static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state){	if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )	{		if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {			dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");			corgi_goto_sleep(alarm_time, alarm_enable, state);			return 1;		}		if(sharpsl_off_charge_battery()) {			dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");			corgi_goto_sleep(alarm_time, alarm_enable, state);			return 1;		}		dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");	}	if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) )	{		dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");		corgi_goto_sleep(alarm_time, alarm_enable, state);		return 1;	}	return 0;}static int corgi_pxa_pm_enter(suspend_state_t state){	unsigned long alarm_time = RTAR;	unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);	dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");	corgi_goto_sleep(alarm_time, alarm_status, state);	while (corgi_enter_suspend(alarm_time,alarm_status,state))		{}	dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");	return 0;}#endif/* * Check for fatal battery errors * Fatal returns -1 */static int sharpsl_fatal_check(void){	int buff[5], temp, i, acin;	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");	/* Check AC-Adapter */	acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {		sharpsl_pm.machinfo->charge(0);		udelay(100);		sharpsl_pm.machinfo->discharge(1);	/* enable discharge */		mdelay(SHARPSL_WAIT_DISCHARGE_ON);	}	if (sharpsl_pm.machinfo->discharge1)		sharpsl_pm.machinfo->discharge1(1);	/* Check battery : check inserting battery ? */	for (i=0; i<5; i++) {		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);	}	if (sharpsl_pm.machinfo->discharge1)		sharpsl_pm.machinfo->discharge1(0);	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {		udelay(100);		sharpsl_pm.machinfo->charge(1);		sharpsl_pm.machinfo->discharge(0);	}	temp = get_select_val(buff);	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT));	if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||			(!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))		return -1;	return 0;}static int sharpsl_off_charge_error(void){	dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n");	sharpsl_pm.machinfo->charge(0);	sharpsl_pm_led(SHARPSL_LED_ERROR);	sharpsl_pm.charge_mode = CHRG_ERROR;	return 1;}/* * Charging Control while suspended * Return 1 - go straight to sleep * Return 0 - sleep or wakeup depending on other factors */static int sharpsl_off_charge_battery(void){	int time;	dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);	if (sharpsl_pm.charge_mode == CHRG_OFF) {		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");		/* AC Check */		if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))			return sharpsl_off_charge_error();		/* Start Charging */		sharpsl_pm_led(SHARPSL_LED_ON);		sharpsl_pm.machinfo->charge(0);		mdelay(SHARPSL_CHARGE_WAIT_TIME);		sharpsl_pm.machinfo->charge(1);		sharpsl_pm.charge_mode = CHRG_ON;		sharpsl_pm.full_count = 0;		return 1;	} else if (sharpsl_pm.charge_mode != CHRG_ON) {		return 1;	}	if (sharpsl_pm.full_count == 0) {		int time;		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");		if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))			return sharpsl_off_charge_error();		sharpsl_pm.machinfo->charge(0);		mdelay(SHARPSL_CHARGE_WAIT_TIME);		sharpsl_pm.machinfo->charge(1);		sharpsl_pm.charge_mode = CHRG_ON;		mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);		time = RCNR;		while(1) {			/* Check if any wakeup event had occured */			if (sharpsl_pm.machinfo->charger_wakeup() != 0)				return 0;			/* Check for timeout */			if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)				return 1;			if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {				dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");	   			sharpsl_pm.full_count++;				sharpsl_pm.machinfo->charge(0);				mdelay(SHARPSL_CHARGE_WAIT_TIME);				sharpsl_pm.machinfo->charge(1);				return 1;			}		}	}	dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");	mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);	time = RCNR;	while(1) {		/* Check if any wakeup event had occured */		if (sharpsl_pm.machinfo->charger_wakeup() != 0)			return 0;		/* Check for timeout */		if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {			if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {				dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");				sharpsl_pm.full_count = 0;			}			sharpsl_pm.full_count++;			return 1;		}		if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {			dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");			sharpsl_pm_led(SHARPSL_LED_OFF);			sharpsl_pm.machinfo->charge(0);			sharpsl_pm.charge_mode = CHRG_DONE;			return 1;		}	}}static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf){	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);}static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf){	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);}static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);extern void (*apm_get_power_status)(struct apm_power_info *);static void sharpsl_apm_get_power_status(struct apm_power_info *info){	info->ac_line_status = sharpsl_pm.battstat.ac_status;	if (sharpsl_pm.charge_mode == CHRG_ON)		info->battery_status = APM_BATTERY_STATUS_CHARGING;	else		info->battery_status = sharpsl_pm.battstat.mainbat_status;	info->battery_flag = (1 << info->battery_status);	info->battery_life = sharpsl_pm.battstat.mainbat_percent;}static struct pm_ops sharpsl_pm_ops = {	.pm_disk_mode	= PM_DISK_FIRMWARE,	.prepare	= pxa_pm_prepare,	.enter		= corgi_pxa_pm_enter,	.finish		= pxa_pm_finish,};static int __init sharpsl_pm_probe(struct platform_device *pdev){	if (!pdev->dev.platform_data)		return -EINVAL;	sharpsl_pm.dev = &pdev->dev;	sharpsl_pm.machinfo = pdev->dev.platform_data;	sharpsl_pm.charge_mode = CHRG_OFF;	sharpsl_pm.flags = 0;	init_timer(&sharpsl_pm.ac_timer);	sharpsl_pm.ac_timer.function = sharpsl_ac_timer;	init_timer(&sharpsl_pm.chrg_full_timer);	sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;	sharpsl_pm.machinfo->init();	device_create_file(&pdev->dev, &dev_attr_battery_percentage);	device_create_file(&pdev->dev, &dev_attr_battery_voltage);	apm_get_power_status = sharpsl_apm_get_power_status;	pm_set_ops(&sharpsl_pm_ops);	mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));	return 0;}static int sharpsl_pm_remove(struct platform_device *pdev){	pm_set_ops(NULL);	device_remove_file(&pdev->dev, &dev_attr_battery_percentage);	device_remove_file(&pdev->dev, &dev_attr_battery_voltage);	sharpsl_pm.machinfo->exit();	del_timer_sync(&sharpsl_pm.chrg_full_timer);	del_timer_sync(&sharpsl_pm.ac_timer);	return 0;}static struct platform_driver sharpsl_pm_driver = {	.probe		= sharpsl_pm_probe,	.remove		= sharpsl_pm_remove,	.suspend	= sharpsl_pm_suspend,	.resume		= sharpsl_pm_resume,	.driver		= {		.name		= "sharpsl-pm",	},};static int __devinit sharpsl_pm_init(void){	return platform_driver_register(&sharpsl_pm_driver);}static void sharpsl_pm_exit(void){ 	platform_driver_unregister(&sharpsl_pm_driver);}late_initcall(sharpsl_pm_init);module_exit(sharpsl_pm_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -