summaryrefslogtreecommitdiff
path: root/firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c')
-rw-r--r--firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c55
1 files changed, 38 insertions, 17 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
25static struct mutex adc_mutex NOCACHEBSS_ATTR; 25static struct mutex adc_mutex NOCACHEBSS_ATTR;
26 26
27/* used in the 2nd gen ADC interrupt */
28static unsigned int_data;
29static int int_status = -1;
30
27unsigned short adc_scan(int channel) 31unsigned 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. */
77void 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
80void adc_init(void) 101void adc_init(void)