diff options
Diffstat (limited to 'firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c')
-rw-r--r-- | firmware/target/arm/ipod/1g2g/adc-ipod-1g2g.c | 55 |
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 | ||
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) |