From 9bf93ba0075adf2b9e3291497e06918634d39880 Mon Sep 17 00:00:00 2001 From: Mark Arigo Date: Fri, 19 Dec 2008 03:31:26 +0000 Subject: [PATCH] Working touchpad for the Philips HDD1630 using the Synaptics driver. Like the m:robe 100, the strip is divided into up, select, and down button regions. You can't swipe like in the OF. The keymap still needs some work. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19480 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 3 + firmware/drivers/synaptics-mep.c | 16 ++ .../arm/olympus/mrobe-100/button-target.h | 3 + .../arm/philips/hdd1630/button-hdd1630.c | 156 ++++++++++++++---- .../arm/philips/hdd1630/button-target.h | 4 + firmware/target/arm/system-pp502x.c | 8 +- 6 files changed, 159 insertions(+), 31 deletions(-) diff --git a/firmware/SOURCES b/firmware/SOURCES index 86dc160291..278fcda9d6 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -535,6 +535,9 @@ target/arm/i2s-pp.c #ifdef PHILIPS_HDD1630 #ifndef SIMULATOR +#ifndef BOOTLOADER +drivers/synaptics-mep.c +#endif /* BOOTLOADER */ target/arm/ata-as-arm.S target/arm/ata-pp5020.c target/arm/wmcodec-pp.c diff --git a/firmware/drivers/synaptics-mep.c b/firmware/drivers/synaptics-mep.c index 44b186034f..858edf54fe 100644 --- a/firmware/drivers/synaptics-mep.c +++ b/firmware/drivers/synaptics-mep.c @@ -32,6 +32,7 @@ /* Driver for the Synaptics Touchpad based on the "Synaptics Modular Embedded Protocol: 3-Wire Interface Specification" documentation */ +#if defined(MROBE_100) #define ACK (GPIOD_INPUT_VAL & 0x1) #define ACK_HI GPIOD_OUTPUT_VAL |= 0x1 #define ACK_LO GPIOD_OUTPUT_VAL &= ~0x1 @@ -45,6 +46,21 @@ #define DATA_LO GPIOD_OUTPUT_EN |= 0x4; GPIOD_OUTPUT_VAL &= ~0x4 #define DATA_CL GPIOD_OUTPUT_EN &= ~0x4 +#elif defined(PHILIPS_HDD1630) +#define ACK (GPIOD_INPUT_VAL & 0x80) +#define ACK_HI GPIOD_OUTPUT_VAL |= 0x80 +#define ACK_LO GPIOD_OUTPUT_VAL &= ~0x80 + +#define CLK ((GPIOA_INPUT_VAL & 0x20) >> 5) +#define CLK_HI GPIOA_OUTPUT_VAL |= 0x20 +#define CLK_LO GPIOA_OUTPUT_VAL &= ~0x20 + +#define DATA ((GPIOA_INPUT_VAL & 0x10) >> 4) +#define DATA_HI GPIOA_OUTPUT_EN |= 0x10; GPIOA_OUTPUT_VAL |= 0x10 +#define DATA_LO GPIOA_OUTPUT_EN |= 0x10; GPIOA_OUTPUT_VAL &= ~0x10 +#define DATA_CL GPIOA_OUTPUT_EN &= ~0x10 +#endif + #define LO 0 #define HI 1 diff --git a/firmware/target/arm/olympus/mrobe-100/button-target.h b/firmware/target/arm/olympus/mrobe-100/button-target.h index 7f230831b1..c6b2c1067f 100644 --- a/firmware/target/arm/olympus/mrobe-100/button-target.h +++ b/firmware/target/arm/olympus/mrobe-100/button-target.h @@ -30,7 +30,10 @@ bool button_hold(void); void button_init_device(void); int button_read_device(void); + +#ifndef BOOTLOADER void button_int(void); +#endif #define POWEROFF_BUTTON BUTTON_POWER #define POWEROFF_COUNT 10 diff --git a/firmware/target/arm/philips/hdd1630/button-hdd1630.c b/firmware/target/arm/philips/hdd1630/button-hdd1630.c index 84cb8f0c06..8976e7325c 100755 --- a/firmware/target/arm/philips/hdd1630/button-hdd1630.c +++ b/firmware/target/arm/philips/hdd1630/button-hdd1630.c @@ -22,9 +22,16 @@ #include "system.h" #include "button.h" #include "backlight.h" +#include "synaptics-mep.h" -/* Remember last buttons, to make single buzz sound */ -int btn_old; +#define LOGF_ENABLE +#include "logf.h" + +#define MEP_BUTTON_HEADER 0x19 +#define MEP_BUTTON_ID 0x9 +#define MEP_ABSOLUTE_HEADER 0x0b + +static int int_btn = BUTTON_NONE; /* * Generate a click sound from the player (not in headphones yet) @@ -38,11 +45,118 @@ void button_click(void) GPO32_VAL &= ~0x2000; } +#ifndef BOOTLOADER +static int syn_status = 0; + void button_init_device(void) { - /* TODO...for now, hardware initialisation is done by the bootloader */ + /* enable touchpad */ + GPO32_ENABLE |= 0x80; + GPO32_VAL &= ~0x80; + udelay(1000); + + /* enable ACK, CLK, DATA lines */ + GPIOD_ENABLE |= 0x80; + GPIOA_ENABLE |= (0x10 | 0x20); + + GPIOD_OUTPUT_EN |= 0x80; /* ACK */ + GPIOD_OUTPUT_VAL |= 0x80; /* high */ + + GPIOA_OUTPUT_EN &= ~0x20; /* CLK */ + + GPIOA_OUTPUT_EN |= 0x10; /* DATA */ + GPIOA_OUTPUT_VAL |= 0x10; /* high */ + + if (syn_init()) + { +#ifdef ROCKBOX_HAS_LOGF + syn_info(); +#endif + syn_status = 1; + + /* enable interrupts */ + GPIOA_INT_LEV &= ~0x20; + GPIOA_INT_CLR |= 0x20; + GPIOA_INT_EN |= 0x20; + + CPU_INT_EN |= HI_MASK; + CPU_HI_INT_EN |= GPIO0_MASK; + } } +/* + * Button interrupt handler + */ +void button_int(void) +{ + int data[4]; + int val, id; + + int_btn = BUTTON_NONE; + + if (syn_status) + { + /* disable interrupt while we read the touchpad */ + GPIOA_INT_EN &= ~0x20; + GPIOA_INT_CLR |= 0x20; + + val = syn_read_device(data, 4); + if (val > 0) + { + val = data[0] & 0xff; /* packet header */ + id = (data[1] >> 4) & 0xf; /* packet id */ + + logf("button_read_device..."); + logf(" data[0] = 0x%08x", data[0]); + logf(" data[1] = 0x%08x", data[1]); + logf(" data[2] = 0x%08x", data[2]); + logf(" data[3] = 0x%08x", data[3]); + + if ((val == MEP_BUTTON_HEADER) && (id == MEP_BUTTON_ID)) + { + /* Buttons packet */ + if (data[1] & 0x1) + int_btn |= BUTTON_LEFT; + if (data[1] & 0x2) + int_btn |= BUTTON_RIGHT; + + /* An Absolute packet should follow which we ignore */ + val = syn_read_device(data, 4); + logf(" int_btn = 0x%04x", int_btn); + } + else if (val == MEP_ABSOLUTE_HEADER) + { + /* Absolute packet - the finger is on the vertical strip. + Position ranges from 1-4095, with 1 at the bottom. */ + val = ((data[1] >> 4) << 8) | data[2]; /* position */ + + logf(" pos %d", val); + logf(" z %d", data[3]); + logf(" finger %d", data[1] & 0x1); + logf(" gesture %d", data[1] & 0x2); + logf(" RelPosVld %d", data[1] & 0x4); + + if(data[1] & 0x1) /* if finger on touch strip */ + { + if ((val > 0) && (val <= 1365)) + int_btn |= BUTTON_DOWN; + else if ((val > 1365) && (val <= 2730)) + int_btn |= BUTTON_SELECT; + else if ((val > 2730) && (val <= 4095)) + int_btn |= BUTTON_UP; + } + } + } + + /* re-enable interrupts */ + GPIOA_INT_LEV &= ~0x20; + GPIOA_INT_EN |= 0x20; + } +} +#else +void button_init_device(void){} +#endif /* bootloader */ + bool button_hold(void) { return !(GPIOJ_INPUT_VAL & 0x8); @@ -53,34 +167,20 @@ bool button_hold(void) */ int button_read_device(void) { - int btn = BUTTON_NONE; - static bool hold_button = false; - bool hold_button_old; + static int btn_old = BUTTON_NONE; + int btn = int_btn; /* Hold */ - hold_button_old = hold_button; - hold_button = button_hold(); + if(button_hold()) + return BUTTON_NONE; - /* device buttons */ - if (!hold_button) - { - /* These are the correct button definitions - if (!(GPIOA_INPUT_VAL & 0x01)) btn |= BUTTON_MENU; - if (!(GPIOA_INPUT_VAL & 0x02)) btn |= BUTTON_VOL_UP; - if (!(GPIOA_INPUT_VAL & 0x04)) btn |= BUTTON_VOL_DOWN; - if (!(GPIOA_INPUT_VAL & 0x08)) btn |= BUTTON_VIEW; - if (!(GPIOD_INPUT_VAL & 0x20)) btn |= BUTTON_PLAYLIST; - if (!(GPIOD_INPUT_VAL & 0x40)) btn |= BUTTON_POWER; - */ - - /* This is a hack until the touchpad works */ - if (!(GPIOA_INPUT_VAL & 0x01)) btn |= BUTTON_LEFT; /* BUTTON_MENU */ - if (!(GPIOA_INPUT_VAL & 0x02)) btn |= BUTTON_UP; /* BUTTON_VOL_UP */ - if (!(GPIOA_INPUT_VAL & 0x04)) btn |= BUTTON_DOWN; /* BUTTON_VOL_DOWN */ - if (!(GPIOA_INPUT_VAL & 0x08)) btn |= BUTTON_RIGHT; /* BUTTON_VIEW */ - if (!(GPIOD_INPUT_VAL & 0x20)) btn |= BUTTON_SELECT; /* BUTTON_PLAYLIST */ - if (!(GPIOD_INPUT_VAL & 0x40)) btn |= BUTTON_POWER; - } + /* Device buttons */ + if (!(GPIOA_INPUT_VAL & 0x01)) btn |= BUTTON_MENU; + if (!(GPIOA_INPUT_VAL & 0x02)) btn |= BUTTON_VOL_UP; + if (!(GPIOA_INPUT_VAL & 0x04)) btn |= BUTTON_VOL_DOWN; + if (!(GPIOA_INPUT_VAL & 0x08)) btn |= BUTTON_VIEW; + if (!(GPIOD_INPUT_VAL & 0x20)) btn |= BUTTON_PLAYLIST; + if (!(GPIOD_INPUT_VAL & 0x40)) btn |= BUTTON_POWER; if ((btn != btn_old) && (btn != BUTTON_NONE)) button_click(); diff --git a/firmware/target/arm/philips/hdd1630/button-target.h b/firmware/target/arm/philips/hdd1630/button-target.h index 65cc4539cf..cd5b13775e 100755 --- a/firmware/target/arm/philips/hdd1630/button-target.h +++ b/firmware/target/arm/philips/hdd1630/button-target.h @@ -31,6 +31,10 @@ bool button_hold(void); void button_init_device(void); int button_read_device(void); +#ifndef BOOTLOADER +void button_int(void); +#endif + /* Main unit's buttons */ #define BUTTON_POWER 0x00000001 #define BUTTON_PLAYLIST 0x00000002 diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c index 0f336576d8..d683b3a561 100644 --- a/firmware/target/arm/system-pp502x.c +++ b/firmware/target/arm/system-pp502x.c @@ -34,9 +34,6 @@ extern void TIMER1(void); extern void TIMER2(void); extern void ipod_mini_button_int(void); /* iPod Mini 1st gen only */ extern void ipod_4g_button_int(void); /* iPod 4th gen and higher only */ -#ifdef MROBE_100 -extern void button_int(void); -#endif void irq(void) { @@ -75,6 +72,11 @@ void irq(void) if (GPIOD_INT_STAT & 0x2) button_int(); } +#elif defined(PHILIPS_HDD1630) + else if (CPU_HI_INT_STAT & GPIO0_MASK) { + if (GPIOA_INT_STAT & 0x20) + button_int(); + } #endif #ifdef HAVE_USBSTACK else if (CPU_INT_STAT & USB_MASK) {