diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2012-03-17 17:39:27 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2012-03-17 17:42:49 +0100 |
commit | e5b5041583e389e6866b210683a09c97a10077d3 (patch) | |
tree | 256bc4b1f0fbccce21295afbda907988be78f3bb /firmware/target/arm/imx233/lradc-imx233.c | |
parent | 7676dae3e0f279d4b193f1c9abf8977c8f52e5d2 (diff) | |
download | rockbox-e5b5041583e389e6866b210683a09c97a10077d3.tar.gz rockbox-e5b5041583e389e6866b210683a09c97a10077d3.zip |
imx233/fuze+: rework lradc/adc code, add external temperature sensing(battery)
Rework code to be more useful:
- move battery channel init to lradc
- always init lradc from system (previously from adc)
- don't reserve channels for vddio, nmos or pmos
- implement external temperature sensing using current source
- use this for battery sensing on the Fuze+ (calibration needed)
Change-Id: I5f9a24b9243db7d1e6bdb16b84bc891e61d0c318
Diffstat (limited to 'firmware/target/arm/imx233/lradc-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/lradc-imx233.c | 75 |
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 @@ | |||
27 | static struct channel_arbiter_t channel_arbiter; | 27 | static struct channel_arbiter_t channel_arbiter; |
28 | /* delay channels */ | 28 | /* delay channels */ |
29 | static struct channel_arbiter_t delay_arbiter; | 29 | static struct channel_arbiter_t delay_arbiter; |
30 | /* battery is very special, dedicate a channel and a delay to it */ | ||
31 | static int battery_chan; | ||
32 | static int battery_delay_chan; | ||
30 | 33 | ||
31 | void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src) | 34 | void 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 | ||
112 | int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) | 115 | int 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 */ | ||
138 | static 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 | |||
157 | int 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 | |||
132 | void imx233_lradc_setup_battery_conversion(bool automatic, unsigned long scale_factor) | 191 | void 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 | } |