From 85c9a05c56a290a0dd1686808d5bdb966d72f9a5 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Sun, 29 Oct 2006 13:48:57 +0000 Subject: H300: Don't read the button ADC as long as no button is pressed, utilising the PCF50606 accessory detect feature. Ported from X5. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11383 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/coldfire/iriver/button-target.h | 4 ++ firmware/target/coldfire/iriver/h300/button-h300.c | 19 +++++-- .../target/coldfire/iriver/h300/pcf50606-h300.c | 61 ++++++++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) (limited to 'firmware/target/coldfire') diff --git a/firmware/target/coldfire/iriver/button-target.h b/firmware/target/coldfire/iriver/button-target.h index b89761b317..3d3247ab80 100644 --- a/firmware/target/coldfire/iriver/button-target.h +++ b/firmware/target/coldfire/iriver/button-target.h @@ -33,6 +33,10 @@ bool remote_button_hold(void); bool remote_button_hold_only(void); void button_init_device(void); int button_read_device(void); +#ifdef IRIVER_H300_SERIES +void button_enable_scan(bool enable); +bool button_scan_enabled(void); +#endif /* iRiver H100/H300 specific button codes */ diff --git a/firmware/target/coldfire/iriver/h300/button-h300.c b/firmware/target/coldfire/iriver/h300/button-h300.c index 80210b6c19..bcd954df8a 100644 --- a/firmware/target/coldfire/iriver/h300/button-h300.c +++ b/firmware/target/coldfire/iriver/h300/button-h300.c @@ -27,9 +27,10 @@ #include "backlight.h" #include "adc.h" #include "system.h" -#ifdef HAVE_REMOTE_LCD #include "lcd-remote.h" -#endif + +/* have buttons scan by default */ +static bool button_scan_on = true; void button_init_device(void) { @@ -41,13 +42,23 @@ void button_init_device(void) GPIO1_FUNCTION |= 0x00100062; } +void button_enable_scan(bool enable) +{ + button_scan_on = enable; +} + +bool button_scan_enabled(void) +{ + return button_scan_on; +} + bool button_hold(void) { return (GPIO1_READ & 0x00000002)?true:false; } bool remote_button_hold_only(void) -{ +{ if(remote_type() == REMOTETYPE_H300_NONLCD) return adc_scan(ADC_REMOTE)<0x0d; /* hold should be 0x00 */ else @@ -88,7 +99,7 @@ int button_read_device(void) backlight_hold_changed(hold_button); #endif - if (!hold_button) + if (button_scan_on && !hold_button) { data = adc_scan(ADC_BUTTONS); diff --git a/firmware/target/coldfire/iriver/h300/pcf50606-h300.c b/firmware/target/coldfire/iriver/h300/pcf50606-h300.c index c990f5ddcb..3a67d541d3 100644 --- a/firmware/target/coldfire/iriver/h300/pcf50606-h300.c +++ b/firmware/target/coldfire/iriver/h300/pcf50606-h300.c @@ -20,6 +20,7 @@ #include "system.h" #include "kernel.h" #include "pcf50606.h" +#include "button-target.h" /* These voltages were determined by measuring the output of the PCF50606 on a running H300, and verified by disassembling the original firmware */ @@ -37,10 +38,44 @@ static void set_voltages(void) pcf50606_write_multiple(0x23, buf, 5); } +static void init_pmu_interrupts(void) +{ + /* inital data is interrupt masks */ + unsigned char data[3] = + { + ~0x00, + ~0x00, + ~0x06, /* unmask ACDREM, ACDINS */ + }; + + /* make sure GPI6 interrupt is off before unmasking anything */ + and_l(~0x0f000000, &INTPRI5); /* INT38 - Priority 0 (Off) */ + + /* unmask the PMU interrupts we want to service */ + pcf50606_write_multiple(0x05, data, 3); + /* clear INT1-3 as these are left set after standby */ + pcf50606_read_multiple(0x02, data, 3); + + /* Set to read pcf50606 INT but keep GPI6 off until init completes */ + and_l(~0x00000040, &GPIO_ENABLE); + or_l(0x00000040, &GPIO_FUNCTION); + or_l(0x00004000, &GPIO_INT_EN); /* GPI6 H-L */ +} + +static inline void enable_pmu_interrupts(void) +{ + /* clear pending GPI6 interrupts first or it may miss the first + H-L transition */ + or_l(0x00004000, &GPIO_INT_CLEAR); + or_l(0x03000000, &INTPRI5); /* INT38 - Priority 3 */ +} + void pcf50606_init(void) { pcf50606_i2c_init(); + /* initialize pmu interrupts but don't service them yet */ + init_pmu_interrupts(); set_voltages(); pcf50606_write(0x08, 0x60); /* Wake on USB and charger insertion */ @@ -49,4 +84,30 @@ void pcf50606_init(void) pcf50606_write(0x35, 0x13); /* Backlight PWM = 512Hz 50/50 */ pcf50606_write(0x3a, 0x3b); /* PWM output on GPOOD1 */ + + pcf50606_write(0x33, 0x8c); /* Accessory detect: ACDAPE=1, THRSHLD=2.20V */ + + enable_pmu_interrupts(); /* allow GPI6 interrupts from PMU now */ +} + +/* PMU interrupt */ +void GPI6(void) __attribute__ ((interrupt_handler)); +void GPI6(void) +{ + unsigned char data[3]; /* 0 = INT1, 1 = INT2, 2 = INT3 */ + + /* Clear pending GPI6 interrupts */ + or_l(0x00004000, &GPIO_INT_CLEAR); + + /* clear pending interrupts from pcf50606 */ + pcf50606_read_multiple(0x02, data, 3); + + if (data[2] & 0x06) + { + /* ACDINS/ACDREM */ + /* Check if the button driver should actually scan main buttons or not + - bias towards "yes" out of paranoia. */ + button_enable_scan((data[2] & 0x02) != 0 || + (pcf50606_read(0x33) & 0x01) != 0); + } } -- cgit v1.2.3