1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Amaury Pouly 2011-11-14 21:05:10 +00:00
parent 9a4213c8f3
commit a9d56ac5de
2 changed files with 96 additions and 25 deletions

View file

@ -22,9 +22,59 @@
#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)
{
@ -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

View file

@ -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__ */