diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2014-02-04 00:23:35 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2014-02-10 23:14:25 +0100 |
commit | 0324bf59a8810cadf35d67f71f5ee409834ec4ee (patch) | |
tree | a636cb9b3ab6cfd6c0d3c54eb5659294799291a2 /firmware/target/arm/imx233/button-lradc-imx233.c | |
parent | 0e0c610df0d3d4044d0b21ddc1752a5dacd7f86e (diff) | |
download | rockbox-0324bf59a8810cadf35d67f71f5ee409834ec4ee.tar.gz rockbox-0324bf59a8810cadf35d67f71f5ee409834ec4ee.zip |
imx233: make button-lradc drive able to handle VDDIO derived values
In most devices, the button ladder is not actually derived from VDDIO but
from a constant voltage source, making it very easy to read it. However on
some devices like ther ZEN X-Fi Style, the ladder is wired to VDDIO we
can be changed so it's crucial that the button driver correctly scales the
values wrt VDDIO.
Change-Id: Ifc11abe2838fa7d16d0d60ecd96964a8dc5ea6d7
Diffstat (limited to 'firmware/target/arm/imx233/button-lradc-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/button-lradc-imx233.c | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/firmware/target/arm/imx233/button-lradc-imx233.c b/firmware/target/arm/imx233/button-lradc-imx233.c index 6bb7f9babe..141281041b 100644 --- a/firmware/target/arm/imx233/button-lradc-imx233.c +++ b/firmware/target/arm/imx233/button-lradc-imx233.c | |||
@@ -58,6 +58,10 @@ | |||
58 | /* delay's delay */ | 58 | /* delay's delay */ |
59 | #define DELAY (LRADC_DELAY_FREQ / RATE / SAMPLES) | 59 | #define DELAY (LRADC_DELAY_FREQ / RATE / SAMPLES) |
60 | 60 | ||
61 | #ifdef IMX233_BUTTON_LRADC_VDDIO | ||
62 | #define HAS_VDDIO | ||
63 | #endif | ||
64 | |||
61 | static int button_delay; | 65 | static int button_delay; |
62 | static int button_chan; | 66 | static int button_chan; |
63 | static int button_val[2]; | 67 | static int button_val[2]; |
@@ -65,9 +69,18 @@ static int button_idx; | |||
65 | static int button_mask; | 69 | static int button_mask; |
66 | static int table_size; | 70 | static int table_size; |
67 | static int raw_val; | 71 | static int raw_val; |
72 | #ifdef HAS_VDDIO | ||
73 | static int vddio_chan; | ||
74 | static int vddio_val; | ||
75 | #endif | ||
76 | static int delay_chan_mask; // trigger channel mask | ||
77 | static int irq_chan_mask; // triggered channel mask | ||
68 | 78 | ||
69 | static int button_find(int val) | 79 | static int button_find(int val) |
70 | { | 80 | { |
81 | #ifdef IMX233_BUTTON_LRADC_VDDIO | ||
82 | val = (val * IMX233_BUTTON_LRADC_VDDIO) / vddio_val; | ||
83 | #endif | ||
71 | // shortcuts | 84 | // shortcuts |
72 | struct imx233_button_lradc_mapping_t *table = imx233_button_lradc_mapping; | 85 | struct imx233_button_lradc_mapping_t *table = imx233_button_lradc_mapping; |
73 | /* FIXME use a dichotomy */ | 86 | /* FIXME use a dichotomy */ |
@@ -91,18 +104,35 @@ static int button_find(int val) | |||
91 | 104 | ||
92 | static void button_lradc_irq(int chan) | 105 | static void button_lradc_irq(int chan) |
93 | { | 106 | { |
94 | (void) chan; | 107 | /* read value, clear channel */ |
95 | /* read value, kick channel */ | 108 | #ifdef HAS_VDDIO |
96 | raw_val = imx233_lradc_read_channel(button_chan) / SAMPLES; | 109 | if(chan == vddio_chan) |
97 | imx233_lradc_clear_channel(button_chan); | 110 | { |
98 | imx233_lradc_setup_channel(button_chan, true, true, SAMPLES - 1, LRADC_SRC(CHAN)); | 111 | vddio_val = imx233_lradc_read_channel(vddio_chan) / SAMPLES; |
99 | imx233_lradc_setup_delay(button_delay, 1 << button_chan, 0, SAMPLES - 1, DELAY); | 112 | vddio_val *= 2; /* VDDIO channel has internal divider */ |
100 | imx233_lradc_kick_delay(button_delay); | 113 | imx233_lradc_clear_channel(vddio_chan); |
101 | /* compute mask, compare to previous one */ | 114 | imx233_lradc_setup_channel(vddio_chan, true, true, SAMPLES - 1, LRADC_SRC_VDDIO); |
102 | button_val[button_idx] = button_find(raw_val); | 115 | } |
103 | button_idx = 1 - button_idx; | 116 | #endif |
104 | if(button_val[0] == button_val[1]) | 117 | if(chan == button_chan) |
105 | button_mask = button_val[0]; | 118 | { |
119 | raw_val = imx233_lradc_read_channel(button_chan) / SAMPLES; | ||
120 | imx233_lradc_clear_channel(button_chan); | ||
121 | imx233_lradc_setup_channel(button_chan, true, true, SAMPLES - 1, LRADC_SRC(CHAN)); | ||
122 | } | ||
123 | /* record irq, trigger delay if all IRQs have been fired */ | ||
124 | irq_chan_mask |= 1 << chan; | ||
125 | if(irq_chan_mask == delay_chan_mask) | ||
126 | { | ||
127 | irq_chan_mask = 0; | ||
128 | imx233_lradc_setup_delay(button_delay, delay_chan_mask, 0, SAMPLES - 1, DELAY); | ||
129 | imx233_lradc_kick_delay(button_delay); | ||
130 | /* compute mask, compare to previous one */ | ||
131 | button_val[button_idx] = button_find(raw_val); | ||
132 | button_idx = 1 - button_idx; | ||
133 | if(button_val[0] == button_val[1]) | ||
134 | button_mask = button_val[0]; | ||
135 | } | ||
106 | } | 136 | } |
107 | 137 | ||
108 | void imx233_button_lradc_init(void) | 138 | void imx233_button_lradc_init(void) |
@@ -118,9 +148,19 @@ void imx233_button_lradc_init(void) | |||
118 | if(button_delay < 0) | 148 | if(button_delay < 0) |
119 | panicf("Cannot get delay for button-lradc"); | 149 | panicf("Cannot get delay for button-lradc"); |
120 | imx233_lradc_setup_channel(button_chan, true, true, SAMPLES - 1, LRADC_SRC(CHAN)); | 150 | imx233_lradc_setup_channel(button_chan, true, true, SAMPLES - 1, LRADC_SRC(CHAN)); |
121 | imx233_lradc_setup_delay(button_delay, 1 << button_chan, 0, SAMPLES - 1, DELAY); | ||
122 | imx233_lradc_enable_channel_irq(button_chan, true); | 151 | imx233_lradc_enable_channel_irq(button_chan, true); |
123 | imx233_lradc_set_channel_irq_callback(button_chan, button_lradc_irq); | 152 | imx233_lradc_set_channel_irq_callback(button_chan, button_lradc_irq); |
153 | delay_chan_mask = 1 << button_chan; | ||
154 | #ifdef HAS_VDDIO | ||
155 | vddio_chan = imx233_lradc_acquire_channel(LRADC_SRC_VDDIO, TIMEOUT_NOBLOCK); | ||
156 | if(vddio_chan < 0) | ||
157 | panicf("Cannot get vddio channel for button-lradc"); | ||
158 | imx233_lradc_setup_channel(vddio_chan, true, true, SAMPLES - 1, LRADC_SRC_VDDIO); | ||
159 | imx233_lradc_enable_channel_irq(vddio_chan, true); | ||
160 | imx233_lradc_set_channel_irq_callback(vddio_chan, button_lradc_irq); | ||
161 | delay_chan_mask |= 1 << vddio_chan; | ||
162 | #endif | ||
163 | imx233_lradc_setup_delay(button_delay, delay_chan_mask, 0, SAMPLES - 1, DELAY); | ||
124 | imx233_lradc_kick_delay(button_delay); | 164 | imx233_lradc_kick_delay(button_delay); |
125 | #if defined(HAS_BUTTON_HOLD) && IMX233_BUTTON_LRADC_HOLD_DET == BLH_GPIO | 165 | #if defined(HAS_BUTTON_HOLD) && IMX233_BUTTON_LRADC_HOLD_DET == BLH_GPIO |
126 | imx233_pinctrl_acquire(BLH_GPIO_BANK, BLH_GPIO_PIN, "button_lradc_hold"); | 166 | imx233_pinctrl_acquire(BLH_GPIO_BANK, BLH_GPIO_PIN, "button_lradc_hold"); |
@@ -164,3 +204,10 @@ int imx233_button_lradc_read_raw(void) | |||
164 | { | 204 | { |
165 | return raw_val; | 205 | return raw_val; |
166 | } | 206 | } |
207 | |||
208 | #ifdef HAS_VDDIO | ||
209 | int imx233_button_lradc_read_vddio(void) | ||
210 | { | ||
211 | return vddio_val; // the VDDIO channel has an internal divider | ||
212 | } | ||
213 | #endif | ||