summaryrefslogtreecommitdiffstats
path: root/src/target/firmware
diff options
context:
space:
mode:
authorSteve Markgraf <steve@steve-m.de>2019-08-11 02:10:24 +0200
committerSteve Markgraf <steve@steve-m.de>2019-08-11 13:33:29 +0200
commitda7cd7408a7230ea474353b54b889ae877354326 (patch)
tree27180eaaca372d64f5bb8894faf50bfe61edea28 /src/target/firmware
parenta1de51d357629e03558cbbb03f3540ed36f94d76 (diff)
fw/abb/twl3025: Add function to query PWON state
This allows us to detect power button presses on the Pirelli DP-L10 and the Huawei GTM900-B module. Polling will only be activated once the power button has been pressed and we received the interrupt. The goal is to reduce the required amount of TWL3025 register accesses to a minimum. Change-Id: I31be61c8089173aed616abd1ede6c4cf5c9b6770
Diffstat (limited to 'src/target/firmware')
-rw-r--r--src/target/firmware/abb/twl3025.c28
-rwxr-xr-xsrc/target/firmware/include/abb/twl3025.h2
2 files changed, 30 insertions, 0 deletions
diff --git a/src/target/firmware/abb/twl3025.c b/src/target/firmware/abb/twl3025.c
index e4fcf4f0..ad2b01f9 100644
--- a/src/target/firmware/abb/twl3025.c
+++ b/src/target/firmware/abb/twl3025.c
@@ -60,8 +60,15 @@ const uint16_t twl3025_default_ramp[16] = {
ABB_RAMP_VAL( 0, 0),
};
+typedef enum pwon_state {
+ PWON_IDLE,
+ PWON_DETECTED,
+ PWON_REPORTED,
+} pwon_state_t;
+
struct twl3025 {
uint8_t page;
+ pwon_state_t pwon;
};
static struct twl3025 twl3025_state;
@@ -106,6 +113,8 @@ static void twl3025_irq(enum irq_nr nr)
case IRQ_EXTERNAL: // charger in/out, pwrbtn, adc done
src = twl3025_reg_read(ITSTATREG);
// printd("itstatreg 0x%02x\n", src);
+ if ((src & 0x04) && twl3025_state.pwon == PWON_IDLE)
+ twl3025_state.pwon = PWON_DETECTED;
if (src & 0x08)
handle_charger();
if (src & 0x20)
@@ -127,6 +136,7 @@ void twl3025_init(void)
twl3025_clk13m(1);
twl3025_reg_write(AFCCTLADD, 0x01); /* AFCCK(1:0) must not be zero! */
twl3025_unit_enable(TWL3025_UNIT_AFC, 1);
+ twl3025_state.pwon = PWON_IDLE;
irq_register_handler(IRQ_EXTERNAL, &twl3025_irq);
irq_config(IRQ_EXTERNAL, 0, 0, 0);
@@ -185,6 +195,24 @@ static void twl3025_wait_ibic_access(void)
delay_ms(1);
}
+int twl3025_get_pwon(void)
+{
+ switch (twl3025_state.pwon) {
+ case PWON_DETECTED:
+ twl3025_state.pwon = PWON_REPORTED;
+ break;
+ case PWON_REPORTED:
+ if (twl3025_reg_read(VRPCSTS) & 0x10)
+ twl3025_state.pwon = PWON_IDLE;
+ break;
+ case PWON_IDLE:
+ default:
+ break;
+ }
+
+ return (twl3025_state.pwon != PWON_IDLE);
+}
+
void twl3025_power_off(void)
{
unsigned long flags;
diff --git a/src/target/firmware/include/abb/twl3025.h b/src/target/firmware/include/abb/twl3025.h
index 36406449..938a4252 100755
--- a/src/target/firmware/include/abb/twl3025.h
+++ b/src/target/firmware/include/abb/twl3025.h
@@ -144,6 +144,8 @@ void twl3025_init(void);
void twl3025_reg_write(uint8_t reg, uint16_t data);
uint16_t twl3025_reg_read(uint8_t reg);
+int twl3025_get_pwon(void);
+
void twl3025_power_off(void);
void twl3025_clk13m(int enable);