summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iaudio/x5
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iaudio/x5')
-rwxr-xr-xfirmware/target/coldfire/iaudio/x5/adc-x5.c44
-rw-r--r--firmware/target/coldfire/iaudio/x5/pcf50606-x5.c28
2 files changed, 58 insertions, 14 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/adc-x5.c b/firmware/target/coldfire/iaudio/x5/adc-x5.c
index fc45da8624..c923951e31 100755
--- a/firmware/target/coldfire/iaudio/x5/adc-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/adc-x5.c
@@ -26,19 +26,47 @@
26 26
27static unsigned short adcdata[NUM_ADC_CHANNELS]; 27static unsigned short adcdata[NUM_ADC_CHANNELS];
28 28
29static int channelnum[] = 29static const int adcc2_parms[] =
30{ 30{
31 5, /* ADC_BUTTONS (ADCIN2) */ 31 [ADC_BUTTONS] = 0x80 | (5 << 1) | 1, /* ADCIN2 */
32 6, /* ADC_REMOTE (ADCIN3) */ 32 [ADC_REMOTE] = 0x80 | (6 << 1) | 1, /* ADCIN3 */
33 0, /* ADC_BATTERY (BATVOLT, resistive divider) */ 33 [ADC_BATTERY] = 0x80 | (0 << 1) | 1, /* BATVOLT, resistive divider */
34}; 34};
35 35
36/* have buttons scan by default */
37static volatile bool button_scan_on = true;
38
39void adc_enable_button_scan(bool enable)
40{
41 button_scan_on = enable;
42}
43
44bool adc_get_button_scan_enabled(void)
45{
46 return button_scan_on;
47}
48
36unsigned short adc_scan(int channel) 49unsigned short adc_scan(int channel)
37{ 50{
38 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 51 int level;
39 unsigned char data; 52 unsigned char data;
40 53
41 pcf50606_write(0x2f, 0x80 | (channelnum[channel] << 1) | 1); 54 if (channel == ADC_BUTTONS)
55 {
56 /* no button scan if nothing pushed */
57 if (!button_scan_on)
58 return adcdata[channel] = 0xff;
59 }
60 else if (channel == ADC_REMOTE)
61 {
62 /* no remote scan if not plugged */
63 if (GPIO_READ & 0x01000000)
64 return adcdata[channel] = 0xff;
65 }
66
67 level = set_irq_level(HIGHEST_IRQ_LEVEL);
68
69 pcf50606_write(0x2f, adcc2_parms[channel]);
42 data = pcf50606_read(0x30); 70 data = pcf50606_read(0x30);
43 71
44 adcdata[channel] = data; 72 adcdata[channel] = data;
@@ -56,7 +84,7 @@ static int adc_counter;
56 84
57static void adc_tick(void) 85static void adc_tick(void)
58{ 86{
59 if(++adc_counter == HZ) 87 if (++adc_counter == HZ)
60 { 88 {
61 adc_counter = 0; 89 adc_counter = 0;
62 adc_scan(ADC_BATTERY); 90 adc_scan(ADC_BATTERY);
diff --git a/firmware/target/coldfire/iaudio/x5/pcf50606-x5.c b/firmware/target/coldfire/iaudio/x5/pcf50606-x5.c
index 58ff5d5cb0..8b3655c107 100644
--- a/firmware/target/coldfire/iaudio/x5/pcf50606-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/pcf50606-x5.c
@@ -20,6 +20,7 @@
20#include "system.h" 20#include "system.h"
21#include "kernel.h" 21#include "kernel.h"
22#include "pcf50606.h" 22#include "pcf50606.h"
23#include "adc.h"
23#include "powermgmt.h" 24#include "powermgmt.h"
24 25
25/* These voltages were determined by measuring the output of the PCF50606 26/* These voltages were determined by measuring the output of the PCF50606
@@ -44,7 +45,7 @@ static void init_pmu_interrupts(void)
44 { 45 {
45 ~0x04, /* unmask ONKEY1S */ 46 ~0x04, /* unmask ONKEY1S */
46 ~0x00, 47 ~0x00,
47 ~0x00 48 ~0x06, /* unmask ACDREM, ACDINS */
48 }; 49 };
49 50
50 /* make sure GPI0 interrupt is off before unmasking anything */ 51 /* make sure GPI0 interrupt is off before unmasking anything */
@@ -63,6 +64,9 @@ static void init_pmu_interrupts(void)
63 64
64static inline void enable_pmu_interrupts(void) 65static inline void enable_pmu_interrupts(void)
65{ 66{
67 /* clear pending GPI0 interrupts first or it may miss the first
68 H-L transition */
69 or_l(0x00000100, &GPIO_INT_CLEAR);
66 or_l(0x3, &INTPRI5); /* INT32 - Priority 3 */ 70 or_l(0x3, &INTPRI5); /* INT32 - Priority 3 */
67} 71}
68 72
@@ -86,6 +90,9 @@ void pcf50606_init(void)
86 pcf50606_write(0x38, 0xb0); /* Backlight ON, GPO1INV=1, GPO1ACT=011 */ 90 pcf50606_write(0x38, 0xb0); /* Backlight ON, GPO1INV=1, GPO1ACT=011 */
87#endif 91#endif
88 92
93 /* Accessory detect */
94 pcf50606_write(0x33, 0x8e); /* ACDAPE=1, THRSHLD=2.40V */
95
89 /* allow GPI0 interrupts from PMU now */ 96 /* allow GPI0 interrupts from PMU now */
90 enable_pmu_interrupts(); 97 enable_pmu_interrupts();
91} 98}
@@ -101,12 +108,15 @@ void pcf50606_reset_timeout(void)
101void GPI0(void) __attribute__ ((interrupt_handler, section(".text"))); 108void GPI0(void) __attribute__ ((interrupt_handler, section(".text")));
102void GPI0(void) 109void GPI0(void)
103{ 110{
104 unsigned char read[3]; /* 0 = INT1, 1 = INT2, 2 = INT3 */ 111 unsigned char data[3]; /* 0 = INT1, 1 = INT2, 2 = INT3 */
112
113 /* Clear pending GPI0 interrupts */
114 or_l(0x00000100, &GPIO_INT_CLEAR);
105 115
106 /* clear pending interrupts from pcf50606 */ 116 /* clear pending interrupts from pcf50606 */
107 pcf50606_read_multiple(0x02, read, 3); 117 pcf50606_read_multiple(0x02, data, 3);
108 118
109 if (read[0] & 0x04) 119 if (data[0] & 0x04)
110 { 120 {
111 /* ONKEY1S */ 121 /* ONKEY1S */
112 if (GPIO_READ & 0x02000000) 122 if (GPIO_READ & 0x02000000)
@@ -115,6 +125,12 @@ void GPI0(void)
115 pcf50606_reset_timeout(); /* remote ONKEY */ 125 pcf50606_reset_timeout(); /* remote ONKEY */
116 } 126 }
117 127
118 /* Clear pending GPI0 interrupts */ 128 if (data[2] & 0x06)
119 or_l(0x00000100, &GPIO_INT_CLEAR); 129 {
130 /* ACDINS/ACDREM */
131 /* Check if adc_scan should actually scan main buttons or not -
132 bias towards "yes" out of paranoia. */
133 adc_enable_button_scan((data[2] & 0x02) != 0 ||
134 (pcf50606_read(0x33) & 0x01) != 0);
135 }
120} 136}