blob: f6fefb181411e45d91a4fd735924fb407db01398 [file] [log] [blame]
Richard Purdie078abcf2005-11-10 17:42:29 +00001/*
2 * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
3 * series of PDAs
4 *
5 * Copyright (c) 2004-2005 Richard Purdie
6 *
7 * Based on code written by Sharp for 2.4 kernels
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#undef DEBUG
16
17#include <linux/module.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000018#include <linux/init.h>
19#include <linux/kernel.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000020#include <linux/interrupt.h>
Richard Purdiec5e1ae92005-11-12 18:53:48 +000021#include <linux/platform_device.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000022
23#include <asm/hardware.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000024#include <asm/mach-types.h>
25#include <asm/irq.h>
26#include <asm/apm.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000027#include <asm/arch/pm.h>
28#include <asm/arch/pxa-regs.h>
29#include <asm/arch/sharpsl.h>
Richard Purdieb7557de2006-01-05 20:44:55 +000030#include <asm/hardware/sharpsl_pm.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000031#include "sharpsl.h"
32
Richard Purdie078abcf2005-11-10 17:42:29 +000033struct battery_thresh spitz_battery_levels_acin[] = {
34 { 213, 100},
35 { 212, 98},
36 { 211, 95},
37 { 210, 93},
38 { 209, 90},
39 { 208, 88},
40 { 207, 85},
41 { 206, 83},
42 { 205, 80},
43 { 204, 78},
44 { 203, 75},
45 { 202, 73},
46 { 201, 70},
47 { 200, 68},
48 { 199, 65},
49 { 198, 63},
50 { 197, 60},
51 { 196, 58},
52 { 195, 55},
53 { 194, 53},
54 { 193, 50},
55 { 192, 48},
56 { 192, 45},
57 { 191, 43},
58 { 191, 40},
59 { 190, 38},
60 { 190, 35},
61 { 189, 33},
62 { 188, 30},
63 { 187, 28},
64 { 186, 25},
65 { 185, 23},
66 { 184, 20},
67 { 183, 18},
68 { 182, 15},
69 { 181, 13},
70 { 180, 10},
71 { 179, 8},
72 { 178, 5},
73 { 0, 0},
74};
75
76struct battery_thresh spitz_battery_levels_noac[] = {
77 { 213, 100},
78 { 212, 98},
79 { 211, 95},
80 { 210, 93},
81 { 209, 90},
82 { 208, 88},
83 { 207, 85},
84 { 206, 83},
85 { 205, 80},
86 { 204, 78},
87 { 203, 75},
88 { 202, 73},
89 { 201, 70},
90 { 200, 68},
91 { 199, 65},
92 { 198, 63},
93 { 197, 60},
94 { 196, 58},
95 { 195, 55},
96 { 194, 53},
97 { 193, 50},
98 { 192, 48},
99 { 191, 45},
100 { 190, 43},
101 { 189, 40},
102 { 188, 38},
103 { 187, 35},
104 { 186, 33},
105 { 185, 30},
106 { 184, 28},
107 { 183, 25},
108 { 182, 23},
109 { 181, 20},
110 { 180, 18},
111 { 179, 15},
112 { 178, 13},
113 { 177, 10},
114 { 176, 8},
115 { 175, 5},
116 { 0, 0},
117};
118
119/* MAX1111 Commands */
120#define MAXCTRL_PD0 1u << 0
121#define MAXCTRL_PD1 1u << 1
122#define MAXCTRL_SGL 1u << 2
123#define MAXCTRL_UNI 1u << 3
124#define MAXCTRL_SEL_SH 4
125#define MAXCTRL_STR 1u << 7
126
Richard Purdie078abcf2005-11-10 17:42:29 +0000127/*
128 * Read MAX1111 ADC
129 */
Richard Purdieb7557de2006-01-05 20:44:55 +0000130int sharpsl_pm_pxa_read_max1111(int channel)
Richard Purdie078abcf2005-11-10 17:42:29 +0000131{
132 return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
133 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
134}
135
Richard Purdieb7557de2006-01-05 20:44:55 +0000136void sharpsl_pm_pxa_init(void)
Richard Purdie078abcf2005-11-10 17:42:29 +0000137{
Richard Purdie078abcf2005-11-10 17:42:29 +0000138 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
139 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
140 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
141
142 /* Register interrupt handlers */
143 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) {
144 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
145 }
146 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE);
147
148 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) {
149 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
150 }
151 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING);
152
153 if (sharpsl_pm.machinfo->gpio_fatal) {
154 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) {
155 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
156 }
157 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
158 }
159
160 if (!machine_is_corgi())
161 {
162 /* Register interrupt handler. */
163 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) {
164 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
165 }
166 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
167 }
Richard Purdie078abcf2005-11-10 17:42:29 +0000168}
169
Richard Purdieb7557de2006-01-05 20:44:55 +0000170void sharpsl_pm_pxa_remove(void)
Richard Purdie078abcf2005-11-10 17:42:29 +0000171{
Richard Purdie078abcf2005-11-10 17:42:29 +0000172 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
173 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
174
175 if (sharpsl_pm.machinfo->gpio_fatal)
176 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
177
178 if (!machine_is_corgi())
179 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
Richard Purdie078abcf2005-11-10 17:42:29 +0000180}