-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 24004 b: refs/heads/master c: 48a03ae h: refs/heads/master v: v3
- Loading branch information
Pavel Machek
authored and
Russell King
committed
Mar 25, 2006
1 parent
b208950
commit a528ddd
Showing
2 changed files
with
279 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 091c539f08a6700e0cca8cd620c3d72dd9f9e2bb | ||
refs/heads/master: 48a03ae863e0031def037fc828d7ea1a29b6fb7b |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
/* | ||
* Based on spitz_pm.c and sharp code. | ||
* | ||
* Copyright (C) 2001 SHARP | ||
* Copyright 2005 Pavel Machek <pavel@suse.cz> | ||
* | ||
* Distribute under GPLv2. | ||
* | ||
* Li-ion batteries are angry beasts, and they like to explode. This driver is not finished, | ||
* and sometimes charges them when it should not. If it makes angry lithium to come your way... | ||
* ...well, you have been warned. | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/stat.h> | ||
#include <linux/init.h> | ||
#include <linux/kernel.h> | ||
#include <linux/delay.h> | ||
#include <linux/interrupt.h> | ||
#include <linux/device.h> | ||
#include <linux/platform_device.h> | ||
|
||
#include <asm/irq.h> | ||
#include <asm/mach-types.h> | ||
#include <asm/hardware.h> | ||
#include <asm/hardware/scoop.h> | ||
#include <asm/dma.h> | ||
#include <asm/arch/collie.h> | ||
#include <asm/mach/sharpsl_param.h> | ||
#include <asm/hardware/sharpsl_pm.h> | ||
|
||
#include "../drivers/mfd/ucb1x00.h" | ||
|
||
static struct ucb1x00 *ucb; | ||
static int ad_revise; | ||
|
||
#define ADCtoPower(x) ((330 * x * 2) / 1024) | ||
|
||
static void collie_charger_init(void) | ||
{ | ||
int err; | ||
|
||
if (sharpsl_param.adadj != -1) { | ||
ad_revise = sharpsl_param.adadj; | ||
} | ||
|
||
/* Register interrupt handler. */ | ||
if ((err = request_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr, SA_INTERRUPT, | ||
"ACIN", sharpsl_ac_isr))) { | ||
printk("Could not get irq %d.\n", COLLIE_IRQ_GPIO_AC_IN); | ||
return; | ||
} | ||
if ((err = request_irq(COLLIE_IRQ_GPIO_CO, sharpsl_chrg_full_isr, SA_INTERRUPT, | ||
"CO", sharpsl_chrg_full_isr))) { | ||
free_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr); | ||
printk("Could not get irq %d.\n", COLLIE_IRQ_GPIO_CO); | ||
return; | ||
} | ||
|
||
ucb1x00_io_set_dir(ucb, 0, COLLIE_TC35143_GPIO_MBAT_ON | COLLIE_TC35143_GPIO_TMP_ON | | ||
COLLIE_TC35143_GPIO_BBAT_ON); | ||
return; | ||
} | ||
|
||
static void collie_measure_temp(int on) | ||
{ | ||
if (on) | ||
ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_TMP_ON, 0); | ||
else | ||
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_TMP_ON); | ||
} | ||
|
||
static void collie_charge(int on) | ||
{ | ||
if (on) { | ||
printk("Should start charger\n"); | ||
} else { | ||
printk("Should stop charger\n"); | ||
} | ||
#ifdef I_AM_SURE | ||
|
||
/* Zaurus seems to contain LTC1731 ; it should know when to | ||
* stop charging itself, so setting charge on should be | ||
* relatively harmless (as long as it is not done too often). | ||
*/ | ||
#define CF_BUF_CTRL_BASE 0xF0800000 | ||
#define SCOOP_REG(adr) (*(volatile unsigned short*)(CF_BUF_CTRL_BASE+(adr))) | ||
#define SCOOP_REG_GPWR SCOOP_REG(SCOOP_GPWR) | ||
|
||
if (on) { | ||
set_scoop_gpio(&colliescoop_device.dev, COLLIE_SCP_CHARGE_ON); | ||
} else { | ||
reset_scoop_gpio(&colliescoop_device.dev, COLLIE_SCP_CHARGE_ON); | ||
} | ||
#endif | ||
} | ||
|
||
static void collie_discharge(int on) | ||
{ | ||
} | ||
|
||
static void collie_discharge1(int on) | ||
{ | ||
} | ||
|
||
static void collie_presuspend(void) | ||
{ | ||
} | ||
|
||
static void collie_postsuspend(void) | ||
{ | ||
} | ||
|
||
static int collie_should_wakeup(unsigned int resume_on_alarm) | ||
{ | ||
return 0; | ||
} | ||
|
||
static unsigned long collie_charger_wakeup(void) | ||
{ | ||
return 0; | ||
} | ||
|
||
int collie_read_backup_battery(void) | ||
{ | ||
int voltage; | ||
|
||
ucb1x00_adc_enable(ucb); | ||
|
||
/* Gives 75..130 */ | ||
ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_BBAT_ON, 0); | ||
voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_SYNC); | ||
|
||
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_BBAT_ON); | ||
ucb1x00_adc_disable(ucb); | ||
|
||
printk("Backup battery = %d(%d)\n", ADCtoPower(voltage), voltage); | ||
|
||
return ADCtoPower(voltage); | ||
} | ||
|
||
int collie_read_main_battery(void) | ||
{ | ||
int voltage, voltage_rev, voltage_volts; | ||
|
||
ucb1x00_adc_enable(ucb); | ||
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_BBAT_ON); | ||
ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_MBAT_ON, 0); | ||
/* gives values 160..255 with battery removed... and | ||
145..255 with battery inserted. (on AC), goes as low as | ||
80 on DC. */ | ||
voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_SYNC); | ||
|
||
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_MBAT_ON); | ||
ucb1x00_adc_disable(ucb); | ||
|
||
voltage_rev = voltage + ((ad_revise * voltage) / 652); | ||
voltage_volts = ADCtoPower(voltage_rev); | ||
|
||
printk("Main battery = %d(%d)\n", voltage_volts, voltage); | ||
|
||
if (voltage != -1) | ||
return voltage_volts; | ||
else | ||
return voltage; | ||
} | ||
|
||
int collie_read_temp(void) | ||
{ | ||
int voltage; | ||
|
||
/* According to Sharp, temp must be > 973, main battery must be < 465, | ||
FIXME: sharpsl_pm.c has both conditions negated? FIXME: values | ||
are way out of range? */ | ||
|
||
ucb1x00_adc_enable(ucb); | ||
ucb1x00_io_write(ucb, COLLIE_TC35143_GPIO_TMP_ON, 0); | ||
/* >1010 = battery removed, 460 = 22C ?, higer = lower temp ? */ | ||
voltage = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD0, UCB_SYNC); | ||
ucb1x00_io_write(ucb, 0, COLLIE_TC35143_GPIO_TMP_ON); | ||
ucb1x00_adc_disable(ucb); | ||
|
||
printk("Battery temp = %d\n", voltage); | ||
return voltage; | ||
} | ||
|
||
static unsigned long read_devdata(int which) | ||
{ | ||
switch (which) { | ||
case SHARPSL_BATT_VOLT: | ||
return collie_read_main_battery(); | ||
case SHARPSL_BATT_TEMP: | ||
return collie_read_temp(); | ||
case SHARPSL_ACIN_VOLT: | ||
return 0x1; | ||
case SHARPSL_STATUS_ACIN: { | ||
int ret = GPLR & COLLIE_GPIO_AC_IN; | ||
printk("AC status = %d\n", ret); | ||
return ret; | ||
} | ||
case SHARPSL_STATUS_FATAL: { | ||
int ret = GPLR & COLLIE_GPIO_MAIN_BAT_LOW; | ||
printk("Fatal bat = %d\n", ret); | ||
return ret; | ||
} | ||
default: | ||
return ~0; | ||
} | ||
} | ||
|
||
struct battery_thresh collie_battery_levels[] = { | ||
{ 368, 100}, | ||
{ 358, 25}, | ||
{ 356, 5}, | ||
{ 0, 0}, | ||
}; | ||
|
||
struct sharpsl_charger_machinfo collie_pm_machinfo = { | ||
.init = collie_charger_init, | ||
.read_devdata = read_devdata, | ||
.discharge = collie_discharge, | ||
.discharge1 = collie_discharge1, | ||
.charge = collie_charge, | ||
.measure_temp = collie_measure_temp, | ||
.presuspend = collie_presuspend, | ||
.postsuspend = collie_postsuspend, | ||
.charger_wakeup = collie_charger_wakeup, | ||
.should_wakeup = collie_should_wakeup, | ||
.bat_levels = 3, | ||
.bat_levels_noac = collie_battery_levels, | ||
.bat_levels_acin = collie_battery_levels, | ||
.status_high_acin = 368, | ||
.status_low_acin = 358, | ||
.status_high_noac = 368, | ||
.status_low_noac = 358, | ||
}; | ||
|
||
static int __init collie_pm_ucb_add(struct ucb1x00_dev *pdev) | ||
{ | ||
sharpsl_pm.machinfo = &collie_pm_machinfo; | ||
ucb = pdev->ucb; | ||
return 0; | ||
} | ||
|
||
static struct ucb1x00_driver collie_pm_ucb_driver = { | ||
.add = collie_pm_ucb_add, | ||
}; | ||
|
||
static struct platform_device *collie_pm_device; | ||
|
||
static int __init collie_pm_init(void) | ||
{ | ||
int ret; | ||
|
||
collie_pm_device = platform_device_alloc("sharpsl-pm", -1); | ||
if (!collie_pm_device) | ||
return -ENOMEM; | ||
|
||
collie_pm_device->dev.platform_data = &collie_pm_machinfo; | ||
ret = platform_device_add(collie_pm_device); | ||
|
||
if (ret) | ||
platform_device_put(collie_pm_device); | ||
|
||
if (!ret) | ||
ret = ucb1x00_register_driver(&collie_pm_ucb_driver); | ||
|
||
return ret; | ||
} | ||
|
||
static void __exit collie_pm_exit(void) | ||
{ | ||
ucb1x00_unregister_driver(&collie_pm_ucb_driver); | ||
platform_device_unregister(collie_pm_device); | ||
} | ||
|
||
module_init(collie_pm_init); | ||
module_exit(collie_pm_exit); |