imx233: enhance lradc driver with touchscreen specific stuff

Change-Id: I83759a00257274c0cbde5a78306256abd2c83800
This commit is contained in:
Amaury Pouly 2012-05-19 13:36:23 +02:00
parent 01216c5ad3
commit 55e01b8de4
2 changed files with 104 additions and 5 deletions

View file

@ -22,6 +22,7 @@
#include "system-target.h"
#include "lradc-imx233.h"
#include "kernel-imx233.h"
#include "stdlib.h"
/* channels */
static struct channel_arbiter_t channel_arbiter;
@ -30,6 +31,34 @@ 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;
/* irq callbacks */
static lradc_irq_fn_t irq_cb[HW_LRADC_NUM_CHANNELS];
#define define_cb(x) \
void INT_LRADC_CH##x(void) \
{ \
INT_LRADC_CH(x); \
}
void INT_LRADC_CH(int chan)
{
if(irq_cb[chan])
irq_cb[chan](chan);
}
define_cb(0)
define_cb(1)
define_cb(2)
define_cb(3)
define_cb(4)
define_cb(5)
define_cb(6)
define_cb(7)
void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb)
{
irq_cb[channel] = cb;
}
void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src)
{
@ -54,9 +83,28 @@ void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays,
delay << HW_LRADC_DELAYx__DELAY_BP;
}
void imx233_lradc_kick_channel(int channel)
void imx233_lradc_clear_channel_irq(int channel)
{
__REG_CLR(HW_LRADC_CTRL1) = HW_LRADC_CTRL1__LRADCx_IRQ(channel);
}
bool imx233_lradc_read_channel_irq(int channel)
{
return HW_LRADC_CTRL1 & HW_LRADC_CTRL1__LRADCx_IRQ(channel);
}
void imx233_lradc_enable_channel_irq(int channel, bool enable)
{
if(enable)
__REG_SET(HW_LRADC_CTRL1) = HW_LRADC_CTRL1__LRADCx_IRQ_EN(channel);
else
__REG_CLR(HW_LRADC_CTRL1) = HW_LRADC_CTRL1__LRADCx_IRQ_EN(channel);
imx233_lradc_clear_channel_irq(channel);
}
void imx233_lradc_kick_channel(int channel)
{
imx233_lradc_clear_channel_irq(channel);
__REG_SET(HW_LRADC_CTRL0) = HW_LRADC_CTRL0__SCHEDULE(channel);
}
@ -68,7 +116,7 @@ void imx233_lradc_kick_delay(int dchan)
void imx233_lradc_wait_channel(int channel)
{
/* wait for completion */
while(!(HW_LRADC_CTRL1 & HW_LRADC_CTRL1__LRADCx_IRQ(channel)))
while(!imx233_lradc_read_channel_irq(channel))
yield();
}
@ -185,7 +233,7 @@ int imx233_lradc_sense_ext_temperature(int chan, int sensor)
/* disable sensor current */
imx233_lradc_set_temp_isrc(sensor, HW_LRADC_CTRL2__TEMP_ISRC__0uA);
return (b - a) / EXT_TEMP_ACC_COUNT;
return (abs(b - a) / EXT_TEMP_ACC_COUNT) * 1104 / 1000;
}
void imx233_lradc_setup_battery_conversion(bool automatic, unsigned long scale_factor)
@ -203,6 +251,32 @@ int imx233_lradc_read_battery_voltage(void)
return __XTRACT(HW_LRADC_CONVERSION, SCALED_BATT_VOLTAGE);
}
void imx233_lradc_setup_touch(bool xminus_enable, bool yminus_enable,
bool xplus_enable, bool yplus_enable, bool touch_detect)
{
__FIELD_SET_CLR(HW_LRADC_CTRL0, XMINUS_ENABLE, xminus_enable);
__FIELD_SET_CLR(HW_LRADC_CTRL0, YMINUS_ENABLE, yminus_enable);
__FIELD_SET_CLR(HW_LRADC_CTRL0, XPLUS_ENABLE, xplus_enable);
__FIELD_SET_CLR(HW_LRADC_CTRL0, YPLUS_ENABLE, yplus_enable);
__FIELD_SET_CLR(HW_LRADC_CTRL0, TOUCH_DETECT_ENABLE, touch_detect);
}
void imx233_lradc_enable_touch_detect_irq(bool enable)
{
__FIELD_SET_CLR(HW_LRADC_CTRL1, TOUCH_DETECT_IRQ_EN, enable);
imx233_lradc_clear_touch_detect_irq();
}
void imx233_lradc_clear_touch_detect_irq(void)
{
__REG_CLR(HW_LRADC_CTRL1) = HW_LRADC_CTRL1__TOUCH_DETECT_IRQ;
}
bool imx233_lradc_read_touch_detect(void)
{
return HW_LRADC_STATUS & HW_LRADC_STATUS__TOUCH_DETECT_RAW;
}
void imx233_lradc_init(void)
{
arbiter_init(&channel_arbiter, HW_LRADC_NUM_CHANNELS);

View file

@ -31,12 +31,19 @@
#define HW_LRADC_BASE 0x80050000
#define HW_LRADC_CTRL0 (*(volatile uint32_t *)(HW_LRADC_BASE + 0x0))
#define HW_LRADC_CTRL0__XPLUS_ENABLE (1 << 16)
#define HW_LRADC_CTRL0__YPLUS_ENABLE (1 << 17)
#define HW_LRADC_CTRL0__XMINUS_ENABLE (1 << 18)
#define HW_LRADC_CTRL0__YMINUS_ENABLE (1 << 19)
#define HW_LRADC_CTRL0__TOUCH_DETECT_ENABLE (1 << 20)
#define HW_LRADC_CTRL0__ONCHIP_GROUNDREF (1 << 21)
#define HW_LRADC_CTRL0__SCHEDULE(x) (1 << (x))
#define HW_LRADC_CTRL1 (*(volatile uint32_t *)(HW_LRADC_BASE + 0x10))
#define HW_LRADC_CTRL1__LRADCx_IRQ(x) (1 << (x))
#define HW_LRADC_CTRL1__LRADCx_IRQ_EN(x) (1 << ((x) + 16))
#define HW_LRADC_CTRL1__LRADCx_IRQ(x) (1 << (x))
#define HW_LRADC_CTRL1__TOUCH_DETECT_IRQ (1 << 8)
#define HW_LRADC_CTRL1__LRADCx_IRQ_EN(x) (1 << ((x) + 16))
#define HW_LRADC_CTRL1__TOUCH_DETECT_IRQ_EN (1 << 24)
#define HW_LRADC_CTRL2 (*(volatile uint32_t *)(HW_LRADC_BASE + 0x20))
#define HW_LRADC_CTRL2__TEMP_ISRC1_BP 4
@ -63,6 +70,7 @@
#define HW_LRADC_CTRL3__CYCLE_TIME__2MHz (3 << 8)
#define HW_LRADC_STATUS (*(volatile uint32_t *)(HW_LRADC_BASE + 0x40))
#define HW_LRADC_STATUS__TOUCH_DETECT_RAW (1 << 0)
#define HW_LRADC_CHx(x) (*(volatile uint32_t *)(HW_LRADC_BASE + 0x50 + (x) * 0x10))
#define HW_LRADC_CHx__NUM_SAMPLES_BM (0x1f << 24)
@ -100,6 +108,10 @@
#define HW_LRADC_NUM_DELAYS 4
#define HW_LRADC_CHANNEL(x) (x)
#define HW_LRADC_CHANNEL_XPLUS HW_LRADC_CHANNEL(2)
#define HW_LRADC_CHANNEL_YPLUS HW_LRADC_CHANNEL(3)
#define HW_LRADC_CHANNEL_XMINUS HW_LRADC_CHANNEL(4)
#define HW_LRADC_CHANNEL_YMINUS HW_LRADC_CHANNEL(5)
#define HW_LRADC_CHANNEL_VDDIO HW_LRADC_CHANNEL(6)
#define HW_LRADC_CHANNEL_BATTERY HW_LRADC_CHANNEL(7)
#define HW_LRADC_CHANNEL_PMOS_THIN HW_LRADC_CHANNEL(8)
@ -112,10 +124,16 @@
#define HW_LRADC_CHANNEL_VBG HW_LRADC_CHANNEL(14)
#define HW_LRADC_CHANNEL_5V HW_LRADC_CHANNEL(15)
typedef void (*lradc_irq_fn_t)(int chan);
void imx233_lradc_init(void);
void imx233_lradc_setup_channel(int channel, bool div2, bool acc, int nr_samples, int src);
void imx233_lradc_setup_delay(int dchan, int trigger_lradc, int trigger_delays,
int loop_count, int delay);
void imx233_lradc_clear_channel_irq(int channel);
bool imx233_lradc_read_channel_irq(int channel);
void imx233_lradc_enable_channel_irq(int channel, bool enable);
void imx233_lradc_set_channel_irq_callback(int channel, lradc_irq_fn_t cb);
void imx233_lradc_kick_channel(int channel);
void imx233_lradc_kick_delay(int dchan);
void imx233_lradc_wait_channel(int channel);
@ -132,6 +150,13 @@ int imx233_lradc_acquire_delay(int timeout);
void imx233_lradc_reserve_delay(int dchannel);
void imx233_lradc_release_delay(int dchan);
/* Setup touch x/yminus pull donws and x/yplus pull ups */
void imx233_lradc_setup_touch(bool xminus_enable, bool yminus_enable,
bool xplus_enable, bool yplus_enable, bool touch_detect);
void imx233_lradc_enable_touch_detect_irq(bool enable);
void imx233_lradc_clear_touch_detect_irq(void);
bool imx233_lradc_read_touch_detect(void);
/* enable sensing and return temperature in kelvin,
* channels needs not to be configured */
int imx233_lradc_sense_die_temperature(int nmos_chan, int pmos_chan);