Use atomic operation for GPIOx_ENABLEs in ide_power_enable() for iPod Video. Thanks...
[kugel-rb.git] / firmware / target / arm / ipod / power-ipod.c
blob14c8bf21e124afa5fe9c86b7bfb34f30aef52783
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "config.h"
22 #include "cpu.h"
23 #include <stdbool.h>
24 #include "kernel.h"
25 #include "system.h"
26 #include "power.h"
27 #include "logf.h"
28 #include "pcf50605.h"
29 #include "usb.h"
30 #include "lcd.h"
31 #include "string.h"
32 #if CONFIG_CPU == PP5022 || CONFIG_CPU == PP5020
33 #include "rtc.h"
34 #endif
36 void power_init(void)
38 #if defined(IPOD_1G2G) || defined(IPOD_3G)
39 GPIOC_ENABLE |= 0x40; /* GPIO C6 is HDD power (low active) */
40 GPIOC_OUTPUT_VAL &= ~0x40; /* on by default */
41 GPIOC_OUTPUT_EN |= 0x40; /* enable output */
42 #endif
43 #ifndef IPOD_1G2G
44 pcf50605_init();
45 #endif
48 #if CONFIG_CHARGING
49 unsigned int power_input_status(void)
51 unsigned int status = POWER_INPUT_NONE;
53 #if defined(IPOD_NANO) || defined(IPOD_VIDEO)
54 if ((GPIOL_INPUT_VAL & 0x08) == 0)
55 status = POWER_INPUT_MAIN_CHARGER;
57 if ((GPIOL_INPUT_VAL & 0x10) != 0)
58 status |= POWER_INPUT_USB_CHARGER;
59 /* */
60 #elif defined(IPOD_4G) || defined(IPOD_COLOR) \
61 || defined(IPOD_MINI) || defined(IPOD_MINI2G)
62 /* C2 is firewire power */
63 if ((GPIOC_INPUT_VAL & 0x04) == 0)
64 status = POWER_INPUT_MAIN_CHARGER;
66 if ((GPIOD_INPUT_VAL & 0x08) != 0)
67 status |= POWER_INPUT_USB_CHARGER;
68 /* */
69 #elif defined(IPOD_3G)
70 /* firewire power */
71 if ((GPIOC_INPUT_VAL & 0x10) == 0)
72 status = POWER_INPUT_MAIN_CHARGER;
73 /* */
74 #else
75 /* This needs filling in for other ipods. */
76 #endif
78 return status;
81 /* Returns true if the unit is charging the batteries. */
82 bool charging_state(void) {
83 #if defined(IPOD_COLOR)
84 /* 0x70000088 appears to be the input value for GPO32 bits.
85 Write a zero to 0x70000088 before reading.
86 To enable input set the corresponding 0x7000008C bit,
87 and clear the corresponding GPO32_ENABLE bit. */
88 outl(0, 0x70000088);
89 return (inl(0x70000088) & 1)?false:true;
90 #else
91 return (GPIOB_INPUT_VAL & 0x01)?false:true;
92 #endif
94 #endif /* CONFIG_CHARGING */
97 void ide_power_enable(bool on)
99 #if defined(IPOD_1G2G) || defined(IPOD_3G)
100 if (on)
101 GPIOC_OUTPUT_VAL &= ~0x40;
102 else
103 GPIOC_OUTPUT_VAL |= 0x40;
104 #elif defined(IPOD_4G) || defined(IPOD_COLOR) \
105 || defined(IPOD_MINI) || defined(IPOD_MINI2G)
106 if (on)
108 GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 0x04);
109 DEV_EN |= DEV_IDE0;
111 else
113 DEV_EN &= ~DEV_IDE0;
114 GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 0x04);
116 #elif defined(IPOD_VIDEO)
117 if (on)
119 GPO32_VAL &= ~0x40000000;
120 sleep(1); /* only need 4 ms */
121 DEV_EN |= DEV_IDE0;
122 GPIOG_ENABLE = 0;
123 GPIOH_ENABLE = 0;
124 GPIO_CLEAR_BITWISE(GPIOI_ENABLE, 0xBF);
125 GPIO_CLEAR_BITWISE(GPIOK_ENABLE, 0x1F);
126 udelay(10);
128 else
130 DEV_EN &= ~DEV_IDE0;
131 udelay(10);
132 GPIOG_ENABLE = 0xFF;
133 GPIOH_ENABLE = 0xFF;
134 GPIO_SET_BITWISE(GPIOI_ENABLE, 0xBF);
135 GPIO_SET_BITWISE(GPIOK_ENABLE, 0x1F);
136 GPO32_VAL |= 0x40000000;
138 #else /* Nano */
139 (void)on; /* Do nothing. */
140 #endif
143 bool ide_powered(void)
145 #if defined(IPOD_1G2G) || defined(IPOD_3G)
146 return !(GPIOC_OUTPUT_VAL & 0x40);
147 #elif defined(IPOD_4G) || defined(IPOD_COLOR) \
148 || defined(IPOD_MINI) || defined(IPOD_MINI2G)
149 return !(GPIOJ_OUTPUT_VAL & 0x04);
150 #elif defined(IPOD_VIDEO)
151 return !(GPO32_VAL & 0x40000000);
152 #else /* Nano */
153 return true; /* Pretend we are always powered */
154 #endif
157 void power_off(void)
159 #if defined(HAVE_LCD_COLOR) && !defined(HAVE_LCD_SHUTDOWN)
160 /* Clear the screen and backdrop to
161 remove ghosting effect on shutdown */
162 lcd_set_backdrop(NULL);
163 lcd_set_background(LCD_WHITE);
164 lcd_clear_display();
165 lcd_update();
166 sleep(HZ/16);
167 #endif
169 #ifndef BOOTLOADER
170 #if CONFIG_CPU == PP5022 || CONFIG_CPU == PP5020
171 /* When shut down by OF, wakeup via alarm is enabled. This resets the
172 alarm time so an unintended wakeup does not occur. */
173 if (!(pcf50605_wakeup_flags & 0x10))
174 rtc_enable_alarm(false);
175 #endif
176 #if defined(IPOD_1G2G)
177 /* we cannot turn off the 1st gen/ 2nd gen yet. Need to figure out sleep mode. */
178 system_reboot();
179 #elif CONFIG_CPU == PP5022
180 /* The OF in flash assumes boot failed because the battery is low.
181 If there is no charger connected, this leads to a shutdown.
183 memcpy((void *)(0x4001ff00+8), "booting!", 8);
184 system_reboot();
185 #elif CONFIG_CPU == PP5020
186 memcpy((void *)(0x40017f00+8), "booting!", 8);
187 system_reboot();
188 #else
189 /* We don't turn off the ipod, we put it in a deep sleep */
190 pcf50605_standby_mode();
191 #endif
192 #endif