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
This commit is contained in:
Amaury Pouly 2012-03-17 17:39:27 +01:00
parent 7676dae3e0
commit e5b5041583
7 changed files with 135 additions and 51 deletions

View file

@ -27,6 +27,9 @@
static struct channel_arbiter_t channel_arbiter;
/* delay channels */
static struct channel_arbiter_t delay_arbiter;
/* battery is very special, dedicate a channel and a delay to it */
static int battery_chan;
static int battery_delay_chan;
void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src)
{
@ -111,6 +114,8 @@ void imx233_lradc_reserve_delay(int channel)
int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan)
{
imx233_lradc_setup_channel(nmos_chan, false, false, 0, HW_LRADC_CHANNEL_NMOS_THIN);
imx233_lradc_setup_channel(pmos_chan, false, false, 0, HW_LRADC_CHANNEL_PMOS_THIN);
// mux sensors
__REG_CLR(HW_LRADC_CTRL2) = HW_LRADC_CTRL2__TEMPSENSE_PWD;
imx233_lradc_clear_channel(nmos_chan);
@ -129,6 +134,60 @@ int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan)
return (diff * 1012) / 4000;
}
/* set to 0 to disable current source */
static void imx233_lradc_set_temp_isrc(int sensor, int value)
{
if(sensor < 0 || sensor > 1)
panicf("imx233_lradc_set_temp_isrc: invalid sensor");
unsigned mask = HW_LRADC_CTRL2__TEMP_ISRCx_BM(sensor);
unsigned bp = HW_LRADC_CTRL2__TEMP_ISRCx_BP(sensor);
unsigned en = HW_LRADC_CTRL2__TEMP_SENSOR_IENABLEx(sensor);
__REG_CLR(HW_LRADC_CTRL2) = mask;
__REG_SET(HW_LRADC_CTRL2) = value << bp;
if(value != 0)
{
__REG_SET(HW_LRADC_CTRL2) = en;
udelay(100);
}
else
__REG_CLR(HW_LRADC_CTRL2) = en;
}
int imx233_lradc_sense_ext_temperature(int chan, int sensor)
{
#define EXT_TEMP_ACC_COUNT 5
/* setup channel */
imx233_lradc_setup_channel(chan, false, false, 0, sensor);
/* set current source to 300µA */
imx233_lradc_set_temp_isrc(sensor, HW_LRADC_CTRL2__TEMP_ISRC__300uA);
/* read value and accumulate */
int a = 0;
for(int i = 0; i < EXT_TEMP_ACC_COUNT; i++)
{
imx233_lradc_clear_channel(chan);
imx233_lradc_kick_channel(chan);
imx233_lradc_wait_channel(chan);
a += imx233_lradc_read_channel(chan);
}
/* setup channel for small accumulation */
/* set current source to 20µA */
imx233_lradc_set_temp_isrc(sensor, HW_LRADC_CTRL2__TEMP_ISRC__20uA);
/* read value */
int b = 0;
for(int i = 0; i < EXT_TEMP_ACC_COUNT; i++)
{
imx233_lradc_clear_channel(chan);
imx233_lradc_kick_channel(chan);
imx233_lradc_wait_channel(chan);
b += imx233_lradc_read_channel(chan);
}
/* disable sensor current */
imx233_lradc_set_temp_isrc(sensor, HW_LRADC_CTRL2__TEMP_ISRC__0uA);
return (b - a) / EXT_TEMP_ACC_COUNT;
}
void imx233_lradc_setup_battery_conversion(bool automatic, unsigned long scale_factor)
{
__REG_CLR(HW_LRADC_CONVERSION) = HW_LRADC_CONVERSION__SCALE_FACTOR_BM;
@ -159,4 +218,20 @@ void imx233_lradc_init(void)
// set frequency
__REG_CLR(HW_LRADC_CTRL3) = HW_LRADC_CTRL3__CYCLE_TIME_BM;
__REG_SET(HW_LRADC_CTRL3) = HW_LRADC_CTRL3__CYCLE_TIME__6MHz;
// setup battery
battery_chan = 7;
imx233_lradc_reserve_channel(battery_chan);
/* setup them for the simplest use: no accumulation, no division*/
imx233_lradc_setup_channel(battery_chan, false, false, 0, HW_LRADC_CHANNEL_BATTERY);
/* setup delay channel for battery for automatic reading and scaling */
battery_delay_chan = 0;
imx233_lradc_reserve_delay(battery_delay_chan);
/* setup delay to trigger battery channel and retrigger itself.
* The counter runs at 2KHz so a delay of 200 will trigger 10
* conversions per seconds */
imx233_lradc_setup_delay(battery_delay_chan, 1 << battery_chan,
1 << battery_delay_chan, 0, 200);
imx233_lradc_kick_delay(battery_delay_chan);
/* enable automatic conversion, use Li-Ion type battery */
imx233_lradc_setup_battery_conversion(true, HW_LRADC_CONVERSION__SCALE_FACTOR__LI_ION);
}