diff options
Diffstat (limited to 'firmware/target/arm/imx233/lradc-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/lradc-imx233.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/firmware/target/arm/imx233/lradc-imx233.c b/firmware/target/arm/imx233/lradc-imx233.c index 4fe05f36f7..d95a002663 100644 --- a/firmware/target/arm/imx233/lradc-imx233.c +++ b/firmware/target/arm/imx233/lradc-imx233.c | |||
@@ -25,7 +25,11 @@ | |||
25 | #include "stdlib.h" | 25 | #include "stdlib.h" |
26 | 26 | ||
27 | /* channels */ | 27 | /* channels */ |
28 | #if IMX233_SUBTARGET >= 3700 | ||
28 | static struct channel_arbiter_t channel_arbiter; | 29 | static struct channel_arbiter_t channel_arbiter; |
30 | #else | ||
31 | static struct semaphore channel_sema[LRADC_NUM_CHANNELS]; | ||
32 | #endif | ||
29 | /* delay channels */ | 33 | /* delay channels */ |
30 | static struct channel_arbiter_t delay_arbiter; | 34 | static struct channel_arbiter_t delay_arbiter; |
31 | /* battery is very special, dedicate a channel and a delay to it */ | 35 | /* battery is very special, dedicate a channel and a delay to it */ |
@@ -44,6 +48,7 @@ void INT_LRADC_CH(int chan) | |||
44 | { | 48 | { |
45 | if(irq_cb[chan]) | 49 | if(irq_cb[chan]) |
46 | irq_cb[chan](chan); | 50 | irq_cb[chan](chan); |
51 | imx233_lradc_clear_channel_irq(chan); | ||
47 | } | 52 | } |
48 | 53 | ||
49 | define_cb(0) | 54 | define_cb(0) |
@@ -58,6 +63,7 @@ define_cb(7) | |||
58 | void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb) | 63 | void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb) |
59 | { | 64 | { |
60 | irq_cb[channel] = cb; | 65 | irq_cb[channel] = cb; |
66 | imx233_icoll_enable_interrupt(INT_SRC_LRADC_CHx(channel), cb != NULL); | ||
61 | } | 67 | } |
62 | 68 | ||
63 | void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src) | 69 | void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src) |
@@ -68,8 +74,23 @@ void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples | |||
68 | BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << channel); | 74 | BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << channel); |
69 | else | 75 | else |
70 | BF_CLRV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << channel); | 76 | BF_CLRV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << channel); |
77 | #if IMX233_SUBTARGET >= 3700 | ||
71 | HW_LRADC_CTRL4_CLR = BM_LRADC_CTRL4_LRADCxSELECT(channel); | 78 | HW_LRADC_CTRL4_CLR = BM_LRADC_CTRL4_LRADCxSELECT(channel); |
72 | HW_LRADC_CTRL4_SET = src << BP_LRADC_CTRL4_LRADCxSELECT(channel); | 79 | HW_LRADC_CTRL4_SET = src << BP_LRADC_CTRL4_LRADCxSELECT(channel); |
80 | #else | ||
81 | if(channel == 6) | ||
82 | { | ||
83 | BF_CLR(LRADC_CTRL2, LRADC6SELECT); | ||
84 | BF_SETV(LRADC_CTRL2, LRADC6SELECT, src); | ||
85 | } | ||
86 | else if(channel == 7) | ||
87 | { | ||
88 | BF_CLR(LRADC_CTRL2, LRADC7SELECT); | ||
89 | BF_SETV(LRADC_CTRL2, LRADC7SELECT, src); | ||
90 | } | ||
91 | else if(channel != src) | ||
92 | panicf("cannot configure channel %d for source %d", channel, src); | ||
93 | #endif | ||
73 | } | 94 | } |
74 | 95 | ||
75 | void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays, | 96 | void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays, |
@@ -126,8 +147,10 @@ void imx233_lradc_clear_channel(int channel) | |||
126 | BF_CLRn(LRADC_CHn, channel, VALUE); | 147 | BF_CLRn(LRADC_CHn, channel, VALUE); |
127 | } | 148 | } |
128 | 149 | ||
129 | int imx233_lradc_acquire_channel(int timeout) | 150 | #if IMX233_SUBTARGET >= 3700 |
151 | int imx233_lradc_acquire_channel(int src, int timeout) | ||
130 | { | 152 | { |
153 | (void) src; | ||
131 | return arbiter_acquire(&channel_arbiter, timeout); | 154 | return arbiter_acquire(&channel_arbiter, timeout); |
132 | } | 155 | } |
133 | 156 | ||
@@ -140,6 +163,26 @@ void imx233_lradc_reserve_channel(int channel) | |||
140 | { | 163 | { |
141 | return arbiter_reserve(&channel_arbiter, channel); | 164 | return arbiter_reserve(&channel_arbiter, channel); |
142 | } | 165 | } |
166 | #else | ||
167 | int imx233_lradc_acquire_channel(int src, int timeout) | ||
168 | { | ||
169 | int channel = src <= LRADC_SRC_BATTERY ? src : 6; | ||
170 | if(semaphore_wait(&channel_sema[channel], timeout) == OBJ_WAIT_TIMEDOUT) | ||
171 | return -1; | ||
172 | return channel; | ||
173 | } | ||
174 | |||
175 | void imx233_lradc_release_channel(int chan) | ||
176 | { | ||
177 | semaphore_release(&channel_sema[chan]); | ||
178 | } | ||
179 | |||
180 | void imx233_lradc_reserve_channel(int channel) | ||
181 | { | ||
182 | if(imx233_lradc_acquire_channel(channel, 0) == -1) | ||
183 | panicf("Cannot reserve a used channel"); | ||
184 | } | ||
185 | #endif | ||
143 | 186 | ||
144 | int imx233_lradc_acquire_delay(int timeout) | 187 | int imx233_lradc_acquire_delay(int timeout) |
145 | { | 188 | { |
@@ -156,6 +199,7 @@ void imx233_lradc_reserve_delay(int channel) | |||
156 | return arbiter_reserve(&delay_arbiter, channel); | 199 | return arbiter_reserve(&delay_arbiter, channel); |
157 | } | 200 | } |
158 | 201 | ||
202 | #if IMX233_SUBTARGET >= 3700 | ||
159 | int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) | 203 | int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) |
160 | { | 204 | { |
161 | imx233_lradc_setup_channel(nmos_chan, false, false, 0, LRADC_SRC_NMOS_THIN); | 205 | imx233_lradc_setup_channel(nmos_chan, false, false, 0, LRADC_SRC_NMOS_THIN); |
@@ -177,6 +221,7 @@ int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) | |||
177 | // return diff * 1.012 / 4 | 221 | // return diff * 1.012 / 4 |
178 | return (diff * 1012) / 4000; | 222 | return (diff * 1012) / 4000; |
179 | } | 223 | } |
224 | #endif | ||
180 | 225 | ||
181 | /* set to 0 to disable current source */ | 226 | /* set to 0 to disable current source */ |
182 | static void imx233_lradc_set_temp_isrc(int sensor, int value) | 227 | static void imx233_lradc_set_temp_isrc(int sensor, int value) |
@@ -278,7 +323,15 @@ bool imx233_lradc_read_touch_detect(void) | |||
278 | 323 | ||
279 | void imx233_lradc_init(void) | 324 | void imx233_lradc_init(void) |
280 | { | 325 | { |
326 | /* On STMP3700+, any channel can measure any source but on STMP3600 only | ||
327 | * channels 6 and 7 can measure all sources. Channel 7 being dedicated to | ||
328 | * battery, only channel 6 is available for free use */ | ||
329 | #if IMX233_SUBTARGET >= 3700 | ||
281 | arbiter_init(&channel_arbiter, LRADC_NUM_CHANNELS); | 330 | arbiter_init(&channel_arbiter, LRADC_NUM_CHANNELS); |
331 | #else | ||
332 | for(int i = 0; i < LRADC_NUM_CHANNELS; i++) | ||
333 | semaphore_init(&channel_sema[i], 1, 1); | ||
334 | #endif | ||
282 | arbiter_init(&delay_arbiter, LRADC_NUM_DELAYS); | 335 | arbiter_init(&delay_arbiter, LRADC_NUM_DELAYS); |
283 | // enable block | 336 | // enable block |
284 | imx233_reset_block(&HW_LRADC_CTRL0); | 337 | imx233_reset_block(&HW_LRADC_CTRL0); |
@@ -287,7 +340,9 @@ void imx233_lradc_init(void) | |||
287 | // disable temperature sensors | 340 | // disable temperature sensors |
288 | BF_CLR(LRADC_CTRL2, TEMP_SENSOR_IENABLE0); | 341 | BF_CLR(LRADC_CTRL2, TEMP_SENSOR_IENABLE0); |
289 | BF_CLR(LRADC_CTRL2, TEMP_SENSOR_IENABLE1); | 342 | BF_CLR(LRADC_CTRL2, TEMP_SENSOR_IENABLE1); |
343 | #if IMX233_SUBTARGET >= 3700 | ||
290 | BF_SET(LRADC_CTRL2, TEMPSENSE_PWD); | 344 | BF_SET(LRADC_CTRL2, TEMPSENSE_PWD); |
345 | #endif | ||
291 | // set frequency | 346 | // set frequency |
292 | BF_CLR(LRADC_CTRL3, CYCLE_TIME); | 347 | BF_CLR(LRADC_CTRL3, CYCLE_TIME); |
293 | BF_SETV(LRADC_CTRL3, CYCLE_TIME_V, 6MHZ); | 348 | BF_SETV(LRADC_CTRL3, CYCLE_TIME_V, 6MHZ); |