xref: /openbmc/linux/arch/arm/mach-pxa/sharpsl_pm.c (revision 45e2a9b4)
1078abcf9SRichard Purdie /*
2078abcf9SRichard Purdie  * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
3078abcf9SRichard Purdie  * series of PDAs
4078abcf9SRichard Purdie  *
5078abcf9SRichard Purdie  * Copyright (c) 2004-2005 Richard Purdie
6078abcf9SRichard Purdie  *
7078abcf9SRichard Purdie  * Based on code written by Sharp for 2.4 kernels
8078abcf9SRichard Purdie  *
9078abcf9SRichard Purdie  * This program is free software; you can redistribute it and/or modify
10078abcf9SRichard Purdie  * it under the terms of the GNU General Public License version 2 as
11078abcf9SRichard Purdie  * published by the Free Software Foundation.
12078abcf9SRichard Purdie  *
13078abcf9SRichard Purdie  */
14078abcf9SRichard Purdie 
15078abcf9SRichard Purdie #undef DEBUG
16078abcf9SRichard Purdie 
17078abcf9SRichard Purdie #include <linux/module.h>
18078abcf9SRichard Purdie #include <linux/init.h>
19078abcf9SRichard Purdie #include <linux/kernel.h>
20078abcf9SRichard Purdie #include <linux/interrupt.h>
211623dee8SThomas Gleixner #include <linux/irq.h>
22c5e1ae97SRichard Purdie #include <linux/platform_device.h>
2361fde514SRussell King #include <linux/apm-emulation.h>
24078abcf9SRichard Purdie 
25a09e64fbSRussell King #include <mach/hardware.h>
26078abcf9SRichard Purdie #include <asm/mach-types.h>
27a09e64fbSRussell King #include <mach/pm.h>
28a09e64fbSRussell King #include <mach/pxa-regs.h>
29a09e64fbSRussell King #include <mach/pxa2xx-gpio.h>
30a09e64fbSRussell King #include <mach/sharpsl.h>
31078abcf9SRichard Purdie #include "sharpsl.h"
32078abcf9SRichard Purdie 
33078abcf9SRichard Purdie struct battery_thresh spitz_battery_levels_acin[] = {
34078abcf9SRichard Purdie 	{ 213, 100},
35078abcf9SRichard Purdie 	{ 212,  98},
36078abcf9SRichard Purdie 	{ 211,  95},
37078abcf9SRichard Purdie 	{ 210,  93},
38078abcf9SRichard Purdie 	{ 209,  90},
39078abcf9SRichard Purdie 	{ 208,  88},
40078abcf9SRichard Purdie 	{ 207,  85},
41078abcf9SRichard Purdie 	{ 206,  83},
42078abcf9SRichard Purdie 	{ 205,  80},
43078abcf9SRichard Purdie 	{ 204,  78},
44078abcf9SRichard Purdie 	{ 203,  75},
45078abcf9SRichard Purdie 	{ 202,  73},
46078abcf9SRichard Purdie 	{ 201,  70},
47078abcf9SRichard Purdie 	{ 200,  68},
48078abcf9SRichard Purdie 	{ 199,  65},
49078abcf9SRichard Purdie 	{ 198,  63},
50078abcf9SRichard Purdie 	{ 197,  60},
51078abcf9SRichard Purdie 	{ 196,  58},
52078abcf9SRichard Purdie 	{ 195,  55},
53078abcf9SRichard Purdie 	{ 194,  53},
54078abcf9SRichard Purdie 	{ 193,  50},
55078abcf9SRichard Purdie 	{ 192,  48},
56078abcf9SRichard Purdie 	{ 192,  45},
57078abcf9SRichard Purdie 	{ 191,  43},
58078abcf9SRichard Purdie 	{ 191,  40},
59078abcf9SRichard Purdie 	{ 190,  38},
60078abcf9SRichard Purdie 	{ 190,  35},
61078abcf9SRichard Purdie 	{ 189,  33},
62078abcf9SRichard Purdie 	{ 188,  30},
63078abcf9SRichard Purdie 	{ 187,  28},
64078abcf9SRichard Purdie 	{ 186,  25},
65078abcf9SRichard Purdie 	{ 185,  23},
66078abcf9SRichard Purdie 	{ 184,  20},
67078abcf9SRichard Purdie 	{ 183,  18},
68078abcf9SRichard Purdie 	{ 182,  15},
69078abcf9SRichard Purdie 	{ 181,  13},
70078abcf9SRichard Purdie 	{ 180,  10},
71078abcf9SRichard Purdie 	{ 179,   8},
72078abcf9SRichard Purdie 	{ 178,   5},
73078abcf9SRichard Purdie 	{   0,   0},
74078abcf9SRichard Purdie };
75078abcf9SRichard Purdie 
76078abcf9SRichard Purdie struct battery_thresh  spitz_battery_levels_noac[] = {
77078abcf9SRichard Purdie 	{ 213, 100},
78078abcf9SRichard Purdie 	{ 212,  98},
79078abcf9SRichard Purdie 	{ 211,  95},
80078abcf9SRichard Purdie 	{ 210,  93},
81078abcf9SRichard Purdie 	{ 209,  90},
82078abcf9SRichard Purdie 	{ 208,  88},
83078abcf9SRichard Purdie 	{ 207,  85},
84078abcf9SRichard Purdie 	{ 206,  83},
85078abcf9SRichard Purdie 	{ 205,  80},
86078abcf9SRichard Purdie 	{ 204,  78},
87078abcf9SRichard Purdie 	{ 203,  75},
88078abcf9SRichard Purdie 	{ 202,  73},
89078abcf9SRichard Purdie 	{ 201,  70},
90078abcf9SRichard Purdie 	{ 200,  68},
91078abcf9SRichard Purdie 	{ 199,  65},
92078abcf9SRichard Purdie 	{ 198,  63},
93078abcf9SRichard Purdie 	{ 197,  60},
94078abcf9SRichard Purdie 	{ 196,  58},
95078abcf9SRichard Purdie 	{ 195,  55},
96078abcf9SRichard Purdie 	{ 194,  53},
97078abcf9SRichard Purdie 	{ 193,  50},
98078abcf9SRichard Purdie 	{ 192,  48},
99078abcf9SRichard Purdie 	{ 191,  45},
100078abcf9SRichard Purdie 	{ 190,  43},
101078abcf9SRichard Purdie 	{ 189,  40},
102078abcf9SRichard Purdie 	{ 188,  38},
103078abcf9SRichard Purdie 	{ 187,  35},
104078abcf9SRichard Purdie 	{ 186,  33},
105078abcf9SRichard Purdie 	{ 185,  30},
106078abcf9SRichard Purdie 	{ 184,  28},
107078abcf9SRichard Purdie 	{ 183,  25},
108078abcf9SRichard Purdie 	{ 182,  23},
109078abcf9SRichard Purdie 	{ 181,  20},
110078abcf9SRichard Purdie 	{ 180,  18},
111078abcf9SRichard Purdie 	{ 179,  15},
112078abcf9SRichard Purdie 	{ 178,  13},
113078abcf9SRichard Purdie 	{ 177,  10},
114078abcf9SRichard Purdie 	{ 176,   8},
115078abcf9SRichard Purdie 	{ 175,   5},
116078abcf9SRichard Purdie 	{   0,   0},
117078abcf9SRichard Purdie };
118078abcf9SRichard Purdie 
11925af3b0fSEric Miao /* MAX1111 Commands */
12025af3b0fSEric Miao #define MAXCTRL_PD0      1u << 0
12125af3b0fSEric Miao #define MAXCTRL_PD1      1u << 1
12225af3b0fSEric Miao #define MAXCTRL_SGL      1u << 2
12325af3b0fSEric Miao #define MAXCTRL_UNI      1u << 3
12425af3b0fSEric Miao #define MAXCTRL_SEL_SH   4
12525af3b0fSEric Miao #define MAXCTRL_STR      1u << 7
12625af3b0fSEric Miao 
127078abcf9SRichard Purdie /*
128078abcf9SRichard Purdie  * Read MAX1111 ADC
129078abcf9SRichard Purdie  */
130b7557de4SRichard Purdie int sharpsl_pm_pxa_read_max1111(int channel)
131078abcf9SRichard Purdie {
132f8703dc8SRichard Purdie 	if (machine_is_tosa()) // Ugly, better move this function into another module
133f8703dc8SRichard Purdie 	    return 0;
134f8703dc8SRichard Purdie 
13545e2a9b4SEric Miao #ifdef CONFIG_CORGI_SSP_DEPRECATED
13645e2a9b4SEric Miao 	return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
13745e2a9b4SEric Miao 			| MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
13845e2a9b4SEric Miao #else
13925af3b0fSEric Miao 	extern int max1111_read_channel(int);
14025af3b0fSEric Miao 
141f16177c2SEric Miao 	/* max1111 accepts channels from 0-3, however,
142f16177c2SEric Miao 	 * it is encoded from 0-7 here in the code.
143f16177c2SEric Miao 	 */
144f16177c2SEric Miao 	return max1111_read_channel(channel >> 1);
14525af3b0fSEric Miao #endif
146078abcf9SRichard Purdie }
147078abcf9SRichard Purdie 
148b7557de4SRichard Purdie void sharpsl_pm_pxa_init(void)
149078abcf9SRichard Purdie {
150078abcf9SRichard Purdie 	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
151078abcf9SRichard Purdie 	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
152078abcf9SRichard Purdie 	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
153078abcf9SRichard Purdie 
154078abcf9SRichard Purdie 	/* Register interrupt handlers */
15552e405eaSThomas Gleixner 	if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED, "AC Input Detect", sharpsl_ac_isr)) {
156078abcf9SRichard Purdie 		dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
157078abcf9SRichard Purdie 	}
1586cab4860SDmitry Baryshkov 	else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQ_TYPE_EDGE_BOTH);
159078abcf9SRichard Purdie 
16052e405eaSThomas Gleixner 	if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED, "Battery Cover", sharpsl_fatal_isr)) {
161078abcf9SRichard Purdie 		dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
162078abcf9SRichard Purdie 	}
1636cab4860SDmitry Baryshkov 	else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQ_TYPE_EDGE_FALLING);
164078abcf9SRichard Purdie 
165078abcf9SRichard Purdie 	if (sharpsl_pm.machinfo->gpio_fatal) {
16652e405eaSThomas Gleixner 		if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED, "Fatal Battery", sharpsl_fatal_isr)) {
167078abcf9SRichard Purdie 			dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
168078abcf9SRichard Purdie 		}
1696cab4860SDmitry Baryshkov 		else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQ_TYPE_EDGE_FALLING);
170078abcf9SRichard Purdie 	}
171078abcf9SRichard Purdie 
172f8703dc8SRichard Purdie 	if (sharpsl_pm.machinfo->batfull_irq)
173078abcf9SRichard Purdie 	{
174078abcf9SRichard Purdie 		/* Register interrupt handler. */
17552e405eaSThomas Gleixner 		if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED, "CO", sharpsl_chrg_full_isr)) {
176078abcf9SRichard Purdie 			dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
177078abcf9SRichard Purdie 		}
1786cab4860SDmitry Baryshkov 		else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQ_TYPE_EDGE_RISING);
179078abcf9SRichard Purdie 	}
180078abcf9SRichard Purdie }
181078abcf9SRichard Purdie 
182b7557de4SRichard Purdie void sharpsl_pm_pxa_remove(void)
183078abcf9SRichard Purdie {
184078abcf9SRichard Purdie 	free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
185078abcf9SRichard Purdie 	free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
186078abcf9SRichard Purdie 
187078abcf9SRichard Purdie 	if (sharpsl_pm.machinfo->gpio_fatal)
188078abcf9SRichard Purdie 		free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
189078abcf9SRichard Purdie 
190f8703dc8SRichard Purdie 	if (sharpsl_pm.machinfo->batfull_irq)
191078abcf9SRichard Purdie 		free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
192078abcf9SRichard Purdie }
193