diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2012-05-19 13:36:23 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2012-05-19 16:10:52 +0200 |
commit | 55e01b8de46555929f62a9eb762d7791786ccc58 (patch) | |
tree | 71c657f38d4d5c461803caf8bda362728284fa01 | |
parent | 01216c5ad3f2996d16cd7279387d2df859ec019b (diff) |
imx233: enhance lradc driver with touchscreen specific stuff
Change-Id: I83759a00257274c0cbde5a78306256abd2c83800
-rw-r--r-- | firmware/target/arm/imx233/lradc-imx233.c | 80 | ||||
-rw-r--r-- | firmware/target/arm/imx233/lradc-imx233.h | 29 |
2 files changed, 104 insertions, 5 deletions
diff --git a/firmware/target/arm/imx233/lradc-imx233.c b/firmware/target/arm/imx233/lradc-imx233.c index 4d309b0875..e6a3738b9c 100644 --- a/firmware/target/arm/imx233/lradc-imx233.c +++ b/firmware/target/arm/imx233/lradc-imx233.c @@ -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); diff --git a/firmware/target/arm/imx233/lradc-imx233.h b/firmware/target/arm/imx233/lradc-imx233.h index b661fa8aa4..f71843b3db 100644 --- a/firmware/target/arm/imx233/lradc-imx233.h +++ b/firmware/target/arm/imx233/lradc-imx233.h @@ -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); |