summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/imx233/adc-imx233.c19
-rw-r--r--firmware/target/arm/imx233/adc-imx233.h2
-rw-r--r--firmware/target/arm/imx233/lradc-imx233.c57
-rw-r--r--firmware/target/arm/imx233/lradc-imx233.h11
-rw-r--r--firmware/target/arm/imx233/touchscreen-imx233.c2
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
24void adc_init(void) 25void adc_init(void)
25{ 26{
@@ -35,7 +36,7 @@ static short adc_read_physical_ex(int virt)
35 36
36static short adc_read_physical(int src, bool div2) 37static 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
28static struct channel_arbiter_t channel_arbiter; 29static struct channel_arbiter_t channel_arbiter;
30#else
31static struct semaphore channel_sema[LRADC_NUM_CHANNELS];
32#endif
29/* delay channels */ 33/* delay channels */
30static struct channel_arbiter_t delay_arbiter; 34static 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
49define_cb(0) 54define_cb(0)
@@ -58,6 +63,7 @@ define_cb(7)
58void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb) 63void 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
63void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src) 69void 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
75void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays, 96void 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
129int imx233_lradc_acquire_channel(int timeout) 150#if IMX233_SUBTARGET >= 3700
151int 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
167int 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
175void imx233_lradc_release_channel(int chan)
176{
177 semaphore_release(&channel_sema[chan]);
178}
179
180void 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
144int imx233_lradc_acquire_delay(int timeout) 187int 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
159int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) 203int 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 */
182static void imx233_lradc_set_temp_isrc(int sensor, int value) 227static void imx233_lradc_set_temp_isrc(int sensor, int value)
@@ -278,7 +323,15 @@ bool imx233_lradc_read_touch_detect(void)
278 323
279void imx233_lradc_init(void) 324void 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,
72void imx233_lradc_clear_channel_irq(int channel); 74void imx233_lradc_clear_channel_irq(int channel);
73bool imx233_lradc_read_channel_irq(int channel); 75bool imx233_lradc_read_channel_irq(int channel);
74void imx233_lradc_enable_channel_irq(int channel, bool enable); 76void 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 */
75void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb); 79void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb);
76void imx233_lradc_kick_channel(int channel); 80void imx233_lradc_kick_channel(int channel);
77void imx233_lradc_kick_delay(int dchan); 81void imx233_lradc_kick_delay(int dchan);
78void imx233_lradc_wait_channel(int channel); 82void imx233_lradc_wait_channel(int channel);
79int imx233_lradc_read_channel(int channel); 83int imx233_lradc_read_channel(int channel);
80void imx233_lradc_clear_channel(int channel); 84void 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
82int imx233_lradc_acquire_channel(int timeout); 86 * the returned channel is garanteed to be able measure source src */
87int imx233_lradc_acquire_channel(int src, int timeout);
83void imx233_lradc_release_channel(int chan); 88void imx233_lradc_release_channel(int chan);
84// doesn't check that channel is in use! 89// doesn't check that channel is in use!
85void imx233_lradc_reserve_channel(int channel); 90void imx233_lradc_reserve_channel(int channel);
@@ -96,9 +101,11 @@ void imx233_lradc_enable_touch_detect_irq(bool enable);
96void imx233_lradc_clear_touch_detect_irq(void); 101void imx233_lradc_clear_touch_detect_irq(void);
97bool imx233_lradc_read_touch_detect(void); 102bool 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 */
101int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan); 107int 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 */
104int imx233_lradc_sense_ext_temperature(int chan, int sensor); 111int 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
168void imx233_touchscreen_init(void) 168void 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");