blob: 16b4ec67e3b6c03c41ff2b6316dc6613a27738fc [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>
Thomas Gleixner1623dee2006-07-01 22:32:20 +010021#include <linux/irq.h>
Richard Purdiec5e1ae92005-11-12 18:53:48 +000022#include <linux/platform_device.h>
Russell King61fde512007-02-26 21:04:29 +000023#include <linux/apm-emulation.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000024
Russell Kinga09e64f2008-08-05 16:14:15 +010025#include <mach/hardware.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000026#include <asm/mach-types.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010027#include <mach/pm.h>
Russell Kinga09e64f2008-08-05 16:14:15 +010028#include <mach/pxa2xx-gpio.h>
29#include <mach/sharpsl.h>
Richard Purdie078abcf2005-11-10 17:42:29 +000030#include "sharpsl.h"
31
Richard Purdie078abcf2005-11-10 17:42:29 +000032struct battery_thresh spitz_battery_levels_acin[] = {
33 { 213, 100},
34 { 212, 98},
35 { 211, 95},
36 { 210, 93},
37 { 209, 90},
38 { 208, 88},
39 { 207, 85},
40 { 206, 83},
41 { 205, 80},
42 { 204, 78},
43 { 203, 75},
44 { 202, 73},
45 { 201, 70},
46 { 200, 68},
47 { 199, 65},
48 { 198, 63},
49 { 197, 60},
50 { 196, 58},
51 { 195, 55},
52 { 194, 53},
53 { 193, 50},
54 { 192, 48},
55 { 192, 45},
56 { 191, 43},
57 { 191, 40},
58 { 190, 38},
59 { 190, 35},
60 { 189, 33},
61 { 188, 30},
62 { 187, 28},
63 { 186, 25},
64 { 185, 23},
65 { 184, 20},
66 { 183, 18},
67 { 182, 15},
68 { 181, 13},
69 { 180, 10},
70 { 179, 8},
71 { 178, 5},
72 { 0, 0},
73};
74
75struct battery_thresh spitz_battery_levels_noac[] = {
76 { 213, 100},
77 { 212, 98},
78 { 211, 95},
79 { 210, 93},
80 { 209, 90},
81 { 208, 88},
82 { 207, 85},
83 { 206, 83},
84 { 205, 80},
85 { 204, 78},
86 { 203, 75},
87 { 202, 73},
88 { 201, 70},
89 { 200, 68},
90 { 199, 65},
91 { 198, 63},
92 { 197, 60},
93 { 196, 58},
94 { 195, 55},
95 { 194, 53},
96 { 193, 50},
97 { 192, 48},
98 { 191, 45},
99 { 190, 43},
100 { 189, 40},
101 { 188, 38},
102 { 187, 35},
103 { 186, 33},
104 { 185, 30},
105 { 184, 28},
106 { 183, 25},
107 { 182, 23},
108 { 181, 20},
109 { 180, 18},
110 { 179, 15},
111 { 178, 13},
112 { 177, 10},
113 { 176, 8},
114 { 175, 5},
115 { 0, 0},
116};
117
Eric Miao25af3b02008-10-21 09:42:29 +0800118/* MAX1111 Commands */
119#define MAXCTRL_PD0 1u << 0
120#define MAXCTRL_PD1 1u << 1
121#define MAXCTRL_SGL 1u << 2
122#define MAXCTRL_UNI 1u << 3
123#define MAXCTRL_SEL_SH 4
124#define MAXCTRL_STR 1u << 7
125
Richard Purdie078abcf2005-11-10 17:42:29 +0000126/*
127 * Read MAX1111 ADC
128 */
Richard Purdieb7557de2006-01-05 20:44:55 +0000129int sharpsl_pm_pxa_read_max1111(int channel)
Richard Purdie078abcf2005-11-10 17:42:29 +0000130{
Richard Purdief8703dc2006-06-19 19:58:52 +0100131 if (machine_is_tosa()) // Ugly, better move this function into another module
132 return 0;
133
Eric Miao45e2a9b2008-10-21 11:36:19 +0800134#ifdef CONFIG_CORGI_SSP_DEPRECATED
135 return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
136 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
137#else
Eric Miao25af3b02008-10-21 09:42:29 +0800138 extern int max1111_read_channel(int);
139
Eric Miaof16177c2008-08-29 06:19:32 +0800140 /* max1111 accepts channels from 0-3, however,
141 * it is encoded from 0-7 here in the code.
142 */
143 return max1111_read_channel(channel >> 1);
Eric Miao25af3b02008-10-21 09:42:29 +0800144#endif
Richard Purdie078abcf2005-11-10 17:42:29 +0000145}
146
Richard Purdieb7557de2006-01-05 20:44:55 +0000147void sharpsl_pm_pxa_init(void)
Richard Purdie078abcf2005-11-10 17:42:29 +0000148{
Richard Purdie078abcf2005-11-10 17:42:29 +0000149 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
150 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
151 pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
152
153 /* Register interrupt handlers */
Thomas Gleixner52e405e2006-07-03 02:20:05 +0200154 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED, "AC Input Detect", sharpsl_ac_isr)) {
Richard Purdie078abcf2005-11-10 17:42:29 +0000155 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
156 }
Dmitry Baryshkov6cab4862008-07-27 04:23:31 +0100157 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQ_TYPE_EDGE_BOTH);
Richard Purdie078abcf2005-11-10 17:42:29 +0000158
Thomas Gleixner52e405e2006-07-03 02:20:05 +0200159 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED, "Battery Cover", sharpsl_fatal_isr)) {
Richard Purdie078abcf2005-11-10 17:42:29 +0000160 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
161 }
Dmitry Baryshkov6cab4862008-07-27 04:23:31 +0100162 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQ_TYPE_EDGE_FALLING);
Richard Purdie078abcf2005-11-10 17:42:29 +0000163
164 if (sharpsl_pm.machinfo->gpio_fatal) {
Thomas Gleixner52e405e2006-07-03 02:20:05 +0200165 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED, "Fatal Battery", sharpsl_fatal_isr)) {
Richard Purdie078abcf2005-11-10 17:42:29 +0000166 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
167 }
Dmitry Baryshkov6cab4862008-07-27 04:23:31 +0100168 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQ_TYPE_EDGE_FALLING);
Richard Purdie078abcf2005-11-10 17:42:29 +0000169 }
170
Richard Purdief8703dc2006-06-19 19:58:52 +0100171 if (sharpsl_pm.machinfo->batfull_irq)
Richard Purdie078abcf2005-11-10 17:42:29 +0000172 {
173 /* Register interrupt handler. */
Thomas Gleixner52e405e2006-07-03 02:20:05 +0200174 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED, "CO", sharpsl_chrg_full_isr)) {
Richard Purdie078abcf2005-11-10 17:42:29 +0000175 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
176 }
Dmitry Baryshkov6cab4862008-07-27 04:23:31 +0100177 else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQ_TYPE_EDGE_RISING);
Richard Purdie078abcf2005-11-10 17:42:29 +0000178 }
Richard Purdie078abcf2005-11-10 17:42:29 +0000179}
180
Richard Purdieb7557de2006-01-05 20:44:55 +0000181void sharpsl_pm_pxa_remove(void)
Richard Purdie078abcf2005-11-10 17:42:29 +0000182{
Richard Purdie078abcf2005-11-10 17:42:29 +0000183 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
184 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
185
186 if (sharpsl_pm.machinfo->gpio_fatal)
187 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
188
Richard Purdief8703dc2006-06-19 19:58:52 +0100189 if (sharpsl_pm.machinfo->batfull_irq)
Richard Purdie078abcf2005-11-10 17:42:29 +0000190 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
Richard Purdie078abcf2005-11-10 17:42:29 +0000191}