diff options
-rw-r--r-- | firmware/target/arm/imx233/adc-imx233.c | 19 | ||||
-rw-r--r-- | firmware/target/arm/imx233/adc-imx233.h | 2 | ||||
-rw-r--r-- | firmware/target/arm/imx233/lradc-imx233.c | 57 | ||||
-rw-r--r-- | firmware/target/arm/imx233/lradc-imx233.h | 11 | ||||
-rw-r--r-- | firmware/target/arm/imx233/touchscreen-imx233.c | 2 |
5 files changed, 83 insertions, 8 deletions
diff --git a/firmware/target/arm/imx233/adc-imx233.c b/firmware/target/arm/imx233/adc-imx233.c index 9b5af82d5d..a6025cfde9 100644 --- a/firmware/target/arm/imx233/adc-imx233.c +++ b/firmware/target/arm/imx233/adc-imx233.c | |||
@@ -20,6 +20,7 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "adc-imx233.h" | 22 | #include "adc-imx233.h" |
23 | #include "power-imx233.h" | ||
23 | 24 | ||
24 | void adc_init(void) | 25 | void adc_init(void) |
25 | { | 26 | { |
@@ -35,7 +36,7 @@ static short adc_read_physical_ex(int virt) | |||
35 | 36 | ||
36 | static short adc_read_physical(int src, bool div2) | 37 | static short adc_read_physical(int src, bool div2) |
37 | { | 38 | { |
38 | int virt = imx233_lradc_acquire_channel(TIMEOUT_BLOCK); | 39 | int virt = imx233_lradc_acquire_channel(src, TIMEOUT_BLOCK); |
39 | // divide by two for wider ranger | 40 | // divide by two for wider ranger |
40 | imx233_lradc_setup_channel(virt, div2, false, 0, src); | 41 | imx233_lradc_setup_channel(virt, div2, false, 0, src); |
41 | int val = adc_read_physical_ex(virt); | 42 | int val = adc_read_physical_ex(virt); |
@@ -52,14 +53,17 @@ static short adc_read_virtual(int c) | |||
52 | case IMX233_ADC_VDDIO: | 53 | case IMX233_ADC_VDDIO: |
53 | /* VddIO pin has a builtin 2:1 divide */ | 54 | /* VddIO pin has a builtin 2:1 divide */ |
54 | return adc_read_physical(LRADC_SRC_VDDIO, false); | 55 | return adc_read_physical(LRADC_SRC_VDDIO, false); |
56 | #if IMX233_SUBTARGET >= 3700 | ||
55 | case IMX233_ADC_VDD5V: | 57 | case IMX233_ADC_VDD5V: |
56 | /* Vdd5V pin has a builtin 4:1 divide */ | 58 | /* Vdd5V pin has a builtin 4:1 divide */ |
57 | return adc_read_physical(LRADC_SRC_5V, false) * 2; | 59 | return adc_read_physical(LRADC_SRC_5V, false) * 2; |
60 | #endif | ||
58 | case IMX233_ADC_DIE_TEMP: | 61 | case IMX233_ADC_DIE_TEMP: |
59 | { | 62 | { |
63 | #if IMX233_SUBTARGET >= 3700 | ||
60 | // don't block on second channel otherwise we might deadlock ! | 64 | // don't block on second channel otherwise we might deadlock ! |
61 | int nmos_chan = imx233_lradc_acquire_channel(TIMEOUT_BLOCK); | 65 | int nmos_chan = imx233_lradc_acquire_channel(LRADC_SRC_NMOS_THIN, TIMEOUT_BLOCK); |
62 | int pmos_chan = imx233_lradc_acquire_channel(TIMEOUT_NOBLOCK); | 66 | int pmos_chan = imx233_lradc_acquire_channel(LRADC_SRC_PMOS_THIN, TIMEOUT_NOBLOCK); |
63 | int val = 0; | 67 | int val = 0; |
64 | if(pmos_chan >= 0) | 68 | if(pmos_chan >= 0) |
65 | { | 69 | { |
@@ -67,12 +71,19 @@ static short adc_read_virtual(int c) | |||
67 | imx233_lradc_release_channel(pmos_chan); | 71 | imx233_lradc_release_channel(pmos_chan); |
68 | } | 72 | } |
69 | imx233_lradc_release_channel(nmos_chan); | 73 | imx233_lradc_release_channel(nmos_chan); |
74 | #else | ||
75 | int min, max, val; | ||
76 | if(imx233_power_sense_die_temperature(&min, &max) < 0) | ||
77 | val = -1; | ||
78 | else | ||
79 | val = (max + min) / 2; | ||
80 | #endif | ||
70 | return val; | 81 | return val; |
71 | } | 82 | } |
72 | #ifdef IMX233_BATT_TEMP_SENSOR | 83 | #ifdef IMX233_BATT_TEMP_SENSOR |
73 | case IMX233_ADC_BATT_TEMP: | 84 | case IMX233_ADC_BATT_TEMP: |
74 | { | 85 | { |
75 | int virt = imx233_lradc_acquire_channel(TIMEOUT_BLOCK); | 86 | int virt = imx233_lradc_acquire_channel(IMX233_BATT_TEMP_SENSOR, TIMEOUT_BLOCK); |
76 | int val = imx233_lradc_sense_ext_temperature(virt, IMX233_BATT_TEMP_SENSOR); | 87 | int val = imx233_lradc_sense_ext_temperature(virt, IMX233_BATT_TEMP_SENSOR); |
77 | imx233_lradc_release_channel(virt); | 88 | imx233_lradc_release_channel(virt); |
78 | return val; | 89 | return val; |
diff --git a/firmware/target/arm/imx233/adc-imx233.h b/firmware/target/arm/imx233/adc-imx233.h index 09fd7eb013..f833e17be0 100644 --- a/firmware/target/arm/imx233/adc-imx233.h +++ b/firmware/target/arm/imx233/adc-imx233.h | |||
@@ -31,7 +31,9 @@ | |||
31 | #define IMX233_ADC_BATTERY -1 /* Battery voltage (mV) */ | 31 | #define IMX233_ADC_BATTERY -1 /* Battery voltage (mV) */ |
32 | #define IMX233_ADC_DIE_TEMP -2 /* Die temperature (°C) */ | 32 | #define IMX233_ADC_DIE_TEMP -2 /* Die temperature (°C) */ |
33 | #define IMX233_ADC_VDDIO -3 /* VddIO voltage (mV) */ | 33 | #define IMX233_ADC_VDDIO -3 /* VddIO voltage (mV) */ |
34 | #if IMX233_SUBTARGET >= 3700 | ||
34 | #define IMX233_ADC_VDD5V -4 /* Vdd5V voltage (mV) */ | 35 | #define IMX233_ADC_VDD5V -4 /* Vdd5V voltage (mV) */ |
36 | #endif | ||
35 | #ifdef IMX233_BATT_TEMP_SENSOR | 37 | #ifdef IMX233_BATT_TEMP_SENSOR |
36 | #define IMX233_ADC_BATT_TEMP -5 /* Battery temperature (°C) */ | 38 | #define IMX233_ADC_BATT_TEMP -5 /* Battery temperature (°C) */ |
37 | #endif | 39 | #endif |
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); |
diff --git a/firmware/target/arm/imx233/lradc-imx233.h b/firmware/target/arm/imx233/lradc-imx233.h index d1529f4266..f274db3520 100644 --- a/firmware/target/arm/imx233/lradc-imx233.h +++ b/firmware/target/arm/imx233/lradc-imx233.h | |||
@@ -55,10 +55,12 @@ | |||
55 | #define LRADC_SRC_NMOS_THICK LRADC_SRC(10) | 55 | #define LRADC_SRC_NMOS_THICK LRADC_SRC(10) |
56 | #define LRADC_SRC_PMOS_THICK LRADC_SRC(11) | 56 | #define LRADC_SRC_PMOS_THICK LRADC_SRC(11) |
57 | #define LRADC_SRC_PMOS_THICK LRADC_SRC(11) | 57 | #define LRADC_SRC_PMOS_THICK LRADC_SRC(11) |
58 | #if IMX233_SUBTARGET >= 3700 | ||
58 | #define LRADC_SRC_USB_DP LRADC_SRC(12) | 59 | #define LRADC_SRC_USB_DP LRADC_SRC(12) |
59 | #define LRADC_SRC_USB_DN LRADC_SRC(13) | 60 | #define LRADC_SRC_USB_DN LRADC_SRC(13) |
60 | #define LRADC_SRC_VBG LRADC_SRC(14) | 61 | #define LRADC_SRC_VBG LRADC_SRC(14) |
61 | #define LRADC_SRC_5V LRADC_SRC(15) | 62 | #define LRADC_SRC_5V LRADC_SRC(15) |
63 | #endif | ||
62 | 64 | ||
63 | /* frequency of the delay counter */ | 65 | /* frequency of the delay counter */ |
64 | #define LRADC_DELAY_FREQ 2000 | 66 | #define LRADC_DELAY_FREQ 2000 |
@@ -72,14 +74,17 @@ void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays, | |||
72 | void imx233_lradc_clear_channel_irq(int channel); | 74 | void imx233_lradc_clear_channel_irq(int channel); |
73 | bool imx233_lradc_read_channel_irq(int channel); | 75 | bool imx233_lradc_read_channel_irq(int channel); |
74 | void imx233_lradc_enable_channel_irq(int channel, bool enable); | 76 | void imx233_lradc_enable_channel_irq(int channel, bool enable); |
77 | /* a non-null cb will enable the icoll interrupt, a null one will disable it | ||
78 | * NOTE the channel irq is automatically cleared */ | ||
75 | void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb); | 79 | void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb); |
76 | void imx233_lradc_kick_channel(int channel); | 80 | void imx233_lradc_kick_channel(int channel); |
77 | void imx233_lradc_kick_delay(int dchan); | 81 | void imx233_lradc_kick_delay(int dchan); |
78 | void imx233_lradc_wait_channel(int channel); | 82 | void imx233_lradc_wait_channel(int channel); |
79 | int imx233_lradc_read_channel(int channel); | 83 | int imx233_lradc_read_channel(int channel); |
80 | void imx233_lradc_clear_channel(int channel); | 84 | void imx233_lradc_clear_channel(int channel); |
81 | // acquire a virtual channel, returns -1 on timeout, channel otherwise */ | 85 | /* acquire a channel, returns -1 on timeout, channel otherwise |
82 | int imx233_lradc_acquire_channel(int timeout); | 86 | * the returned channel is garanteed to be able measure source src */ |
87 | int imx233_lradc_acquire_channel(int src, int timeout); | ||
83 | void imx233_lradc_release_channel(int chan); | 88 | void imx233_lradc_release_channel(int chan); |
84 | // doesn't check that channel is in use! | 89 | // doesn't check that channel is in use! |
85 | void imx233_lradc_reserve_channel(int channel); | 90 | void imx233_lradc_reserve_channel(int channel); |
@@ -96,9 +101,11 @@ void imx233_lradc_enable_touch_detect_irq(bool enable); | |||
96 | void imx233_lradc_clear_touch_detect_irq(void); | 101 | void imx233_lradc_clear_touch_detect_irq(void); |
97 | bool imx233_lradc_read_touch_detect(void); | 102 | bool imx233_lradc_read_touch_detect(void); |
98 | 103 | ||
104 | #if IMX233_SUBTARGET >= 3700 | ||
99 | /* enable sensing and return temperature in kelvin, | 105 | /* enable sensing and return temperature in kelvin, |
100 | * channels needs not to be configured */ | 106 | * channels needs not to be configured */ |
101 | int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan); | 107 | int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan); |
108 | #endif | ||
102 | /* return *raw* external temperature, might need some transformation | 109 | /* return *raw* external temperature, might need some transformation |
103 | * channel needs not to be configured */ | 110 | * channel needs not to be configured */ |
104 | int imx233_lradc_sense_ext_temperature(int chan, int sensor); | 111 | int imx233_lradc_sense_ext_temperature(int chan, int sensor); |
diff --git a/firmware/target/arm/imx233/touchscreen-imx233.c b/firmware/target/arm/imx233/touchscreen-imx233.c index 4f35110df7..e76d7a49e3 100644 --- a/firmware/target/arm/imx233/touchscreen-imx233.c +++ b/firmware/target/arm/imx233/touchscreen-imx233.c | |||
@@ -167,7 +167,7 @@ static void touch_channel_irq(int chan) | |||
167 | 167 | ||
168 | void imx233_touchscreen_init(void) | 168 | void imx233_touchscreen_init(void) |
169 | { | 169 | { |
170 | touch_chan = imx233_lradc_acquire_channel(TIMEOUT_NOBLOCK); | 170 | touch_chan = imx233_lradc_acquire_channel(LRADC_SRC_XPLUS, TIMEOUT_NOBLOCK); |
171 | touch_delay = imx233_lradc_acquire_delay(TIMEOUT_NOBLOCK); | 171 | touch_delay = imx233_lradc_acquire_delay(TIMEOUT_NOBLOCK); |
172 | if(touch_chan < 0 || touch_delay < 0) | 172 | if(touch_chan < 0 || touch_delay < 0) |
173 | panicf("Cannot acquire channel and delays for touchscreen measurement"); | 173 | panicf("Cannot acquire channel and delays for touchscreen measurement"); |