From a9d56ac5de93611b80fa46992390428719782f79 Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Mon, 14 Nov 2011 21:05:10 +0000 Subject: imx233: use generic code for both channels and delays arbiter code git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30981 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/imx233/lradc-imx233.c | 112 +++++++++++++++++++++++------- firmware/target/arm/imx233/lradc-imx233.h | 9 +++ 2 files changed, 96 insertions(+), 25 deletions(-) (limited to 'firmware/target') diff --git a/firmware/target/arm/imx233/lradc-imx233.c b/firmware/target/arm/imx233/lradc-imx233.c index 7da58c64b3..1101e3d32d 100644 --- a/firmware/target/arm/imx233/lradc-imx233.c +++ b/firmware/target/arm/imx233/lradc-imx233.c @@ -22,13 +22,63 @@ #include "system-target.h" #include "lradc-imx233.h" -static struct semaphore free_bm_sema; -static struct mutex free_bm_mutex; -static unsigned free_bm; +struct channel_arbiter_t +{ + struct semaphore sema; + struct mutex mutex; + unsigned free_bm; + int count; +}; + +static void arbiter_init(struct channel_arbiter_t *a, unsigned count) +{ + mutex_init(&a->mutex); + semaphore_init(&a->sema, count, count); + a->free_bm = (1 << count) - 1; + a->count = count; +} + +// doesn't check in use ! +static void arbiter_reserve(struct channel_arbiter_t *a, unsigned channel) +{ + // assume semaphore has a free slot immediately + if(semaphore_wait(&a->sema, TIMEOUT_NOBLOCK) != OBJ_WAIT_SUCCEEDED) + panicf("arbiter_reserve failed on semaphore_wait !"); + mutex_lock(&a->mutex); + a->free_bm &= ~(1 << channel); + mutex_unlock(&a->mutex); +} + +static int arbiter_acquire(struct channel_arbiter_t *a, int timeout) +{ + int w = semaphore_wait(&a->sema, timeout); + if(w == OBJ_WAIT_TIMEDOUT) + return w; + mutex_lock(&a->mutex); + int chan = find_first_set_bit(a->free_bm); + if(chan >= a->count) + panicf("arbiter_acquire cannot find a free channel !"); + a->free_bm &= ~(1 << chan); + mutex_unlock(&a->mutex); + return chan; +} + +static void arbiter_release(struct channel_arbiter_t *a, int channel) +{ + mutex_lock(&a->mutex); + a->free_bm |= 1 << channel; + mutex_unlock(&a->mutex); + semaphore_release(&a->sema); +} + +/* channels */ +struct channel_arbiter_t channel_arbiter; +/* delay channels */ +struct channel_arbiter_t delay_arbiter; void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src) { - __REG_CLR(HW_LRADC_CHx(channel)) =HW_LRADC_CHx__NUM_SAMPLES_BM | HW_LRADC_CHx__ACCUMULATE; + __REG_CLR(HW_LRADC_CHx(channel)) = HW_LRADC_CHx__NUM_SAMPLES_BM | HW_LRADC_CHx__ACCUMULATE; __REG_SET(HW_LRADC_CHx(channel)) = nr_samples << HW_LRADC_CHx__NUM_SAMPLES_BP | acc << HW_LRADC_CHx__ACCUMULATE; if(div2) @@ -79,32 +129,32 @@ void imx233_lradc_clear_channel(int channel) int imx233_lradc_acquire_channel(int timeout) { - int w = semaphore_wait(&free_bm_sema, timeout); - if(w == OBJ_WAIT_TIMEDOUT) - return w; - mutex_lock(&free_bm_mutex); - int chan = find_first_set_bit(free_bm); - if(chan >= HW_LRADC_NUM_CHANNELS) - panicf("imx233_lradc_acquire_channel cannot find a free channel !"); - free_bm &= ~(1 << chan); - mutex_unlock(&free_bm_mutex); - return chan; + return arbiter_acquire(&channel_arbiter, timeout); } void imx233_lradc_release_channel(int chan) { - mutex_lock(&free_bm_mutex); - free_bm |= 1 << chan; - mutex_unlock(&free_bm_mutex); - semaphore_release(&free_bm_sema); + return arbiter_release(&channel_arbiter, chan); } void imx233_lradc_reserve_channel(int channel) { - semaphore_wait(&free_bm_sema, TIMEOUT_NOBLOCK); - mutex_lock(&free_bm_mutex); - free_bm &= ~(1 << channel); - mutex_unlock(&free_bm_mutex); + return arbiter_reserve(&channel_arbiter, channel); +} + +int imx233_lradc_acquire_delay(int timeout) +{ + return arbiter_acquire(&delay_arbiter, timeout); +} + +void imx233_lradc_release_delay(int chan) +{ + return arbiter_release(&delay_arbiter, chan); +} + +void imx233_lradc_reserve_delay(int channel) +{ + return arbiter_reserve(&delay_arbiter, channel); } int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) @@ -127,11 +177,23 @@ int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan) return (diff * 1012) / 4000; } +void imx233_lradc_setup_battery_conversion(bool automatic, int scale_factor) +{ + __REG_CLR(HW_LRADC_CONVERSION) = HW_LRADC_CONVERSION__AUTOMATIC | + HW_LRADC_CONVERSION__SCALE_FACTOR_BM; + __REG_SET(HW_LRADC_CONVERSION) = scale_factor | + automatic ? HW_LRADC_CONVERSION__AUTOMATIC : 0; +} + +int imx233_lradc_read_battery_voltage(void) +{ + return __XTRACT(HW_LRADC_CONVERSION, SCALED_BATT_VOLTAGE); +} + void imx233_lradc_init(void) { - mutex_init(&free_bm_mutex); - semaphore_init(&free_bm_sema, HW_LRADC_NUM_CHANNELS, HW_LRADC_NUM_CHANNELS); - free_bm = (1 << HW_LRADC_NUM_CHANNELS) - 1; + arbiter_init(&channel_arbiter, HW_LRADC_NUM_CHANNELS); + arbiter_init(&delay_arbiter, HW_LRADC_NUM_DELAYS); // enable block imx233_reset_block(&HW_LRADC_CTRL0); // disable ground ref diff --git a/firmware/target/arm/imx233/lradc-imx233.h b/firmware/target/arm/imx233/lradc-imx233.h index a72916054a..fb0085fc74 100644 --- a/firmware/target/arm/imx233/lradc-imx233.h +++ b/firmware/target/arm/imx233/lradc-imx233.h @@ -121,8 +121,17 @@ void imx233_lradc_release_channel(int chan); // doesn't check that channel is in use! void imx233_lradc_reserve_channel(int channel); +int imx233_lradc_acquire_delay(int timeout); +// doesn't check that delay channel is in use! +void imx233_lradc_reserve_delay(int dchannel); +void imx233_lradc_release_delay(int dchan); + /* enable sensing and return temperature in kelvin, * channels must already be configured as nmos and pmos */ int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan); +void imx233_lradc_setup_battery_conversion(bool automatic, int scale_factor); +// read scaled voltage, only available after proper setup +int imx233_lradc_read_battery_voltage(void); + #endif /* __lradc_imx233__ */ -- cgit v1.2.3