aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-13 21:17:54 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-13 21:17:54 -0500
commit70ac551651a2c5a234b703d9a495817f2ca09639 (patch)
tree71f55b9a3de438969a7a0d951971febf59784294 /arch/arm
parent7f729ccff35befa08a836ab33a4372c7f6735645 (diff)
parentbd5d080ab99642e3245ef7cfa54490384c01d878 (diff)
Merge master.kernel.org:/home/rmk/linux-2.6-arm
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/common/locomo.c4
-rw-r--r--arch/arm/common/scoop.c2
-rw-r--r--arch/arm/kernel/smp.c4
-rw-r--r--arch/arm/mach-footbridge/common.c24
-rw-r--r--arch/arm/mach-pxa/Kconfig6
-rw-r--r--arch/arm/mach-pxa/Makefile5
-rw-r--r--arch/arm/mach-pxa/akita-ioexp.c223
-rw-r--r--arch/arm/mach-pxa/corgi_pm.c228
-rw-r--r--arch/arm/mach-pxa/sharpsl.h8
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c109
-rw-r--r--arch/arm/mach-pxa/spitz.c49
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c233
13 files changed, 820 insertions, 77 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3df7cbd924a..70b007e6692 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -702,6 +702,8 @@ menu "Device Drivers"
702 702
703source "drivers/base/Kconfig" 703source "drivers/base/Kconfig"
704 704
705source "drivers/connector/Kconfig"
706
705if ALIGNMENT_TRAP 707if ALIGNMENT_TRAP
706source "drivers/mtd/Kconfig" 708source "drivers/mtd/Kconfig"
707endif 709endif
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 557e52c1c86..1b7eaab02b9 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -623,8 +623,6 @@ static int locomo_resume(struct platform_device *dev)
623 locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD); 623 locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
624 624
625 spin_unlock_irqrestore(&lchip->lock, flags); 625 spin_unlock_irqrestore(&lchip->lock, flags);
626
627 dev->power.saved_state = NULL;
628 kfree(save); 626 kfree(save);
629 627
630 return 0; 628 return 0;
@@ -775,7 +773,7 @@ static int locomo_probe(struct platform_device *dev)
775 773
776static int locomo_remove(struct platform_device *dev) 774static int locomo_remove(struct platform_device *dev)
777{ 775{
778 struct locomo *lchip = platform__get_drvdata(dev); 776 struct locomo *lchip = platform_get_drvdata(dev);
779 777
780 if (lchip) { 778 if (lchip) {
781 __locomo_remove(lchip); 779 __locomo_remove(lchip);
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 32924c6714f..0c3cbd9a388 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -153,7 +153,7 @@ int __init scoop_probe(struct platform_device *pdev)
153 printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base); 153 printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base);
154 154
155 SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140; 155 SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140;
156 reset_scoop(dev); 156 reset_scoop(&pdev->dev);
157 SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; 157 SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
158 SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; 158 SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
159 159
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e55ea952f7a..373c0959bc2 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -256,9 +256,7 @@ void __cpuexit cpu_die(void)
256asmlinkage void __cpuinit secondary_start_kernel(void) 256asmlinkage void __cpuinit secondary_start_kernel(void)
257{ 257{
258 struct mm_struct *mm = &init_mm; 258 struct mm_struct *mm = &init_mm;
259 unsigned int cpu; 259 unsigned int cpu = smp_processor_id();
260
261 cpu = smp_processor_id();
262 260
263 printk("CPU%u: Booted secondary processor\n", cpu); 261 printk("CPU%u: Booted secondary processor\n", cpu);
264 262
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index dc09fd200c1..bbe6e4a0bf6 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -132,14 +132,14 @@ void __init footbridge_init_irq(void)
132static struct map_desc fb_common_io_desc[] __initdata = { 132static struct map_desc fb_common_io_desc[] __initdata = {
133 { 133 {
134 .virtual = ARMCSR_BASE, 134 .virtual = ARMCSR_BASE,
135 .pfn = DC21285_ARMCSR_BASE, 135 .pfn = __phys_to_pfn(DC21285_ARMCSR_BASE),
136 .length = ARMCSR_SIZE, 136 .length = ARMCSR_SIZE,
137 .type = MT_DEVICE 137 .type = MT_DEVICE,
138 }, { 138 }, {
139 .virtual = XBUS_BASE, 139 .virtual = XBUS_BASE,
140 .pfn = __phys_to_pfn(0x40000000), 140 .pfn = __phys_to_pfn(0x40000000),
141 .length = XBUS_SIZE, 141 .length = XBUS_SIZE,
142 .type = MT_DEVICE 142 .type = MT_DEVICE,
143 } 143 }
144}; 144};
145 145
@@ -153,28 +153,28 @@ static struct map_desc ebsa285_host_io_desc[] __initdata = {
153 .virtual = PCIMEM_BASE, 153 .virtual = PCIMEM_BASE,
154 .pfn = __phys_to_pfn(DC21285_PCI_MEM), 154 .pfn = __phys_to_pfn(DC21285_PCI_MEM),
155 .length = PCIMEM_SIZE, 155 .length = PCIMEM_SIZE,
156 .type = MT_DEVICE 156 .type = MT_DEVICE,
157 }, { 157 }, {
158 .virtual = PCICFG0_BASE, 158 .virtual = PCICFG0_BASE,
159 .pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG), 159 .pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
160 .length = PCICFG0_SIZE, 160 .length = PCICFG0_SIZE,
161 .type = MT_DEVICE 161 .type = MT_DEVICE,
162 }, { 162 }, {
163 .virtual = PCICFG1_BASE, 163 .virtual = PCICFG1_BASE,
164 .pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG), 164 .pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
165 .length = PCICFG1_SIZE, 165 .length = PCICFG1_SIZE,
166 .type = MT_DEVICE 166 .type = MT_DEVICE,
167 }, { 167 }, {
168 .virtual = PCIIACK_BASE, 168 .virtual = PCIIACK_BASE,
169 .pfn = __phys_to_pfn(DC21285_PCI_IACK), 169 .pfn = __phys_to_pfn(DC21285_PCI_IACK),
170 .length = PCIIACK_SIZE, 170 .length = PCIIACK_SIZE,
171 .type = MT_DEVICE 171 .type = MT_DEVICE,
172 }, { 172 }, {
173 .virtual = PCIO_BASE, 173 .virtual = PCIO_BASE,
174 .pfn = __phys_to_pfn(DC21285_PCI_IO), 174 .pfn = __phys_to_pfn(DC21285_PCI_IO),
175 .length = PCIO_SIZE, 175 .length = PCIO_SIZE,
176 .type = MT_DEVICE 176 .type = MT_DEVICE,
177 } 177 },
178#endif 178#endif
179}; 179};
180 180
@@ -187,13 +187,13 @@ static struct map_desc co285_io_desc[] __initdata = {
187 .virtual = PCIO_BASE, 187 .virtual = PCIO_BASE,
188 .pfn = __phys_to_pfn(DC21285_PCI_IO), 188 .pfn = __phys_to_pfn(DC21285_PCI_IO),
189 .length = PCIO_SIZE, 189 .length = PCIO_SIZE,
190 .type = MT_DEVICE 190 .type = MT_DEVICE,
191 }, { 191 }, {
192 .virtual = PCIMEM_BASE, 192 .virtual = PCIMEM_BASE,
193 .pfn = __phys_to_pfn(DC21285_PCI_MEM), 193 .pfn = __phys_to_pfn(DC21285_PCI_MEM),
194 .length = PCIMEM_SIZE, 194 .length = PCIMEM_SIZE,
195 .type = MT_DEVICE 195 .type = MT_DEVICE,
196 } 196 },
197#endif 197#endif
198}; 198};
199 199
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index e201aa9765b..cd506646801 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -72,6 +72,12 @@ config MACH_HUSKY
72 depends PXA_SHARPSL_25x 72 depends PXA_SHARPSL_25x
73 select PXA_SHARP_C7xx 73 select PXA_SHARP_C7xx
74 74
75config MACH_AKITA
76 bool "Enable Sharp SL-1000 (Akita) Support"
77 depends PXA_SHARPSL_27x
78 select PXA_SHARP_Cxx00
79 select MACH_SPITZ
80
75config MACH_SPITZ 81config MACH_SPITZ
76 bool "Enable Sharp Zaurus SL-3000 (Spitz) Support" 82 bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
77 depends PXA_SHARPSL_27x 83 depends PXA_SHARPSL_27x
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index d210bd5032c..32526a0a6f8 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -11,8 +11,9 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o 11obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
12obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o 12obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
13obj-$(CONFIG_ARCH_PXA_IDP) += idp.o 13obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
14obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o 14obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
15obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o 15obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
16obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
16obj-$(CONFIG_MACH_POODLE) += poodle.o 17obj-$(CONFIG_MACH_POODLE) += poodle.o
17obj-$(CONFIG_MACH_TOSA) += tosa.o 18obj-$(CONFIG_MACH_TOSA) += tosa.o
18 19
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c
new file mode 100644
index 00000000000..f6d73cc01f7
--- /dev/null
+++ b/arch/arm/mach-pxa/akita-ioexp.c
@@ -0,0 +1,223 @@
1/*
2 * Support for the Extra GPIOs on the Sharp SL-C1000 (Akita)
3 * (uses a Maxim MAX7310 8 Port IO Expander)
4 *
5 * Copyright 2005 Openedhand Ltd.
6 *
7 * Author: Richard Purdie <richard@openedhand.com>
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#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/module.h>
19#include <linux/i2c.h>
20#include <linux/slab.h>
21#include <linux/workqueue.h>
22#include <asm/arch/akita.h>
23
24/* MAX7310 Regiser Map */
25#define MAX7310_INPUT 0x00
26#define MAX7310_OUTPUT 0x01
27#define MAX7310_POLINV 0x02
28#define MAX7310_IODIR 0x03 /* 1 = Input, 0 = Output */
29#define MAX7310_TIMEOUT 0x04
30
31/* Addresses to scan */
32static unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END };
33
34/* I2C Magic */
35I2C_CLIENT_INSMOD;
36
37static int max7310_write(struct i2c_client *client, int address, int data);
38static struct i2c_client max7310_template;
39static void akita_ioexp_work(void *private_);
40
41static struct device *akita_ioexp_device;
42static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT;
43DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL);
44
45
46/*
47 * MAX7310 Access
48 */
49static int max7310_config(struct device *dev, int iomode, int polarity)
50{
51 int ret;
52 struct i2c_client *client = to_i2c_client(dev);
53
54 ret = max7310_write(client, MAX7310_POLINV, polarity);
55 if (ret < 0)
56 return ret;
57 ret = max7310_write(client, MAX7310_IODIR, iomode);
58 return ret;
59}
60
61static int max7310_set_ouputs(struct device *dev, int outputs)
62{
63 struct i2c_client *client = to_i2c_client(dev);
64
65 return max7310_write(client, MAX7310_OUTPUT, outputs);
66}
67
68/*
69 * I2C Functions
70 */
71static int max7310_write(struct i2c_client *client, int address, int value)
72{
73 u8 data[2];
74
75 data[0] = address & 0xff;
76 data[1] = value & 0xff;
77
78 if (i2c_master_send(client, data, 2) == 2)
79 return 0;
80 return -1;
81}
82
83static int max7310_detect(struct i2c_adapter *adapter, int address, int kind)
84{
85 struct i2c_client *new_client;
86 int err;
87
88 if (!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
89 return -ENOMEM;
90
91 max7310_template.adapter = adapter;
92 max7310_template.addr = address;
93
94 memcpy(new_client, &max7310_template, sizeof(struct i2c_client));
95
96 if ((err = i2c_attach_client(new_client))) {
97 kfree(new_client);
98 return err;
99 }
100
101 max7310_config(&new_client->dev, AKITA_IOEXP_IO_DIR, 0);
102 akita_ioexp_device = &new_client->dev;
103 schedule_work(&akita_ioexp);
104
105 return 0;
106}
107
108static int max7310_attach_adapter(struct i2c_adapter *adapter)
109{
110 return i2c_probe(adapter, &addr_data, max7310_detect);
111}
112
113static int max7310_detach_client(struct i2c_client *client)
114{
115 int err;
116
117 akita_ioexp_device = NULL;
118
119 if ((err = i2c_detach_client(client)))
120 return err;
121
122 kfree(client);
123 return 0;
124}
125
126static struct i2c_driver max7310_i2c_driver = {
127 .owner = THIS_MODULE,
128 .name = "akita-max7310",
129 .id = I2C_DRIVERID_AKITAIOEXP,
130 .flags = I2C_DF_NOTIFY,
131 .attach_adapter = max7310_attach_adapter,
132 .detach_client = max7310_detach_client,
133};
134
135static struct i2c_client max7310_template = {
136 name: "akita-max7310",
137 flags: I2C_CLIENT_ALLOW_USE,
138 driver: &max7310_i2c_driver,
139};
140
141void akita_set_ioexp(struct device *dev, unsigned char bit)
142{
143 ioexp_output_value |= bit;
144
145 if (akita_ioexp_device)
146 schedule_work(&akita_ioexp);
147 return;
148}
149
150void akita_reset_ioexp(struct device *dev, unsigned char bit)
151{
152 ioexp_output_value &= ~bit;
153
154 if (akita_ioexp_device)
155 schedule_work(&akita_ioexp);
156 return;
157}
158
159EXPORT_SYMBOL(akita_set_ioexp);
160EXPORT_SYMBOL(akita_reset_ioexp);
161
162static void akita_ioexp_work(void *private_)
163{
164 if (akita_ioexp_device)
165 max7310_set_ouputs(akita_ioexp_device, ioexp_output_value);
166}
167
168
169#ifdef CONFIG_PM
170static int akita_ioexp_suspend(struct platform_device *pdev, pm_message_t state)
171{
172 flush_scheduled_work();
173 return 0;
174}
175
176static int akita_ioexp_resume(struct platform_device *pdev)
177{
178 schedule_work(&akita_ioexp);
179 return 0;
180}
181#else
182#define akita_ioexp_suspend NULL
183#define akita_ioexp_resume NULL
184#endif
185
186static int __init akita_ioexp_probe(struct platform_device *pdev)
187{
188 return i2c_add_driver(&max7310_i2c_driver);
189}
190
191static int akita_ioexp_remove(struct platform_device *pdev)
192{
193 i2c_del_driver(&max7310_i2c_driver);
194 return 0;
195}
196
197static struct platform_driver akita_ioexp_driver = {
198 .probe = akita_ioexp_probe,
199 .remove = akita_ioexp_remove,
200 .suspend = akita_ioexp_suspend,
201 .resume = akita_ioexp_resume,
202 .driver = {
203 .name = "akita-ioexp",
204 },
205};
206
207static int __init akita_ioexp_init(void)
208{
209 return platform_driver_register(&akita_ioexp_driver);
210}
211
212static void __exit akita_ioexp_exit(void)
213{
214 platform_driver_unregister(&akita_ioexp_driver);
215}
216
217MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
218MODULE_DESCRIPTION("Akita IO-Expander driver");
219MODULE_LICENSE("GPL");
220
221fs_initcall(akita_ioexp_init);
222module_exit(akita_ioexp_exit);
223
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
new file mode 100644
index 00000000000..599be14754f
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -0,0 +1,228 @@
1/*
2 * Battery and Power Management code for the Sharp SL-C7xx
3 *
4 * Copyright (c) 2005 Richard Purdie
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/stat.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/delay.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <asm/apm.h>
20#include <asm/irq.h>
21#include <asm/mach-types.h>
22#include <asm/hardware.h>
23#include <asm/hardware/scoop.h>
24
25#include <asm/arch/sharpsl.h>
26#include <asm/arch/corgi.h>
27#include <asm/arch/pxa-regs.h>
28#include "sharpsl.h"
29
30static void corgi_charger_init(void)
31{
32 pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT);
33 pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT);
34 pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT);
35 pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN);
36}
37
38static void corgi_charge_led(int val)
39{
40 if (val == SHARPSL_LED_ERROR) {
41 dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
42 } else if (val == SHARPSL_LED_ON) {
43 dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
44 GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
45 } else {
46 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
47 GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
48 }
49}
50
51static void corgi_measure_temp(int on)
52{
53 if (on)
54 GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
55 else
56 GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
57}
58
59static void corgi_charge(int on)
60{
61 if (on) {
62 if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) {
63 GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
64 GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
65 } else {
66 GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
67 GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
68 }
69 } else {
70 GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
71 GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
72 }
73}
74
75static void corgi_discharge(int on)
76{
77 if (on)
78 GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
79 else
80 GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
81}
82
83static void corgi_presuspend(void)
84{
85 int i;
86 unsigned long wakeup_mask;
87
88 /* charging , so CHARGE_ON bit is HIGH during OFF. */
89 if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON))
90 PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON);
91 else
92 PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON);
93
94 if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE))
95 PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE);
96 else
97 PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE);
98
99 if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN))
100 PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN);
101 else
102 PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN);
103
104 /* Resume on keyboard power key */
105 PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0);
106
107 wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL);
108
109 if (!machine_is_corgi())
110 wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW);
111
112 PWER = wakeup_mask | PWER_RTC;
113 PRER = wakeup_mask;
114 PFER = wakeup_mask;
115
116 for (i = 0; i <=15; i++) {
117 if (PRER & PFER & GPIO_bit(i)) {
118 if (GPLR0 & GPIO_bit(i) )
119 PRER &= ~GPIO_bit(i);
120 else
121 PFER &= ~GPIO_bit(i);
122 }
123 }
124}
125
126static void corgi_postsuspend(void)
127{
128}
129
130/*
131 * Check what brought us out of the suspend.
132 * Return: 0 to sleep, otherwise wake
133 */
134static int corgi_should_wakeup(unsigned int resume_on_alarm)
135{
136 int is_resume = 0;
137
138 dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
139
140 if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) {
141 if (STATUS_AC_IN()) {
142 /* charge on */
143 dev_dbg(sharpsl_pm.dev, "ac insert\n");
144 sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
145 } else {
146 /* charge off */
147 dev_dbg(sharpsl_pm.dev, "ac remove\n");
148 CHARGE_LED_OFF();
149 CHARGE_OFF();
150 sharpsl_pm.charge_mode = CHRG_OFF;
151 }
152 }
153
154 if ((PEDR & GPIO_bit(CORGI_GPIO_CHRG_FULL)))
155 dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
156
157 if (PEDR & GPIO_bit(CORGI_GPIO_KEY_INT))
158 is_resume |= GPIO_bit(CORGI_GPIO_KEY_INT);
159
160 if (PEDR & GPIO_bit(CORGI_GPIO_WAKEUP))
161 is_resume |= GPIO_bit(CORGI_GPIO_WAKEUP);
162
163 if (resume_on_alarm && (PEDR & PWER_RTC))
164 is_resume |= PWER_RTC;
165
166 dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
167 return is_resume;
168}
169
170static unsigned long corgi_charger_wakeup(void)
171{
172 return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) );
173}
174
175static int corgi_acin_status(void)
176{
177 return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0);
178}
179
180static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
181 .init = corgi_charger_init,
182 .gpio_batlock = CORGI_GPIO_BAT_COVER,
183 .gpio_acin = CORGI_GPIO_AC_IN,
184 .gpio_batfull = CORGI_GPIO_CHRG_FULL,
185 .status_acin = corgi_acin_status,
186 .discharge = corgi_discharge,
187 .charge = corgi_charge,
188 .chargeled = corgi_charge_led,
189 .measure_temp = corgi_measure_temp,
190 .presuspend = corgi_presuspend,
191 .postsuspend = corgi_postsuspend,
192 .charger_wakeup = corgi_charger_wakeup,
193 .should_wakeup = corgi_should_wakeup,
194 .bat_levels = 40,
195 .bat_levels_noac = spitz_battery_levels_noac,
196 .bat_levels_acin = spitz_battery_levels_acin,
197 .status_high_acin = 188,
198 .status_low_acin = 178,
199 .status_high_noac = 185,
200 .status_low_noac = 175,
201};
202
203static struct platform_device *corgipm_device;
204
205static int __devinit corgipm_init(void)
206{
207 int ret;
208
209 corgipm_device = platform_device_alloc("sharpsl-pm", -1);
210 if (!corgipm_device)
211 return -ENOMEM;
212
213 corgipm_device->dev.platform_data = &corgi_pm_machinfo;
214 ret = platform_device_add(corgipm_device);
215
216 if (ret)
217 platform_device_put(corgipm_device);
218
219 return ret;
220}
221
222static void corgipm_exit(void)
223{
224 platform_device_unregister(corgipm_device);
225}
226
227module_init(corgipm_init);
228module_exit(corgipm_exit);
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index 4879c0f7da7..b0c40a1d667 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -115,7 +115,7 @@ extern struct battery_thresh spitz_battery_levels_noac[];
115#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR) 115#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
116#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1) 116#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1)
117#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0) 117#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0)
118#define STATUS_AC_IN sharpsl_pm.machinfo->status_acin() 118#define STATUS_AC_IN() sharpsl_pm.machinfo->status_acin()
119#define STATUS_BATT_LOCKED READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock) 119#define STATUS_BATT_LOCKED() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
120#define STATUS_CHRG_FULL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull) 120#define STATUS_CHRG_FULL() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
121#define STATUS_FATAL READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal) 121#define STATUS_FATAL() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 6c9e871c53d..c10be00fb52 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -21,7 +21,7 @@
21#include <linux/apm_bios.h> 21#include <linux/apm_bios.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/device.h> 24#include <linux/platform_device.h>
25 25
26#include <asm/hardware.h> 26#include <asm/hardware.h>
27#include <asm/hardware/scoop.h> 27#include <asm/hardware/scoop.h>
@@ -45,15 +45,15 @@
45#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ 45#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */
46#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ 46#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */
47#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */ 47#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */
48#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD 10 /* 10 msec */ 48#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */
49#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */ 49#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */
50#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */ 50#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */
51#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */ 51#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */
52 52
53#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ 53#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */
54#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */ 54#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */
55#define SHARPSL_CHARGE_ON_JKVAD_HIGH 0x9b /* 6V */ 55#define SHARPSL_CHARGE_ON_ACIN_HIGH 0x9b /* 6V */
56#define SHARPSL_CHARGE_ON_JKVAD_LOW 0x34 /* 2V */ 56#define SHARPSL_CHARGE_ON_ACIN_LOW 0x34 /* 2V */
57#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */ 57#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */
58#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */ 58#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */
59 59
@@ -160,9 +160,10 @@ struct battery_thresh spitz_battery_levels_noac[] = {
160/* 160/*
161 * Prototypes 161 * Prototypes
162 */ 162 */
163static int sharpsl_read_MainBattery(void); 163static int sharpsl_read_main_battery(void);
164static int sharpsl_off_charge_battery(void); 164static int sharpsl_off_charge_battery(void);
165static int sharpsl_check_battery(int mode); 165static int sharpsl_check_battery_temp(void);
166static int sharpsl_check_battery_voltage(void);
166static int sharpsl_ac_check(void); 167static int sharpsl_ac_check(void);
167static int sharpsl_fatal_check(void); 168static int sharpsl_fatal_check(void);
168static int sharpsl_average_value(int ad); 169static int sharpsl_average_value(int ad);
@@ -228,7 +229,7 @@ static void sharpsl_battery_thread(void *private_)
228 if (!sharpsl_pm.machinfo) 229 if (!sharpsl_pm.machinfo)
229 return; 230 return;
230 231
231 sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE); 232 sharpsl_pm.battstat.ac_status = (STATUS_AC_IN() ? APM_AC_ONLINE : APM_AC_OFFLINE);
232 233
233 /* Corgi cannot confirm when battery fully charged so periodically kick! */ 234 /* Corgi cannot confirm when battery fully charged so periodically kick! */
234 if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON) 235 if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
@@ -236,7 +237,7 @@ static void sharpsl_battery_thread(void *private_)
236 schedule_work(&toggle_charger); 237 schedule_work(&toggle_charger);
237 238
238 while(1) { 239 while(1) {
239 voltage = sharpsl_read_MainBattery(); 240 voltage = sharpsl_read_main_battery();
240 if (voltage > 0) break; 241 if (voltage > 0) break;
241 if (i++ > 5) { 242 if (i++ > 5) {
242 voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; 243 voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
@@ -317,10 +318,10 @@ static void sharpsl_charge_toggle(void *private_)
317{ 318{
318 dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); 319 dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
319 320
320 if (STATUS_AC_IN == 0) { 321 if (STATUS_AC_IN() == 0) {
321 sharpsl_charge_off(); 322 sharpsl_charge_off();
322 return; 323 return;
323 } else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) { 324 } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
324 sharpsl_charge_error(); 325 sharpsl_charge_error();
325 return; 326 return;
326 } 327 }
@@ -335,7 +336,7 @@ static void sharpsl_charge_toggle(void *private_)
335 336
336static void sharpsl_ac_timer(unsigned long data) 337static void sharpsl_ac_timer(unsigned long data)
337{ 338{
338 int acin = STATUS_AC_IN; 339 int acin = STATUS_AC_IN();
339 340
340 dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin); 341 dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
341 342
@@ -364,7 +365,7 @@ static void sharpsl_chrg_full_timer(unsigned long data)
364 365
365 sharpsl_pm.full_count++; 366 sharpsl_pm.full_count++;
366 367
367 if (STATUS_AC_IN == 0) { 368 if (STATUS_AC_IN() == 0) {
368 dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n"); 369 dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
369 if (sharpsl_pm.charge_mode == CHRG_ON) 370 if (sharpsl_pm.charge_mode == CHRG_ON)
370 sharpsl_charge_off(); 371 sharpsl_charge_off();
@@ -399,12 +400,12 @@ static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
399{ 400{
400 int is_fatal = 0; 401 int is_fatal = 0;
401 402
402 if (STATUS_BATT_LOCKED == 0) { 403 if (STATUS_BATT_LOCKED() == 0) {
403 dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n"); 404 dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
404 is_fatal = 1; 405 is_fatal = 1;
405 } 406 }
406 407
407 if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) { 408 if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL() == 0)) {
408 dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n"); 409 dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
409 is_fatal = 1; 410 is_fatal = 1;
410 } 411 }
@@ -461,12 +462,12 @@ static int read_max1111(int channel)
461 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR); 462 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
462} 463}
463 464
464static int sharpsl_read_MainBattery(void) 465static int sharpsl_read_main_battery(void)
465{ 466{
466 return read_max1111(BATT_AD); 467 return read_max1111(BATT_AD);
467} 468}
468 469
469static int sharpsl_read_Temp(void) 470static int sharpsl_read_temp(void)
470{ 471{
471 int temp; 472 int temp;
472 473
@@ -480,7 +481,7 @@ static int sharpsl_read_Temp(void)
480 return temp; 481 return temp;
481} 482}
482 483
483static int sharpsl_read_jkvad(void) 484static int sharpsl_read_acin(void)
484{ 485{
485 return read_max1111(JK_VAD); 486 return read_max1111(JK_VAD);
486} 487}
@@ -522,16 +523,14 @@ static int get_select_val(int *val)
522 return (sum/3); 523 return (sum/3);
523} 524}
524 525
525/* mode 0 - Check temperature and voltage 526static int sharpsl_check_battery_temp(void)
526 * 1 - Check temperature only */
527static int sharpsl_check_battery(int mode)
528{ 527{
529 int val, i, buff[5]; 528 int val, i, buff[5];
530 529
531 /* Check battery temperature */ 530 /* Check battery temperature */
532 for (i=0; i<5; i++) { 531 for (i=0; i<5; i++) {
533 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); 532 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
534 buff[i] = sharpsl_read_Temp(); 533 buff[i] = sharpsl_read_temp();
535 } 534 }
536 535
537 val = get_select_val(buff); 536 val = get_select_val(buff);
@@ -539,8 +538,13 @@ static int sharpsl_check_battery(int mode)
539 dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val); 538 dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
540 if (val > SHARPSL_CHARGE_ON_TEMP) 539 if (val > SHARPSL_CHARGE_ON_TEMP)
541 return -1; 540 return -1;
542 if (mode == 1) 541
543 return 0; 542 return 0;
543}
544
545static int sharpsl_check_battery_voltage(void)
546{
547 int val, i, buff[5];
544 548
545 /* disable charge, enable discharge */ 549 /* disable charge, enable discharge */
546 CHARGE_OFF(); 550 CHARGE_OFF();
@@ -552,7 +556,7 @@ static int sharpsl_check_battery(int mode)
552 556
553 /* Check battery voltage */ 557 /* Check battery voltage */
554 for (i=0; i<5; i++) { 558 for (i=0; i<5; i++) {
555 buff[i] = sharpsl_read_MainBattery(); 559 buff[i] = sharpsl_read_main_battery();
556 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); 560 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
557 } 561 }
558 562
@@ -575,14 +579,14 @@ static int sharpsl_ac_check(void)
575 int temp, i, buff[5]; 579 int temp, i, buff[5];
576 580
577 for (i=0; i<5; i++) { 581 for (i=0; i<5; i++) {
578 buff[i] = sharpsl_read_jkvad(); 582 buff[i] = sharpsl_read_acin();
579 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD); 583 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
580 } 584 }
581 585
582 temp = get_select_val(buff); 586 temp = get_select_val(buff);
583 dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp); 587 dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
584 588
585 if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) { 589 if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) {
586 dev_err(sharpsl_pm.dev, "Error: AC check failed.\n"); 590 dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
587 return -1; 591 return -1;
588 } 592 }
@@ -591,7 +595,7 @@ static int sharpsl_ac_check(void)
591} 595}
592 596
593#ifdef CONFIG_PM 597#ifdef CONFIG_PM
594static int sharpsl_pm_suspend(struct device *dev, pm_message_t state) 598static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
595{ 599{
596 sharpsl_pm.flags |= SHARPSL_SUSPENDED; 600 sharpsl_pm.flags |= SHARPSL_SUSPENDED;
597 flush_scheduled_work(); 601 flush_scheduled_work();
@@ -604,7 +608,7 @@ static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
604 return 0; 608 return 0;
605} 609}
606 610
607static int sharpsl_pm_resume(struct device *dev) 611static int sharpsl_pm_resume(struct platform_device *pdev)
608{ 612{
609 /* Clear the reset source indicators as they break the bootloader upon reboot */ 613 /* Clear the reset source indicators as they break the bootloader upon reboot */
610 RCSR = 0x0f; 614 RCSR = 0x0f;
@@ -622,7 +626,7 @@ static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable
622 dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG); 626 dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
623 /* not charging and AC-IN! */ 627 /* not charging and AC-IN! */
624 628
625 if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) { 629 if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN() != 0)) {
626 dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n"); 630 dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
627 sharpsl_pm.charge_mode = CHRG_OFF; 631 sharpsl_pm.charge_mode = CHRG_OFF;
628 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; 632 sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
@@ -671,7 +675,7 @@ static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enab
671 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); 675 dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
672 } 676 }
673 677
674 if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) ) 678 if ((STATUS_BATT_LOCKED() == 0) || (sharpsl_fatal_check() < 0) )
675 { 679 {
676 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); 680 dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
677 corgi_goto_sleep(alarm_time, alarm_enable, state); 681 corgi_goto_sleep(alarm_time, alarm_enable, state);
@@ -711,7 +715,7 @@ static int sharpsl_fatal_check(void)
711 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n"); 715 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
712 716
713 /* Check AC-Adapter */ 717 /* Check AC-Adapter */
714 acin = STATUS_AC_IN; 718 acin = STATUS_AC_IN();
715 719
716 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { 720 if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
717 CHARGE_OFF(); 721 CHARGE_OFF();
@@ -725,7 +729,7 @@ static int sharpsl_fatal_check(void)
725 729
726 /* Check battery : check inserting battery ? */ 730 /* Check battery : check inserting battery ? */
727 for (i=0; i<5; i++) { 731 for (i=0; i<5; i++) {
728 buff[i] = sharpsl_read_MainBattery(); 732 buff[i] = sharpsl_read_main_battery();
729 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); 733 mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
730 } 734 }
731 735
@@ -739,7 +743,7 @@ static int sharpsl_fatal_check(void)
739 } 743 }
740 744
741 temp = get_select_val(buff); 745 temp = get_select_val(buff);
742 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery()); 746 dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_main_battery());
743 747
744 if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) || 748 if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
745 (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT))) 749 (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
@@ -771,7 +775,7 @@ static int sharpsl_off_charge_battery(void)
771 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); 775 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
772 776
773 /* AC Check */ 777 /* AC Check */
774 if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0)) 778 if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
775 return sharpsl_off_charge_error(); 779 return sharpsl_off_charge_error();
776 780
777 /* Start Charging */ 781 /* Start Charging */
@@ -793,7 +797,7 @@ static int sharpsl_off_charge_battery(void)
793 797
794 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); 798 dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
795 799
796 if (sharpsl_check_battery(0) < 0) 800 if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
797 return sharpsl_off_charge_error(); 801 return sharpsl_off_charge_error();
798 802
799 CHARGE_OFF(); 803 CHARGE_OFF();
@@ -811,7 +815,7 @@ static int sharpsl_off_charge_battery(void)
811 /* Check for timeout */ 815 /* Check for timeout */
812 if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) 816 if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
813 return 1; 817 return 1;
814 if (STATUS_CHRG_FULL) { 818 if (STATUS_CHRG_FULL()) {
815 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n"); 819 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
816 sharpsl_pm.full_count++; 820 sharpsl_pm.full_count++;
817 CHARGE_OFF(); 821 CHARGE_OFF();
@@ -840,7 +844,7 @@ static int sharpsl_off_charge_battery(void)
840 sharpsl_pm.full_count++; 844 sharpsl_pm.full_count++;
841 return 1; 845 return 1;
842 } 846 }
843 if (STATUS_CHRG_FULL) { 847 if (STATUS_CHRG_FULL()) {
844 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); 848 dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
845 CHARGE_LED_OFF(); 849 CHARGE_LED_OFF();
846 CHARGE_OFF(); 850 CHARGE_OFF();
@@ -886,13 +890,13 @@ static struct pm_ops sharpsl_pm_ops = {
886 .finish = pxa_pm_finish, 890 .finish = pxa_pm_finish,
887}; 891};
888 892
889static int __init sharpsl_pm_probe(struct device *dev) 893static int __init sharpsl_pm_probe(struct platform_device *pdev)
890{ 894{
891 if (!dev->platform_data) 895 if (!pdev->dev.platform_data)
892 return -EINVAL; 896 return -EINVAL;
893 897
894 sharpsl_pm.dev = dev; 898 sharpsl_pm.dev = &pdev->dev;
895 sharpsl_pm.machinfo = dev->platform_data; 899 sharpsl_pm.machinfo = pdev->dev.platform_data;
896 sharpsl_pm.charge_mode = CHRG_OFF; 900 sharpsl_pm.charge_mode = CHRG_OFF;
897 sharpsl_pm.flags = 0; 901 sharpsl_pm.flags = 0;
898 902
@@ -935,8 +939,8 @@ static int __init sharpsl_pm_probe(struct device *dev)
935 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING); 939 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
936 } 940 }
937 941
938 device_create_file(dev, &dev_attr_battery_percentage); 942 device_create_file(&pdev->dev, &dev_attr_battery_percentage);
939 device_create_file(dev, &dev_attr_battery_voltage); 943 device_create_file(&pdev->dev, &dev_attr_battery_voltage);
940 944
941 apm_get_power_status = sharpsl_apm_get_power_status; 945 apm_get_power_status = sharpsl_apm_get_power_status;
942 946
@@ -947,12 +951,12 @@ static int __init sharpsl_pm_probe(struct device *dev)
947 return 0; 951 return 0;
948} 952}
949 953
950static int sharpsl_pm_remove(struct device *dev) 954static int sharpsl_pm_remove(struct platform_device *pdev)
951{ 955{
952 pm_set_ops(NULL); 956 pm_set_ops(NULL);
953 957
954 device_remove_file(dev, &dev_attr_battery_percentage); 958 device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
955 device_remove_file(dev, &dev_attr_battery_voltage); 959 device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
956 960
957 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); 961 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
958 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); 962 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
@@ -969,23 +973,24 @@ static int sharpsl_pm_remove(struct device *dev)
969 return 0; 973 return 0;
970} 974}
971 975
972static struct device_driver sharpsl_pm_driver = { 976static struct platform_driver sharpsl_pm_driver = {
973 .name = "sharpsl-pm",
974 .bus = &platform_bus_type,
975 .probe = sharpsl_pm_probe, 977 .probe = sharpsl_pm_probe,
976 .remove = sharpsl_pm_remove, 978 .remove = sharpsl_pm_remove,
977 .suspend = sharpsl_pm_suspend, 979 .suspend = sharpsl_pm_suspend,
978 .resume = sharpsl_pm_resume, 980 .resume = sharpsl_pm_resume,
981 .driver = {
982 .name = "sharpsl-pm",
983 },
979}; 984};
980 985
981static int __devinit sharpsl_pm_init(void) 986static int __devinit sharpsl_pm_init(void)
982{ 987{
983 return driver_register(&sharpsl_pm_driver); 988 return platform_driver_register(&sharpsl_pm_driver);
984} 989}
985 990
986static void sharpsl_pm_exit(void) 991static void sharpsl_pm_exit(void)
987{ 992{
988 driver_unregister(&sharpsl_pm_driver); 993 platform_driver_unregister(&sharpsl_pm_driver);
989} 994}
990 995
991late_initcall(sharpsl_pm_init); 996late_initcall(sharpsl_pm_init);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 4e9a699ee42..2df1b56615b 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -345,6 +345,16 @@ static void spitz_irda_transceiver_mode(struct device *dev, int mode)
345 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON); 345 reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
346} 346}
347 347
348#ifdef CONFIG_MACH_AKITA
349static void akita_irda_transceiver_mode(struct device *dev, int mode)
350{
351 if (mode & IR_OFF)
352 akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
353 else
354 akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
355}
356#endif
357
348static struct pxaficp_platform_data spitz_ficp_platform_data = { 358static struct pxaficp_platform_data spitz_ficp_platform_data = {
349 .transceiver_cap = IR_SIRMODE | IR_OFF, 359 .transceiver_cap = IR_SIRMODE | IR_OFF,
350 .transceiver_mode = spitz_irda_transceiver_mode, 360 .transceiver_mode = spitz_irda_transceiver_mode,
@@ -417,6 +427,32 @@ static void __init spitz_init(void)
417 platform_device_register(&spitzscoop2_device); 427 platform_device_register(&spitzscoop2_device);
418} 428}
419 429
430#ifdef CONFIG_MACH_AKITA
431/*
432 * Akita IO Expander
433 */
434struct platform_device akitaioexp_device = {
435 .name = "akita-ioexp",
436 .id = -1,
437};
438
439static void __init akita_init(void)
440{
441 spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
442
443 /* We just pretend the second element of the array doesn't exist */
444 spitz_pcmcia_config.num_devs = 1;
445 platform_scoop_config = &spitz_pcmcia_config;
446 spitz_bl_machinfo.set_bl_intensity = akita_bl_set_intensity;
447
448 platform_device_register(&akitaioexp_device);
449
450 spitzscoop_device.dev.parent = &akitaioexp_device.dev;
451 common_init();
452}
453#endif
454
455
420static void __init fixup_spitz(struct machine_desc *desc, 456static void __init fixup_spitz(struct machine_desc *desc,
421 struct tag *tags, char **cmdline, struct meminfo *mi) 457 struct tag *tags, char **cmdline, struct meminfo *mi)
422{ 458{
@@ -452,3 +488,16 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
452 .timer = &pxa_timer, 488 .timer = &pxa_timer,
453MACHINE_END 489MACHINE_END
454#endif 490#endif
491
492#ifdef CONFIG_MACH_AKITA
493MACHINE_START(AKITA, "SHARP Akita")
494 .phys_ram = 0xa0000000,
495 .phys_io = 0x40000000,
496 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
497 .fixup = fixup_spitz,
498 .map_io = pxa_map_io,
499 .init_irq = pxa_init_irq,
500 .init_machine = akita_init,
501 .timer = &pxa_timer,
502MACHINE_END
503#endif
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
new file mode 100644
index 00000000000..3ce7486daa5
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -0,0 +1,233 @@
1/*
2 * Battery and Power Management code for the Sharp SL-Cxx00
3 *
4 * Copyright (c) 2005 Richard Purdie
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/module.h>
13#include <linux/stat.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/delay.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <asm/apm.h>
20#include <asm/irq.h>
21#include <asm/mach-types.h>
22#include <asm/hardware.h>
23#include <asm/hardware/scoop.h>
24
25#include <asm/arch/sharpsl.h>
26#include <asm/arch/spitz.h>
27#include <asm/arch/pxa-regs.h>
28#include "sharpsl.h"
29
30static int spitz_last_ac_status;
31
32static void spitz_charger_init(void)
33{
34 pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN);
35 pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
36}
37
38static void spitz_charge_led(int val)
39{
40 if (val == SHARPSL_LED_ERROR) {
41 dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
42 } else if (val == SHARPSL_LED_ON) {
43 dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
44 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
45 } else {
46 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
47 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
48 }
49}
50
51static void spitz_measure_temp(int on)
52{
53 if (on)
54 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
55 else
56 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
57}
58
59static void spitz_charge(int on)
60{
61 if (on) {
62 if (sharpsl_pm.flags & SHARPSL_SUSPENDED) {
63 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
64 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
65 } else {
66 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
67 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
68 }
69 } else {
70 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
71 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
72 }
73}
74
75static void spitz_discharge(int on)
76{
77 if (on)
78 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
79 else
80 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
81}
82
83/* HACK - For unknown reasons, accurate voltage readings are only made with a load
84 on the power bus which the green led on spitz provides */
85static void spitz_discharge1(int on)
86{
87 if (on)
88 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
89 else
90 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
91}
92
93static void spitz_presuspend(void)
94{
95 spitz_last_ac_status = STATUS_AC_IN();
96
97 /* GPIO Sleep Register */
98 PGSR0 = 0x00144018;
99 PGSR1 = 0x00EF0000;
100 if (machine_is_akita()) {
101 PGSR2 = 0x2121C000;
102 PGSR3 = 0x00600400;
103 } else {
104 PGSR2 = 0x0121C000;
105 PGSR3 = 0x00600000;
106 }
107
108 PGSR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
109 PGSR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
110 PGSR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
111 PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
112 PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
113
114 pxa_gpio_mode(GPIO18_RDY|GPIO_OUT | GPIO_DFLT_HIGH);
115
116 PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
117 PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
118 PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC;
119 PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
120 PKSR = 0xffffffff; // clear
121
122 /* nRESET_OUT Disable */
123 PSLR |= PSLR_SL_ROD;
124
125 /* Clear reset status */
126 RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
127
128 /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
129 PCFR = PCFR_GPR_EN | PCFR_OPDE;
130}
131
132static void spitz_postsuspend(void)
133{
134 pxa_gpio_mode(GPIO18_RDY_MD);
135 pxa_gpio_mode(10 | GPIO_IN);
136}
137
138static int spitz_should_wakeup(unsigned int resume_on_alarm)
139{
140 int is_resume = 0;
141 int acin = STATUS_AC_IN();
142
143 if (spitz_last_ac_status != acin) {
144 if (acin) {
145 /* charge on */
146 sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
147 dev_dbg(sharpsl_pm.dev, "AC Inserted\n");
148 } else {
149 /* charge off */
150 dev_dbg(sharpsl_pm.dev, "AC Removed\n");
151 CHARGE_LED_OFF();
152 CHARGE_OFF();
153 sharpsl_pm.charge_mode = CHRG_OFF;
154 }
155 spitz_last_ac_status = acin;
156 /* Return to suspend as this must be what we were woken for */
157 return 0;
158 }
159
160 if (PEDR & GPIO_bit(SPITZ_GPIO_KEY_INT))
161 is_resume |= GPIO_bit(SPITZ_GPIO_KEY_INT);
162
163 if (PKSR & GPIO_bit(SPITZ_GPIO_SYNC))
164 is_resume |= GPIO_bit(SPITZ_GPIO_SYNC);
165
166 if (resume_on_alarm && (PEDR & PWER_RTC))
167 is_resume |= PWER_RTC;
168
169 dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
170 return is_resume;
171}
172
173static unsigned long spitz_charger_wakeup(void)
174{
175 return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC));
176}
177
178static int spitz_acin_status(void)
179{
180 return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0);
181}
182
183struct sharpsl_charger_machinfo spitz_pm_machinfo = {
184 .init = spitz_charger_init,
185 .gpio_batlock = SPITZ_GPIO_BAT_COVER,
186 .gpio_acin = SPITZ_GPIO_AC_IN,
187 .gpio_batfull = SPITZ_GPIO_CHRG_FULL,
188 .gpio_fatal = SPITZ_GPIO_FATAL_BAT,
189 .status_acin = spitz_acin_status,
190 .discharge = spitz_discharge,
191 .discharge1 = spitz_discharge1,
192 .charge = spitz_charge,
193 .chargeled = spitz_charge_led,
194 .measure_temp = spitz_measure_temp,
195 .presuspend = spitz_presuspend,
196 .postsuspend = spitz_postsuspend,
197 .charger_wakeup = spitz_charger_wakeup,
198 .should_wakeup = spitz_should_wakeup,
199 .bat_levels = 40,
200 .bat_levels_noac = spitz_battery_levels_noac,
201 .bat_levels_acin = spitz_battery_levels_acin,
202 .status_high_acin = 188,
203 .status_low_acin = 178,
204 .status_high_noac = 185,
205 .status_low_noac = 175,
206};
207
208static struct platform_device *spitzpm_device;
209
210static int __devinit spitzpm_init(void)
211{
212 int ret;
213
214 spitzpm_device = platform_device_alloc("sharpsl-pm", -1);
215 if (!spitzpm_device)
216 return -ENOMEM;
217
218 spitzpm_device->dev.platform_data = &spitz_pm_machinfo;
219 ret = platform_device_add(spitzpm_device);
220
221 if (ret)
222 platform_device_put(spitzpm_device);
223
224 return ret;
225}
226
227static void spitzpm_exit(void)
228{
229 platform_device_unregister(spitzpm_device);
230}
231
232module_init(spitzpm_init);
233module_exit(spitzpm_exit);