| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 1 | /* | 
|  | 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 Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 18 | #include <linux/init.h> | 
|  | 19 | #include <linux/kernel.h> | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 20 | #include <linux/interrupt.h> | 
| Thomas Gleixner | 1623dee | 2006-07-01 22:32:20 +0100 | [diff] [blame] | 21 | #include <linux/irq.h> | 
| Richard Purdie | c5e1ae9 | 2005-11-12 18:53:48 +0000 | [diff] [blame] | 22 | #include <linux/platform_device.h> | 
| Russell King | 61fde51 | 2007-02-26 21:04:29 +0000 | [diff] [blame] | 23 | #include <linux/apm-emulation.h> | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 24 |  | 
|  | 25 | #include <asm/hardware.h> | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 26 | #include <asm/mach-types.h> | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 27 | #include <asm/arch/pm.h> | 
|  | 28 | #include <asm/arch/pxa-regs.h> | 
| eric miao | a683b14 | 2008-03-03 09:44:25 +0800 | [diff] [blame] | 29 | #include <asm/arch/pxa2xx-gpio.h> | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 30 | #include <asm/arch/sharpsl.h> | 
|  | 31 | #include "sharpsl.h" | 
|  | 32 |  | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 33 | struct 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 |  | 
|  | 76 | struct 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 Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 127 | /* | 
|  | 128 | * Read MAX1111 ADC | 
|  | 129 | */ | 
| Richard Purdie | b7557de | 2006-01-05 20:44:55 +0000 | [diff] [blame] | 130 | int sharpsl_pm_pxa_read_max1111(int channel) | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 131 | { | 
| Richard Purdie | f8703dc | 2006-06-19 19:58:52 +0100 | [diff] [blame] | 132 | if (machine_is_tosa()) // Ugly, better move this function into another module | 
|  | 133 | return 0; | 
|  | 134 |  | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 135 | return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1 | 
|  | 136 | | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR); | 
|  | 137 | } | 
|  | 138 |  | 
| Richard Purdie | b7557de | 2006-01-05 20:44:55 +0000 | [diff] [blame] | 139 | void sharpsl_pm_pxa_init(void) | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 140 | { | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 141 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN); | 
|  | 142 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN); | 
|  | 143 | pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN); | 
|  | 144 |  | 
|  | 145 | /* Register interrupt handlers */ | 
| Thomas Gleixner | 52e405e | 2006-07-03 02:20:05 +0200 | [diff] [blame] | 146 | if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED, "AC Input Detect", sharpsl_ac_isr)) { | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 147 | dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); | 
|  | 148 | } | 
| Dmitry Baryshkov | 6cab486 | 2008-07-27 04:23:31 +0100 | [diff] [blame] | 149 | else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQ_TYPE_EDGE_BOTH); | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 150 |  | 
| Thomas Gleixner | 52e405e | 2006-07-03 02:20:05 +0200 | [diff] [blame] | 151 | if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED, "Battery Cover", sharpsl_fatal_isr)) { | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 152 | dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); | 
|  | 153 | } | 
| Dmitry Baryshkov | 6cab486 | 2008-07-27 04:23:31 +0100 | [diff] [blame] | 154 | else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQ_TYPE_EDGE_FALLING); | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 155 |  | 
|  | 156 | if (sharpsl_pm.machinfo->gpio_fatal) { | 
| Thomas Gleixner | 52e405e | 2006-07-03 02:20:05 +0200 | [diff] [blame] | 157 | if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED, "Fatal Battery", sharpsl_fatal_isr)) { | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 158 | dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); | 
|  | 159 | } | 
| Dmitry Baryshkov | 6cab486 | 2008-07-27 04:23:31 +0100 | [diff] [blame] | 160 | else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQ_TYPE_EDGE_FALLING); | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 161 | } | 
|  | 162 |  | 
| Richard Purdie | f8703dc | 2006-06-19 19:58:52 +0100 | [diff] [blame] | 163 | if (sharpsl_pm.machinfo->batfull_irq) | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 164 | { | 
|  | 165 | /* Register interrupt handler. */ | 
| Thomas Gleixner | 52e405e | 2006-07-03 02:20:05 +0200 | [diff] [blame] | 166 | if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED, "CO", sharpsl_chrg_full_isr)) { | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 167 | dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); | 
|  | 168 | } | 
| Dmitry Baryshkov | 6cab486 | 2008-07-27 04:23:31 +0100 | [diff] [blame] | 169 | else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQ_TYPE_EDGE_RISING); | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 170 | } | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 171 | } | 
|  | 172 |  | 
| Richard Purdie | b7557de | 2006-01-05 20:44:55 +0000 | [diff] [blame] | 173 | void sharpsl_pm_pxa_remove(void) | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 174 | { | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 175 | free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); | 
|  | 176 | free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); | 
|  | 177 |  | 
|  | 178 | if (sharpsl_pm.machinfo->gpio_fatal) | 
|  | 179 | free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); | 
|  | 180 |  | 
| Richard Purdie | f8703dc | 2006-06-19 19:58:52 +0100 | [diff] [blame] | 181 | if (sharpsl_pm.machinfo->batfull_irq) | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 182 | free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); | 
| Richard Purdie | 078abcf | 2005-11-10 17:42:29 +0000 | [diff] [blame] | 183 | } |