Commit 078abcf9 authored by Richard Purdie's avatar Richard Purdie Committed by Russell King

[ARM] 3096/1: Add SharpSL Zaurus power and battery management core driver

Patch from Richard Purdie

This patch adds a power and battery management core driver which with
the addition of the right device files, supports the c7x0 and cxx00
series of Sharp Zaurus handhelds.

The driver is complex for several reasons. Battery charging is manually
monitored and controlled. When suspended, the device needs to
periodically partially resume, check the charging status and then
re-suspend. It does without bothering the higher linux layers as
a full resume and re-suspend is unnecessary. The code is carefully
written to avoid interrupts or calling code outside the module under
these circumstances. It also vets the various wake up sources and
monitors the device's power situation.

Hooks to limit the backlight intensity and to notify the battery
monitoring code of backlight events are connected/added as the
backlight is one of the biggest users of power on the device.
Signed-off-by: default avatarRichard Purdie <rpurdie@rpsys.net>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent b1faebb6
......@@ -32,3 +32,90 @@ void corgi_put_hsync(void);
void spitz_put_hsync(void);
void corgi_wait_hsync(void);
void spitz_wait_hsync(void);
/*
* SharpSL Battery/PM Driver
*/
struct sharpsl_charger_machinfo {
void (*init)(void);
int gpio_acin;
int gpio_batfull;
int gpio_batlock;
int gpio_fatal;
int (*status_acin)(void);
void (*discharge)(int);
void (*discharge1)(int);
void (*charge)(int);
void (*chargeled)(int);
void (*measure_temp)(int);
void (*presuspend)(void);
void (*postsuspend)(void);
unsigned long (*charger_wakeup)(void);
int (*should_wakeup)(unsigned int resume_on_alarm);
int bat_levels;
struct battery_thresh *bat_levels_noac;
struct battery_thresh *bat_levels_acin;
int status_high_acin;
int status_low_acin;
int status_high_noac;
int status_low_noac;
};
struct battery_thresh {
int voltage;
int percentage;
};
struct battery_stat {
int ac_status; /* APM AC Present/Not Present */
int mainbat_status; /* APM Main Battery Status */
int mainbat_percent; /* Main Battery Percentage Charge */
int mainbat_voltage; /* Main Battery Voltage */
};
struct sharpsl_pm_status {
struct device *dev;
struct timer_list ac_timer;
struct timer_list chrg_full_timer;
int charge_mode;
#define CHRG_ERROR (-1)
#define CHRG_OFF (0)
#define CHRG_ON (1)
#define CHRG_DONE (2)
unsigned int flags;
#define SHARPSL_SUSPENDED (1 << 0) /* Device is Suspended */
#define SHARPSL_ALARM_ACTIVE (1 << 1) /* Alarm is for charging event (not user) */
#define SHARPSL_BL_LIMIT (1 << 2) /* Backlight Intensity Limited */
#define SHARPSL_APM_QUEUED (1 << 3) /* APM Event Queued */
#define SHARPSL_DO_OFFLINE_CHRG (1 << 4) /* Trigger the offline charger */
int full_count;
unsigned long charge_start_time;
struct sharpsl_charger_machinfo *machinfo;
struct battery_stat battstat;
};
extern struct sharpsl_pm_status sharpsl_pm;
extern struct battery_thresh spitz_battery_levels_acin[];
extern struct battery_thresh spitz_battery_levels_noac[];
#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x))
#define SHARPSL_LED_ERROR 2
#define SHARPSL_LED_ON 1
#define SHARPSL_LED_OFF 0
#define CHARGE_ON() sharpsl_pm.machinfo->charge(1)
#define CHARGE_OFF() sharpsl_pm.machinfo->charge(0)
#define CHARGE_LED_ON() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ON)
#define CHARGE_LED_OFF() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_OFF)
#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1)
#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0)
#define STATUS_AC_IN sharpsl_pm.machinfo->status_acin()
#define STATUS_BATT_LOCKED READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
#define STATUS_CHRG_FULL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
#define STATUS_FATAL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
This diff is collapsed.
......@@ -48,6 +48,12 @@ static void corgibl_send_intensity(int intensity)
corgibl_mach_set_intensity(intensity);
spin_unlock_irqrestore(&bl_lock, flags);
corgi_kick_batt = symbol_get(sharpsl_battery_kick);
if (corgi_kick_batt) {
corgi_kick_batt();
symbol_put(sharpsl_battery_kick);
}
}
static void corgibl_blank(int blank)
......
......@@ -21,12 +21,18 @@ struct corgits_machinfo {
void (*wait_hsync)(void);
};
/*
* SharpSL Backlight
*/
struct corgibl_machinfo {
int max_intensity;
void (*set_bl_intensity)(int intensity);
};
extern void corgibl_limit_intensity(int limit);
/*
* SharpSL Battery/PM Driver
*/
extern void sharpsl_battery_kick(void);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment