summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s5l8702')
-rw-r--r--firmware/target/arm/s5l8702/debug-s5l8702.c29
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c162
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/pmu-target.h25
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c2
-rw-r--r--firmware/target/arm/s5l8702/system-s5l8702.c1
5 files changed, 203 insertions, 16 deletions
diff --git a/firmware/target/arm/s5l8702/debug-s5l8702.c b/firmware/target/arm/s5l8702/debug-s5l8702.c
index 614019bac1..48a20a97c2 100644
--- a/firmware/target/arm/s5l8702/debug-s5l8702.c
+++ b/firmware/target/arm/s5l8702/debug-s5l8702.c
@@ -102,14 +102,14 @@ bool dbg_hw_info(void)
102 _DEBUG_PRINTF("PMU:"); 102 _DEBUG_PRINTF("PMU:");
103 for(i=0;i<7;i++) 103 for(i=0;i<7;i++)
104 { 104 {
105 char *device[] = {"(unknown)", 105 char *device[] = {"unknown",
106 "(unknown)", 106 "unknown",
107 "(unknown)", 107 "LCD",
108 "(unknown)", 108 "AUDIO",
109 "(unknown)", 109 "unknown",
110 "(unknown)", 110 "CLICKWHEEL",
111 "(unknown)"}; 111 "ACCESSORY"};
112 _DEBUG_PRINTF("ldo%d %s: %dmV %s",i, 112 _DEBUG_PRINTF("ldo%d %s: %dmV (%s)",i,
113 pmu_read(0x2e + (i << 1))?" on":"off", 113 pmu_read(0x2e + (i << 1))?" on":"off",
114 900 + pmu_read(0x2d + (i << 1))*100, 114 900 + pmu_read(0x2d + (i << 1))*100,
115 device[i]); 115 device[i]);
@@ -120,6 +120,19 @@ bool dbg_hw_info(void)
120 _DEBUG_PRINTF("charging: %s", charging_state() ? "true" : "false"); 120 _DEBUG_PRINTF("charging: %s", charging_state() ? "true" : "false");
121 _DEBUG_PRINTF("backlight: %s", pmu_read(0x29) ? "on" : "off"); 121 _DEBUG_PRINTF("backlight: %s", pmu_read(0x29) ? "on" : "off");
122 _DEBUG_PRINTF("brightness value: %d", pmu_read(0x28)); 122 _DEBUG_PRINTF("brightness value: %d", pmu_read(0x28));
123 line++;
124 _DEBUG_PRINTF("USB present: %s",
125 pmu_usb_present() ? "true" : "false");
126#if CONFIG_CHARGING
127 _DEBUG_PRINTF("FW present: %s",
128 pmu_firewire_present() ? "true" : "false");
129#endif
130 _DEBUG_PRINTF("holdswitch locked: %s",
131 pmu_holdswitch_locked() ? "true" : "false");
132#ifdef IPOD_ACCESSORY_PROTOCOL
133 _DEBUG_PRINTF("accessory present: %s",
134 pmu_accessory_present() ? "true" : "false");
135#endif
123 } 136 }
124#ifdef UC870X_DEBUG 137#ifdef UC870X_DEBUG
125 else if(state==2) 138 else if(state==2)
diff --git a/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
index 920c93ad5d..4200308861 100644
--- a/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/pmu-ipod6g.c
@@ -21,8 +21,12 @@
21 21
22#include "config.h" 22#include "config.h"
23#include "kernel.h" 23#include "kernel.h"
24#include "i2c-s5l8702.h" 24#include "thread.h"
25
25#include "pmu-target.h" 26#include "pmu-target.h"
27#include "i2c-s5l8702.h"
28#include "gpio-s5l8702.h"
29
26 30
27static struct mutex pmu_adc_mutex; 31static struct mutex pmu_adc_mutex;
28 32
@@ -50,11 +54,6 @@ int pmu_write(int address, unsigned char val)
50 return pmu_write_multiple(address, 1, &val); 54 return pmu_write_multiple(address, 1, &val);
51} 55}
52 56
53void pmu_init(void)
54{
55 mutex_init(&pmu_adc_mutex);
56}
57
58int pmu_read_adc(unsigned int adc) 57int pmu_read_adc(unsigned int adc)
59{ 58{
60 int data = 0; 59 int data = 0;
@@ -144,6 +143,157 @@ void pmu_write_rtc(unsigned char* buffer)
144} 143}
145 144
146/* 145/*
146 * eINT
147 */
148#define Q_EINT 0
149
150static char pmu_thread_stack[DEFAULT_STACK_SIZE/4];
151static struct event_queue pmu_queue;
152static unsigned char ints_msk[6];
153
154static void pmu_eint_isr(struct eint_handler*);
155
156static struct eint_handler pmu_eint = {
157 .gpio_n = GPIO_EINT_PMU,
158 .type = EIC_INTTYPE_LEVEL,
159 .level = EIC_INTLEVEL_LOW,
160 .isr = pmu_eint_isr,
161};
162
163static int pmu_input_holdswitch;
164static int pmu_input_usb;
165
166int pmu_holdswitch_locked(void)
167{
168 return pmu_input_holdswitch;
169}
170
171int pmu_usb_present(void)
172{
173 return pmu_input_usb;
174}
175
176#ifdef IPOD_ACCESSORY_PROTOCOL
177static int pmu_input_accessory;
178
179int pmu_accessory_present(void)
180{
181 return pmu_input_accessory;
182}
183#endif
184
185#if CONFIG_CHARGING
186static int pmu_input_firewire;
187
188int pmu_firewire_present(void)
189{
190 return pmu_input_firewire;
191}
192
193static void pmu_read_inputs_mbcs(void)
194{
195 pmu_input_firewire = !!(pmu_read(PCF5063X_REG_MBCS1)
196 & PCF5063X_MBCS1_ADAPTPRES);
197}
198#endif
199
200static void pmu_read_inputs_gpio(void)
201{
202 pmu_input_holdswitch = !(pmu_read(PCF50635_REG_GPIOSTAT)
203 & PCF50635_GPIOSTAT_GPIO2);
204}
205
206static void pmu_read_inputs_ooc(void)
207{
208 unsigned char oocstat = pmu_read(PCF5063X_REG_OOCSTAT);
209 pmu_input_usb = !!(oocstat & PCF5063X_OOCSTAT_EXTON2);
210#ifdef IPOD_ACCESSORY_PROTOCOL
211 pmu_input_accessory = !(oocstat & PCF5063X_OOCSTAT_EXTON3);
212#endif
213}
214
215static void pmu_eint_isr(struct eint_handler *h)
216{
217 eint_unregister(h);
218 queue_post(&pmu_queue, Q_EINT, 0);
219}
220
221static void NORETURN_ATTR pmu_thread(void)
222{
223 struct queue_event ev;
224 unsigned char ints[6];
225
226 while (true)
227 {
228 queue_wait_w_tmo(&pmu_queue, &ev, TIMEOUT_BLOCK);
229 switch (ev.id)
230 {
231 case Q_EINT:
232 /* read (clear) PMU interrupts, this will also
233 raise the PMU IRQ pin */
234 pmu_read_multiple(PCF5063X_REG_INT1, 2, ints);
235 ints[5] = pmu_read(PCF50635_REG_INT6);
236
237#if CONFIG_CHARGING
238 if (ints[0] & ~ints_msk[0]) pmu_read_inputs_mbcs();
239#endif
240 if (ints[1] & ~ints_msk[1]) pmu_read_inputs_ooc();
241 if (ints[5] & ~ints_msk[5]) pmu_read_inputs_gpio();
242
243 eint_register(&pmu_eint);
244 break;
245
246 case SYS_TIMEOUT:
247 break;
248 }
249 }
250}
251
252/* main init */
253void pmu_init(void)
254{
255 mutex_init(&pmu_adc_mutex);
256 queue_init(&pmu_queue, false);
257
258 create_thread(pmu_thread,
259 pmu_thread_stack, sizeof(pmu_thread_stack), 0,
260 "PMU" IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU));
261
262 /* configure PMU interrutps */
263 for (int i = 0; i < 6; i++)
264 ints_msk[i] = 0xff;
265
266#if CONFIG_CHARGING
267 ints_msk[0] &= ~PCF5063X_INT1_ADPINS & /* FireWire */
268 ~PCF5063X_INT1_ADPREM;
269#endif
270 ints_msk[1] &= ~PCF5063X_INT2_EXTON2R & /* USB */
271 ~PCF5063X_INT2_EXTON2F;
272#ifdef IPOD_ACCESSORY_PROTOCOL
273 ints_msk[1] &= ~PCF5063X_INT2_EXTON3R & /* Accessory */
274 ~PCF5063X_INT2_EXTON3F;
275#endif
276 ints_msk[5] &= ~PCF50635_INT6_GPIO2; /* Holdswitch */
277
278 pmu_write_multiple(PCF5063X_REG_INT1M, 5, ints_msk);
279 pmu_write(PCF50635_REG_INT6M, ints_msk[5]);
280
281 /* clear all */
282 unsigned char ints[5];
283 pmu_read_multiple(PCF5063X_REG_INT1, 5, ints);
284 pmu_read(PCF50635_REG_INT6);
285
286 /* get initial values */
287#if CONFIG_CHARGING
288 pmu_read_inputs_mbcs();
289#endif
290 pmu_read_inputs_ooc();
291 pmu_read_inputs_gpio();
292
293 eint_register(&pmu_eint);
294}
295
296/*
147 * preinit 297 * preinit
148 */ 298 */
149int pmu_rd_multiple(int address, int count, unsigned char* buffer) 299int pmu_rd_multiple(int address, int count, unsigned char* buffer)
diff --git a/firmware/target/arm/s5l8702/ipod6g/pmu-target.h b/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
index d090f72a67..2274b4061f 100644
--- a/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
+++ b/firmware/target/arm/s5l8702/ipod6g/pmu-target.h
@@ -30,7 +30,21 @@
30/* undocummented PMU registers */ 30/* undocummented PMU registers */
31#define PCF50635_REG_INT6 0x85 31#define PCF50635_REG_INT6 0x85
32#define PCF50635_REG_INT6M 0x86 32#define PCF50635_REG_INT6M 0x86
33#define PCF50635_REG_GPIOSTAT 0x87 /* bit1: GPIO2 status (TBC) */ 33#define PCF50635_REG_GPIOSTAT 0x87
34
35enum pcf50635_reg_int6 {
36 PCF50635_INT6_GPIO1 = 0x01, /* TBC */
37 PCF50635_INT6_GPIO2 = 0x02,
38};
39
40enum pcf50635_reg_gpiostat {
41 PCF50635_GPIOSTAT_GPIO1 = 0x01, /* TBC */
42 PCF50635_GPIOSTAT_GPIO2 = 0x02,
43};
44
45
46/* GPIO for external PMU interrupt */
47#define GPIO_EINT_PMU 0x7b
34 48
35/* LDOs */ 49/* LDOs */
36#define LDO_UNK1 1 /* TBC: SoC voltage (USB) */ 50#define LDO_UNK1 1 /* TBC: SoC voltage (USB) */
@@ -77,6 +91,15 @@ void pmu_read_rtc(unsigned char* buffer);
77void pmu_write_rtc(unsigned char* buffer); 91void pmu_write_rtc(unsigned char* buffer);
78void pmu_hdd_power(bool on); 92void pmu_hdd_power(bool on);
79 93
94int pmu_holdswitch_locked(void);
95int pmu_usb_present(void);
96#if CONFIG_CHARGING
97int pmu_firewire_present(void);
98#endif
99#ifdef IPOD_ACCESSORY_PROTOCOL
100int pmu_accessory_present(void);
101#endif
102
80void pmu_preinit(void); 103void pmu_preinit(void);
81#ifdef BOOTLOADER 104#ifdef BOOTLOADER
82unsigned char pmu_rd(int address); 105unsigned char pmu_rd(int address);
diff --git a/firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c
index 57358b8cb6..d3224d2a66 100644
--- a/firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c
@@ -41,6 +41,8 @@ void power_off(void)
41 41
42void power_init(void) 42void power_init(void)
43{ 43{
44 pmu_init();
45
44 idepowered = false; 46 idepowered = false;
45 47
46 /* DOWN1CTL: CPU DVM step time = 30us (default: no DVM) */ 48 /* DOWN1CTL: CPU DVM step time = 30us (default: no DVM) */
diff --git a/firmware/target/arm/s5l8702/system-s5l8702.c b/firmware/target/arm/s5l8702/system-s5l8702.c
index cbe8bfcaf7..459f4c36c6 100644
--- a/firmware/target/arm/s5l8702/system-s5l8702.c
+++ b/firmware/target/arm/s5l8702/system-s5l8702.c
@@ -207,7 +207,6 @@ void system_init(void)
207#endif 207#endif
208 gpio_init(); 208 gpio_init();
209 eint_init(); 209 eint_init();
210 pmu_init();
211 dma_init(); 210 dma_init();
212#ifdef HAVE_SERIAL 211#ifdef HAVE_SERIAL
213 uart_init(); 212 uart_init();