diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2017-05-16 12:14:43 +1000 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2017-05-16 12:14:43 +1000 |
commit | 3210457764e0828056e64bbddbb9273d0384657c (patch) | |
tree | a399bc53cc448bb5db6e92d486e1c4845d12f716 /firmware/target/arm | |
parent | 5dd443c03385393de7458a03097e0b40635e6e4e (diff) | |
download | rockbox-3210457764e0828056e64bbddbb9273d0384657c.tar.gz rockbox-3210457764e0828056e64bbddbb9273d0384657c.zip |
imx233: fix touchscreen driver
One cannot call lradc_acquire in IRQ context. The solution is to reserve the
channel once at init. There is an additional complication on STMP3600 where
channel mapping is fixed.
Change-Id: Idccbac634a4d9002703e2b1d57748beb9b245cbb
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/imx233/kernel-imx233.h | 2 | ||||
-rw-r--r-- | firmware/target/arm/imx233/touchscreen-imx233.c | 36 |
2 files changed, 31 insertions, 7 deletions
diff --git a/firmware/target/arm/imx233/kernel-imx233.h b/firmware/target/arm/imx233/kernel-imx233.h index 960f3f2431..74a6f248f2 100644 --- a/firmware/target/arm/imx233/kernel-imx233.h +++ b/firmware/target/arm/imx233/kernel-imx233.h | |||
@@ -43,4 +43,4 @@ int arbiter_acquire(struct channel_arbiter_t *a, int timeout); | |||
43 | void arbiter_release(struct channel_arbiter_t *a, int channel); | 43 | void arbiter_release(struct channel_arbiter_t *a, int channel); |
44 | bool arbiter_acquired(struct channel_arbiter_t *a, int channel); | 44 | bool arbiter_acquired(struct channel_arbiter_t *a, int channel); |
45 | 45 | ||
46 | #endif /* __KERNEL_IMX233__ */ \ No newline at end of file | 46 | #endif /* __KERNEL_IMX233__ */ |
diff --git a/firmware/target/arm/imx233/touchscreen-imx233.c b/firmware/target/arm/imx233/touchscreen-imx233.c index 7a784db5a3..f98dc9b738 100644 --- a/firmware/target/arm/imx233/touchscreen-imx233.c +++ b/firmware/target/arm/imx233/touchscreen-imx233.c | |||
@@ -57,6 +57,10 @@ enum touch_state_t | |||
57 | 57 | ||
58 | static enum touch_state_t touch_state; | 58 | static enum touch_state_t touch_state; |
59 | static int touch_chan = -1; | 59 | static int touch_chan = -1; |
60 | #if IMX233_SUBTARGET < 3700 | ||
61 | /* See imx233_touchscreen_init() */ | ||
62 | static int touch_chan_xp = -1, touch_chan_yp = -1; | ||
63 | #endif | ||
60 | static int touch_delay = -1; | 64 | static int touch_delay = -1; |
61 | static int touch_x, touch_y; | 65 | static int touch_x, touch_y; |
62 | /* once a touch is confirmed, the parameters are copied to these value for | 66 | /* once a touch is confirmed, the parameters are copied to these value for |
@@ -98,11 +102,15 @@ static void pulldown_setup(bool xminus_enable, bool yminus_enable, | |||
98 | 102 | ||
99 | static void kick_measure(bool pull_x, bool pull_y, bool detect, int src) | 103 | static void kick_measure(bool pull_x, bool pull_y, bool detect, int src) |
100 | { | 104 | { |
101 | if(touch_chan >= 0) | 105 | #if IMX233_SUBTARGET < 3700 |
102 | imx233_lradc_release_channel(touch_chan); | 106 | /* Select proper channel on STMP3600 */ |
103 | touch_chan = imx233_lradc_acquire_channel(src, TIMEOUT_NOBLOCK); | 107 | if(src == LRADC_SRC_XPLUS) |
104 | if(touch_chan < 0) | 108 | touch_chan = touch_chan_xp; |
105 | panicf("touchscreen: cannot get adc channel"); | 109 | else if(src == LRADC_SRC_XPLUS) |
110 | touch_chan = touch_chan_xp; | ||
111 | else | ||
112 | panicf("Unknown channel source %d in touchscreen", src); | ||
113 | #endif | ||
106 | /* enable interrupt */ | 114 | /* enable interrupt */ |
107 | imx233_lradc_set_channel_irq_callback(touch_chan, &touch_channel_irq); | 115 | imx233_lradc_set_channel_irq_callback(touch_chan, &touch_channel_irq); |
108 | imx233_icoll_enable_interrupt(INT_SRC_LRADC_CHx(touch_chan), true); | 116 | imx233_icoll_enable_interrupt(INT_SRC_LRADC_CHx(touch_chan), true); |
@@ -192,7 +200,23 @@ void imx233_touchscreen_init(void) | |||
192 | { | 200 | { |
193 | touch_delay = imx233_lradc_acquire_delay(TIMEOUT_NOBLOCK); | 201 | touch_delay = imx233_lradc_acquire_delay(TIMEOUT_NOBLOCK); |
194 | if(touch_delay < 0) | 202 | if(touch_delay < 0) |
195 | panicf("Cannot acquire channel and delays for touchscreen measurement"); | 203 | panicf("Cannot acquire delay for touchscreen measurement"); |
204 | #if IMX233_SUBTARGET >= 3700 | ||
205 | /* On STMP3700+, any channel can measure any source so one channel is enough | ||
206 | * for all operations */ | ||
207 | touch_chan = imx233_lradc_acquire_channel(LRADC_SRC_XPLUS, TIMEOUT_NOBLOCK); | ||
208 | if(touch_chan < 0) | ||
209 | panicf("touchscreen: cannot get adc channel"); | ||
210 | #else | ||
211 | /* On STMP3600, channel mapping is fixed for touch screen so we need to reserve | ||
212 | * two channels */ | ||
213 | touch_chan_xp = imx233_lradc_acquire_channel(LRADC_SRC_XPLUS, TIMEOUT_NOBLOCK); | ||
214 | if(touch_chan_xp < 0) | ||
215 | panicf("touchscreen: cannot get adc X+ channel"); | ||
216 | touch_chan_yp = imx233_lradc_acquire_channel(LRADC_SRC_YPLUS, TIMEOUT_NOBLOCK); | ||
217 | if(touch_chan_yp < 0) | ||
218 | panicf("touchscreen: cannot get adc Y+ channel"); | ||
219 | #endif | ||
196 | imx233_touchscreen_enable(false); | 220 | imx233_touchscreen_enable(false); |
197 | } | 221 | } |
198 | 222 | ||