summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/lradc-imx233.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233/lradc-imx233.c')
-rw-r--r--firmware/target/arm/imx233/lradc-imx233.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/lradc-imx233.c b/firmware/target/arm/imx233/lradc-imx233.c
index 432d1c1035..4d309b0875 100644
--- a/firmware/target/arm/imx233/lradc-imx233.c
+++ b/firmware/target/arm/imx233/lradc-imx233.c
@@ -27,6 +27,9 @@
27static struct channel_arbiter_t channel_arbiter; 27static struct channel_arbiter_t channel_arbiter;
28/* delay channels */ 28/* delay channels */
29static struct channel_arbiter_t delay_arbiter; 29static struct channel_arbiter_t delay_arbiter;
30/* battery is very special, dedicate a channel and a delay to it */
31static int battery_chan;
32static int battery_delay_chan;
30 33
31void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src) 34void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src)
32{ 35{
@@ -111,6 +114,8 @@ void imx233_lradc_reserve_delay(int channel)
111 114
112int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) 115int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan)
113{ 116{
117 imx233_lradc_setup_channel(nmos_chan, false, false, 0, HW_LRADC_CHANNEL_NMOS_THIN);
118 imx233_lradc_setup_channel(pmos_chan, false, false, 0, HW_LRADC_CHANNEL_PMOS_THIN);
114 // mux sensors 119 // mux sensors
115 __REG_CLR(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__TEMPSENSE_PWD; 120 __REG_CLR(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__TEMPSENSE_PWD;
116 imx233_lradc_clear_channel(nmos_chan); 121 imx233_lradc_clear_channel(nmos_chan);
@@ -129,6 +134,60 @@ int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan)
129 return (diff * 1012) / 4000; 134 return (diff * 1012) / 4000;
130} 135}
131 136
137/* set to 0 to disable current source */
138static void imx233_lradc_set_temp_isrc(int sensor, int value)
139{
140 if(sensor < 0 || sensor > 1)
141 panicf("imx233_lradc_set_temp_isrc: invalid sensor");
142 unsigned mask = HW_LRADC_CTRL2__TEMP_ISRCx_BM(sensor);
143 unsigned bp = HW_LRADC_CTRL2__TEMP_ISRCx_BP(sensor);
144 unsigned en = HW_LRADC_CTRL2__TEMP_SENSOR_IENABLEx(sensor);
145
146 __REG_CLR(HW_LRADC_CTRL2) = mask;
147 __REG_SET(HW_LRADC_CTRL2) = value << bp;
148 if(value != 0)
149 {
150 __REG_SET(HW_LRADC_CTRL2) = en;
151 udelay(100);
152 }
153 else
154 __REG_CLR(HW_LRADC_CTRL2) = en;
155}
156
157int imx233_lradc_sense_ext_temperature(int chan, int sensor)
158{
159#define EXT_TEMP_ACC_COUNT 5
160 /* setup channel */
161 imx233_lradc_setup_channel(chan, false, false, 0, sensor);
162 /* set current source to 300µA */
163 imx233_lradc_set_temp_isrc(sensor, HW_LRADC_CTRL2__TEMP_ISRC__300uA);
164 /* read value and accumulate */
165 int a = 0;
166 for(int i = 0; i < EXT_TEMP_ACC_COUNT; i++)
167 {
168 imx233_lradc_clear_channel(chan);
169 imx233_lradc_kick_channel(chan);
170 imx233_lradc_wait_channel(chan);
171 a += imx233_lradc_read_channel(chan);
172 }
173 /* setup channel for small accumulation */
174 /* set current source to 20µA */
175 imx233_lradc_set_temp_isrc(sensor, HW_LRADC_CTRL2__TEMP_ISRC__20uA);
176 /* read value */
177 int b = 0;
178 for(int i = 0; i < EXT_TEMP_ACC_COUNT; i++)
179 {
180 imx233_lradc_clear_channel(chan);
181 imx233_lradc_kick_channel(chan);
182 imx233_lradc_wait_channel(chan);
183 b += imx233_lradc_read_channel(chan);
184 }
185 /* disable sensor current */
186 imx233_lradc_set_temp_isrc(sensor, HW_LRADC_CTRL2__TEMP_ISRC__0uA);
187
188 return (b - a) / EXT_TEMP_ACC_COUNT;
189}
190
132void imx233_lradc_setup_battery_conversion(bool automatic, unsigned long scale_factor) 191void imx233_lradc_setup_battery_conversion(bool automatic, unsigned long scale_factor)
133{ 192{
134 __REG_CLR(HW_LRADC_CONVERSION) = HW_LRADC_CONVERSION__SCALE_FACTOR_BM; 193 __REG_CLR(HW_LRADC_CONVERSION) = HW_LRADC_CONVERSION__SCALE_FACTOR_BM;
@@ -159,4 +218,20 @@ void imx233_lradc_init(void)
159 // set frequency 218 // set frequency
160 __REG_CLR(HW_LRADC_CTRL3) = HW_LRADC_CTRL3__CYCLE_TIME_BM; 219 __REG_CLR(HW_LRADC_CTRL3) = HW_LRADC_CTRL3__CYCLE_TIME_BM;
161 __REG_SET(HW_LRADC_CTRL3) = HW_LRADC_CTRL3__CYCLE_TIME__6MHz; 220 __REG_SET(HW_LRADC_CTRL3) = HW_LRADC_CTRL3__CYCLE_TIME__6MHz;
221 // setup battery
222 battery_chan = 7;
223 imx233_lradc_reserve_channel(battery_chan);
224 /* setup them for the simplest use: no accumulation, no division*/
225 imx233_lradc_setup_channel(battery_chan, false, false, 0, HW_LRADC_CHANNEL_BATTERY);
226 /* setup delay channel for battery for automatic reading and scaling */
227 battery_delay_chan = 0;
228 imx233_lradc_reserve_delay(battery_delay_chan);
229 /* setup delay to trigger battery channel and retrigger itself.
230 * The counter runs at 2KHz so a delay of 200 will trigger 10
231 * conversions per seconds */
232 imx233_lradc_setup_delay(battery_delay_chan, 1 << battery_chan,
233 1 << battery_delay_chan, 0, 200);
234 imx233_lradc_kick_delay(battery_delay_chan);
235 /* enable automatic conversion, use Li-Ion type battery */
236 imx233_lradc_setup_battery_conversion(true, HW_LRADC_CONVERSION__SCALE_FACTOR__LI_ION);
162} 237}