forked from len0rd/rockbox
imx233: make button-lradc drive able to handle VDDIO derived values
In most devices, the button ladder is not actually derived from VDDIO but from a constant voltage source, making it very easy to read it. However on some devices like ther ZEN X-Fi Style, the ladder is wired to VDDIO we can be changed so it's crucial that the button driver correctly scales the values wrt VDDIO. Change-Id: Ifc11abe2838fa7d16d0d60ecd96964a8dc5ea6d7
This commit is contained in:
parent
0e0c610df0
commit
0324bf59a8
4 changed files with 93 additions and 13 deletions
|
@ -58,6 +58,10 @@
|
||||||
/* delay's delay */
|
/* delay's delay */
|
||||||
#define DELAY (LRADC_DELAY_FREQ / RATE / SAMPLES)
|
#define DELAY (LRADC_DELAY_FREQ / RATE / SAMPLES)
|
||||||
|
|
||||||
|
#ifdef IMX233_BUTTON_LRADC_VDDIO
|
||||||
|
#define HAS_VDDIO
|
||||||
|
#endif
|
||||||
|
|
||||||
static int button_delay;
|
static int button_delay;
|
||||||
static int button_chan;
|
static int button_chan;
|
||||||
static int button_val[2];
|
static int button_val[2];
|
||||||
|
@ -65,9 +69,18 @@ static int button_idx;
|
||||||
static int button_mask;
|
static int button_mask;
|
||||||
static int table_size;
|
static int table_size;
|
||||||
static int raw_val;
|
static int raw_val;
|
||||||
|
#ifdef HAS_VDDIO
|
||||||
|
static int vddio_chan;
|
||||||
|
static int vddio_val;
|
||||||
|
#endif
|
||||||
|
static int delay_chan_mask; // trigger channel mask
|
||||||
|
static int irq_chan_mask; // triggered channel mask
|
||||||
|
|
||||||
static int button_find(int val)
|
static int button_find(int val)
|
||||||
{
|
{
|
||||||
|
#ifdef IMX233_BUTTON_LRADC_VDDIO
|
||||||
|
val = (val * IMX233_BUTTON_LRADC_VDDIO) / vddio_val;
|
||||||
|
#endif
|
||||||
// shortcuts
|
// shortcuts
|
||||||
struct imx233_button_lradc_mapping_t *table = imx233_button_lradc_mapping;
|
struct imx233_button_lradc_mapping_t *table = imx233_button_lradc_mapping;
|
||||||
/* FIXME use a dichotomy */
|
/* FIXME use a dichotomy */
|
||||||
|
@ -91,18 +104,35 @@ static int button_find(int val)
|
||||||
|
|
||||||
static void button_lradc_irq(int chan)
|
static void button_lradc_irq(int chan)
|
||||||
{
|
{
|
||||||
(void) chan;
|
/* read value, clear channel */
|
||||||
/* read value, kick channel */
|
#ifdef HAS_VDDIO
|
||||||
raw_val = imx233_lradc_read_channel(button_chan) / SAMPLES;
|
if(chan == vddio_chan)
|
||||||
imx233_lradc_clear_channel(button_chan);
|
{
|
||||||
imx233_lradc_setup_channel(button_chan, true, true, SAMPLES - 1, LRADC_SRC(CHAN));
|
vddio_val = imx233_lradc_read_channel(vddio_chan) / SAMPLES;
|
||||||
imx233_lradc_setup_delay(button_delay, 1 << button_chan, 0, SAMPLES - 1, DELAY);
|
vddio_val *= 2; /* VDDIO channel has internal divider */
|
||||||
imx233_lradc_kick_delay(button_delay);
|
imx233_lradc_clear_channel(vddio_chan);
|
||||||
/* compute mask, compare to previous one */
|
imx233_lradc_setup_channel(vddio_chan, true, true, SAMPLES - 1, LRADC_SRC_VDDIO);
|
||||||
button_val[button_idx] = button_find(raw_val);
|
}
|
||||||
button_idx = 1 - button_idx;
|
#endif
|
||||||
if(button_val[0] == button_val[1])
|
if(chan == button_chan)
|
||||||
button_mask = button_val[0];
|
{
|
||||||
|
raw_val = imx233_lradc_read_channel(button_chan) / SAMPLES;
|
||||||
|
imx233_lradc_clear_channel(button_chan);
|
||||||
|
imx233_lradc_setup_channel(button_chan, true, true, SAMPLES - 1, LRADC_SRC(CHAN));
|
||||||
|
}
|
||||||
|
/* record irq, trigger delay if all IRQs have been fired */
|
||||||
|
irq_chan_mask |= 1 << chan;
|
||||||
|
if(irq_chan_mask == delay_chan_mask)
|
||||||
|
{
|
||||||
|
irq_chan_mask = 0;
|
||||||
|
imx233_lradc_setup_delay(button_delay, delay_chan_mask, 0, SAMPLES - 1, DELAY);
|
||||||
|
imx233_lradc_kick_delay(button_delay);
|
||||||
|
/* compute mask, compare to previous one */
|
||||||
|
button_val[button_idx] = button_find(raw_val);
|
||||||
|
button_idx = 1 - button_idx;
|
||||||
|
if(button_val[0] == button_val[1])
|
||||||
|
button_mask = button_val[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void imx233_button_lradc_init(void)
|
void imx233_button_lradc_init(void)
|
||||||
|
@ -118,9 +148,19 @@ void imx233_button_lradc_init(void)
|
||||||
if(button_delay < 0)
|
if(button_delay < 0)
|
||||||
panicf("Cannot get delay for button-lradc");
|
panicf("Cannot get delay for button-lradc");
|
||||||
imx233_lradc_setup_channel(button_chan, true, true, SAMPLES - 1, LRADC_SRC(CHAN));
|
imx233_lradc_setup_channel(button_chan, true, true, SAMPLES - 1, LRADC_SRC(CHAN));
|
||||||
imx233_lradc_setup_delay(button_delay, 1 << button_chan, 0, SAMPLES - 1, DELAY);
|
|
||||||
imx233_lradc_enable_channel_irq(button_chan, true);
|
imx233_lradc_enable_channel_irq(button_chan, true);
|
||||||
imx233_lradc_set_channel_irq_callback(button_chan, button_lradc_irq);
|
imx233_lradc_set_channel_irq_callback(button_chan, button_lradc_irq);
|
||||||
|
delay_chan_mask = 1 << button_chan;
|
||||||
|
#ifdef HAS_VDDIO
|
||||||
|
vddio_chan = imx233_lradc_acquire_channel(LRADC_SRC_VDDIO, TIMEOUT_NOBLOCK);
|
||||||
|
if(vddio_chan < 0)
|
||||||
|
panicf("Cannot get vddio channel for button-lradc");
|
||||||
|
imx233_lradc_setup_channel(vddio_chan, true, true, SAMPLES - 1, LRADC_SRC_VDDIO);
|
||||||
|
imx233_lradc_enable_channel_irq(vddio_chan, true);
|
||||||
|
imx233_lradc_set_channel_irq_callback(vddio_chan, button_lradc_irq);
|
||||||
|
delay_chan_mask |= 1 << vddio_chan;
|
||||||
|
#endif
|
||||||
|
imx233_lradc_setup_delay(button_delay, delay_chan_mask, 0, SAMPLES - 1, DELAY);
|
||||||
imx233_lradc_kick_delay(button_delay);
|
imx233_lradc_kick_delay(button_delay);
|
||||||
#if defined(HAS_BUTTON_HOLD) && IMX233_BUTTON_LRADC_HOLD_DET == BLH_GPIO
|
#if defined(HAS_BUTTON_HOLD) && IMX233_BUTTON_LRADC_HOLD_DET == BLH_GPIO
|
||||||
imx233_pinctrl_acquire(BLH_GPIO_BANK, BLH_GPIO_PIN, "button_lradc_hold");
|
imx233_pinctrl_acquire(BLH_GPIO_BANK, BLH_GPIO_PIN, "button_lradc_hold");
|
||||||
|
@ -164,3 +204,10 @@ int imx233_button_lradc_read_raw(void)
|
||||||
{
|
{
|
||||||
return raw_val;
|
return raw_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAS_VDDIO
|
||||||
|
int imx233_button_lradc_read_vddio(void)
|
||||||
|
{
|
||||||
|
return vddio_val; // the VDDIO channel has an internal divider
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -30,7 +30,19 @@
|
||||||
* - imx233_button_lradc_mapping: target-defined table of adc values and mapping
|
* - imx233_button_lradc_mapping: target-defined table of adc values and mapping
|
||||||
* - IMX233_BUTTON_LRADC_CHANNEL: lradc channel to use
|
* - IMX233_BUTTON_LRADC_CHANNEL: lradc channel to use
|
||||||
* - IMX233_BUTTON_LRADC_HOLD_DET: define hold detection method (ignored if !HAS_BUTTON_HOLD)
|
* - IMX233_BUTTON_LRADC_HOLD_DET: define hold detection method (ignored if !HAS_BUTTON_HOLD)
|
||||||
|
* - IMX233_BUTTON_LRADC_MODE: define the button lradc mode
|
||||||
*
|
*
|
||||||
|
* The LRADC code supports two modes of operations: VDDIO relative or absolute.
|
||||||
|
* In the (default) absolute value mode, the LRADC channel is sampled and its value
|
||||||
|
* is compared to the one in the imx233_button_lradc_mapping table. This is
|
||||||
|
* appropriate when the resistor ladder is derived from a fixed voltage.
|
||||||
|
* In the VDDIO relative mode, the values in imx233_button_lradc_mapping are
|
||||||
|
* the values for a specific value of VDDIO which is given by
|
||||||
|
* IMX233_BUTTON_LRADC_VDDIO. In this mode, the code will also sample VDDIO
|
||||||
|
* and do the following comparison:
|
||||||
|
* lradc_value <=? imx233_button_lradc_mapping[i] * vddio_ref / vddio_value
|
||||||
|
* where vddio_ref is IMX233_BUTTON_LRADC_VDDIO.
|
||||||
|
*
|
||||||
* The available values of IMX233_BUTTON_LRADC_HOLD are:
|
* The available values of IMX233_BUTTON_LRADC_HOLD are:
|
||||||
* - BLH_ADC: detect hold using adc
|
* - BLH_ADC: detect hold using adc
|
||||||
* - BLH_EXT: target button driver implements imx233_button_lradc_hold() using
|
* - BLH_EXT: target button driver implements imx233_button_lradc_hold() using
|
||||||
|
@ -40,6 +52,10 @@
|
||||||
* + BLH_GPIO_PIN: pin in bank
|
* + BLH_GPIO_PIN: pin in bank
|
||||||
* + BLH_GPIO_INVERTED: define if inverted, default is active high
|
* + BLH_GPIO_INVERTED: define if inverted, default is active high
|
||||||
* + BLH_GPIO_PULLUP: define if pins needs pullup
|
* + BLH_GPIO_PULLUP: define if pins needs pullup
|
||||||
|
*
|
||||||
|
* WARNING
|
||||||
|
* There must always be entry in imx233_button_lradc_mapping whose value is the steady
|
||||||
|
* value of the channel when no button is pressed, and which maps to no button (.btn = 0)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* hold detect method */
|
/* hold detect method */
|
||||||
|
@ -74,5 +90,8 @@ int imx233_button_lradc_read(int others);
|
||||||
bool imx233_button_lradc_hold(void);
|
bool imx233_button_lradc_hold(void);
|
||||||
#endif
|
#endif
|
||||||
int imx233_button_lradc_read_raw(void); // return raw adc value
|
int imx233_button_lradc_read_raw(void); // return raw adc value
|
||||||
|
#ifdef IMX233_BUTTON_LRADC_VDDIO
|
||||||
|
int imx233_button_lradc_read_vddio(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __button_lradc_imx233__ */
|
#endif /* __button_lradc_imx233__ */
|
||||||
|
|
|
@ -25,11 +25,22 @@
|
||||||
|
|
||||||
bool button_debug_screen(void);
|
bool button_debug_screen(void);
|
||||||
|
|
||||||
|
/* HOLD button */
|
||||||
#if !defined(CREATIVE_ZENXFISTYLE)
|
#if !defined(CREATIVE_ZENXFISTYLE)
|
||||||
#define HAS_BUTTON_HOLD
|
#define HAS_BUTTON_HOLD
|
||||||
#define IMX233_BUTTON_LRADC_HOLD_DET BLH_ADC
|
#define IMX233_BUTTON_LRADC_HOLD_DET BLH_ADC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* VDDIO value */
|
||||||
|
#if defined(CREATIVE_ZENXFISTYLE)
|
||||||
|
#define IMX233_BUTTON_LRADC_VDDIO 3660
|
||||||
|
#elif defined(CREATIVE_ZEN)
|
||||||
|
#define IMX233_BUTTON_LRADC_VDDIO 3480
|
||||||
|
#elif defined(CREATIVE_ZENXFI)
|
||||||
|
#define IMX233_BUTTON_LRADC_VDDIO 3500
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* LRADC channel */
|
||||||
#if defined(CREATIVE_ZENXFISTYLE)
|
#if defined(CREATIVE_ZENXFISTYLE)
|
||||||
#define IMX233_BUTTON_LRADC_CHANNEL 2
|
#define IMX233_BUTTON_LRADC_CHANNEL 2
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -65,6 +65,9 @@
|
||||||
/* frequency of the delay counter */
|
/* frequency of the delay counter */
|
||||||
#define LRADC_DELAY_FREQ 2000
|
#define LRADC_DELAY_FREQ 2000
|
||||||
|
|
||||||
|
/* maximum value of a sample (without accumulation), defines the precision */
|
||||||
|
#define LRADC_MAX_VALUE 4096
|
||||||
|
|
||||||
typedef void (*lradc_irq_fn_t)(int chan);
|
typedef void (*lradc_irq_fn_t)(int chan);
|
||||||
|
|
||||||
void imx233_lradc_init(void);
|
void imx233_lradc_init(void);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue