diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c | 55 | ||||
-rw-r--r-- | firmware/target/arm/system-pp5002.c | 14 |
2 files changed, 50 insertions, 19 deletions
diff --git a/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c b/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c index 759b6fb592..8866c3dcde 100644 --- a/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c +++ b/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c | |||
@@ -24,18 +24,22 @@ | |||
24 | 24 | ||
25 | static struct mutex adc_mutex NOCACHEBSS_ATTR; | 25 | static struct mutex adc_mutex NOCACHEBSS_ATTR; |
26 | 26 | ||
27 | /* used in the 2nd gen ADC interrupt */ | ||
28 | static unsigned int_data; | ||
29 | static int int_status = -1; | ||
30 | |||
27 | unsigned short adc_scan(int channel) | 31 | unsigned short adc_scan(int channel) |
28 | { | 32 | { |
29 | int i, j; | ||
30 | unsigned short data = 0; | 33 | unsigned short data = 0; |
31 | unsigned pval; | ||
32 | 34 | ||
33 | (void)channel; /* there is only one */ | 35 | (void)channel; /* there is only one */ |
34 | spinlock_lock(&adc_mutex); | 36 | spinlock_lock(&adc_mutex); |
35 | 37 | ||
36 | if ((IPOD_HW_REVISION >> 16) == 1) | 38 | if ((IPOD_HW_REVISION >> 16) == 1) |
37 | { | 39 | { |
38 | pval = GPIOB_OUTPUT_VAL; | 40 | int i, j; |
41 | unsigned pval = GPIOB_OUTPUT_VAL; | ||
42 | |||
39 | GPIOB_OUTPUT_VAL = pval | 0x04; /* B2 -> high */ | 43 | GPIOB_OUTPUT_VAL = pval | 0x04; /* B2 -> high */ |
40 | for (i = 32; i > 0; --i); | 44 | for (i = 32; i > 0; --i); |
41 | 45 | ||
@@ -55,26 +59,43 @@ unsigned short adc_scan(int channel) | |||
55 | } | 59 | } |
56 | else if ((IPOD_HW_REVISION >> 16) == 2) | 60 | else if ((IPOD_HW_REVISION >> 16) == 2) |
57 | { | 61 | { |
58 | pval = GPIOB_OUTPUT_VAL; | 62 | int_status = 0; |
59 | GPIOB_OUTPUT_VAL = pval | 0x0a; /* B1, B3 -> high */ | 63 | GPIOB_INT_LEV |= 0x04; /* high active */ |
60 | while (!(GPIOB_INPUT_VAL & 0x04)); /* wait for B2 == 1 */ | 64 | GPIOB_INT_EN |= 0x04; /* enable interrupt */ |
65 | GPIOB_OUTPUT_VAL |= 0x0a; /* B1, B3 -> high: start conversion */ | ||
61 | 66 | ||
62 | GPIOB_OUTPUT_VAL = pval; /* B1, B3 -> low */ | 67 | while (int_status >= 0) |
63 | while (GPIOB_INPUT_VAL & 0x04); /* wait for B2 == 0 */ | 68 | yield(); |
64 | 69 | ||
65 | for (j = 0; j < 8; j++) | 70 | data = int_data & 0xff; |
66 | { | 71 | } |
67 | GPIOB_OUTPUT_VAL = pval | 0x02; /* B1 -> high */ | 72 | spinlock_unlock(&adc_mutex); |
68 | while (!(GPIOB_INPUT_VAL & 0x04)); /* wait for B2 == 1 */ | 73 | return data; |
74 | } | ||
69 | 75 | ||
70 | data = (data << 1) | ((GPIOB_INPUT_VAL & 0x10) >> 4); | 76 | /* Used for 2nd gen only. Conversion can take several milliseconds there. */ |
77 | void ipod_2g_adc_int(void) | ||
78 | { | ||
79 | if (GPIOB_INPUT_VAL & 0x04) | ||
80 | { | ||
81 | int_data = (int_data << 1) | ((GPIOB_INPUT_VAL & 0x10) >> 4); | ||
71 | 82 | ||
72 | GPIOB_OUTPUT_VAL = pval; /* B1 -> low */ | 83 | GPIOB_OUTPUT_VAL &= ~0x0a; /* B1, B3 -> low */ |
73 | while (GPIOB_INPUT_VAL & 0x04); /* wait for B2 == 0 */ | 84 | /* B3 needs to be set low in the first call only, but then stays low |
85 | * anyway so no need for special handling */ | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | if (++int_status > 8) | ||
90 | { | ||
91 | GPIOB_INT_EN &= ~0x04; | ||
92 | int_status = -1; | ||
74 | } | 93 | } |
94 | else | ||
95 | GPIOB_OUTPUT_VAL |= 0x02; /* B1 -> high */ | ||
75 | } | 96 | } |
76 | spinlock_unlock(&adc_mutex); | 97 | GPIOB_INT_LEV ^= 0x04; /* toggle interrupt level */ |
77 | return data; | 98 | GPIOB_INT_CLR = 0x04; /* acknowledge interrupt */ |
78 | } | 99 | } |
79 | 100 | ||
80 | void adc_init(void) | 101 | void adc_init(void) |
diff --git a/firmware/target/arm/system-pp5002.c b/firmware/target/arm/system-pp5002.c index 6d32d258cc..38dfe5b49c 100644 --- a/firmware/target/arm/system-pp5002.c +++ b/firmware/target/arm/system-pp5002.c | |||
@@ -22,6 +22,7 @@ | |||
22 | extern void TIMER1(void); | 22 | extern void TIMER1(void); |
23 | extern void TIMER2(void); | 23 | extern void TIMER2(void); |
24 | extern void ipod_3g_button_int(void); | 24 | extern void ipod_3g_button_int(void); |
25 | extern void ipod_2g_adc_int(void); | ||
25 | 26 | ||
26 | void irq(void) | 27 | void irq(void) |
27 | { | 28 | { |
@@ -32,8 +33,17 @@ void irq(void) | |||
32 | else if (CPU_INT_STAT & TIMER2_MASK) | 33 | else if (CPU_INT_STAT & TIMER2_MASK) |
33 | TIMER2(); | 34 | TIMER2(); |
34 | else if (CPU_INT_STAT & GPIO_MASK) | 35 | else if (CPU_INT_STAT & GPIO_MASK) |
35 | ipod_3g_button_int(); | 36 | { |
36 | } else { | 37 | if (GPIOA_INT_STAT) |
38 | ipod_3g_button_int(); | ||
39 | #ifdef IPOD_1G2G | ||
40 | if (GPIOB_INT_STAT & 0x04) | ||
41 | ipod_2g_adc_int(); | ||
42 | #endif | ||
43 | } | ||
44 | } | ||
45 | else | ||
46 | { | ||
37 | if (COP_INT_STAT & TIMER1_MASK) | 47 | if (COP_INT_STAT & TIMER1_MASK) |
38 | TIMER1(); | 48 | TIMER1(); |
39 | else if (COP_INT_STAT & TIMER2_MASK) | 49 | else if (COP_INT_STAT & TIMER2_MASK) |