summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Ryabinin <ryabinin.a.a@gmail.com>2012-10-17 11:37:55 +0400
committerAndrew Ryabinin <ryabinin.a.a@gmail.com>2012-10-18 14:10:02 +0400
commit04fb4b77ac6badc53256c69475ff131eb24edc83 (patch)
tree6bb5599499dba6515b87f10c95110b182668ab02
parent89254cb612dc1c1f69e123bde81b97a1c00dfa8f (diff)
downloadrockbox-04fb4b77ac6badc53256c69475ff131eb24edc83.zip
rockbox-04fb4b77ac6badc53256c69475ff131eb24edc83.tar.gz
rockbox-04fb4b77ac6badc53256c69475ff131eb24edc83.tar.bz2
rockbox-04fb4b77ac6badc53256c69475ff131eb24edc83.tar.xz
hm801: Implement additional button driver.
Several HM-801 DAPs have another buttons circuit. This patch adds support for such devices so they could work properly. Change-Id: Ic49e8e46b3e785b91c7c4706003fac3dbc20ae59
-rw-r--r--firmware/target/arm/rk27xx/adc-target.h7
-rw-r--r--firmware/target/arm/rk27xx/hm801/button-hm801.c120
2 files changed, 99 insertions, 28 deletions
diff --git a/firmware/target/arm/rk27xx/adc-target.h b/firmware/target/arm/rk27xx/adc-target.h
index c359f3d..d408b74 100644
--- a/firmware/target/arm/rk27xx/adc-target.h
+++ b/firmware/target/arm/rk27xx/adc-target.h
@@ -25,7 +25,12 @@
#define ADC_BATTERY 0
#define ADC_BUTTONS 1
-#define ADC_UNKNOWN 2
+
+/* HiFiMAN HM-801 usually use this channel for second battery,
+ but some of them use it for buttons.
+ */
+#define ADC_EXTRA 2
+
#define ADC_VREF 3 /* that is what datasheet says */
#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
diff --git a/firmware/target/arm/rk27xx/hm801/button-hm801.c b/firmware/target/arm/rk27xx/hm801/button-hm801.c
index 8e3d46b..d0323e6 100644
--- a/firmware/target/arm/rk27xx/hm801/button-hm801.c
+++ b/firmware/target/arm/rk27xx/hm801/button-hm801.c
@@ -24,45 +24,111 @@
#include "button.h"
#include "adc.h"
+enum keyboard_type_t {
+ KEYBOARD_V1,
+ KEYBOARD_V2,
+};
+
+static enum keyboard_type_t kbd_type;
+
void button_init_device(void) {
/* setup button gpio as input */
GPIO_PCCON &= ~(POWEROFF_BUTTON);
+
+ /* identify keyboard type */
+ SCU_IOMUXB_CON &= ~(1<<2);
+ GPIO_PCCON |= (1<<4);
+ if (GPIO_PCDR & (1<<4)) {
+ kbd_type = KEYBOARD_V1;
+ } else {
+ kbd_type = KEYBOARD_V2;
+ }
}
-int button_read_device(void) {
+static int button_read_device_v1(void) {
int adc_val = adc_read(ADC_BUTTONS);
int button = 0;
if (adc_val < 480) { /* middle */
- if (adc_val < 200) { /* 200 - 0 */
- if (adc_val < 30) {
- button = BUTTON_UP;
- } else {
- button = BUTTON_RIGHT; /* 30 - 200 */
- }
+ if (adc_val < 200) { /* 0 - 200 */
+ if (adc_val < 30) {
+ button = BUTTON_UP;
+ } else { /* 30 - 200 */
+ button = BUTTON_RIGHT;
+ }
} else { /* 200 - 480 */
- if (adc_val < 370) {
- button = BUTTON_SELECT;
- } else {
- button = BUTTON_DOWN;
- }
- }
+ if (adc_val < 370) { /* 200 - 370 */
+ button = BUTTON_SELECT;
+ } else { /* 370 - 480 */
+ button = BUTTON_DOWN;
+ }
+ }
} else { /* > 480 */
if (adc_val < 690) { /* 480 - 690 */
- if (adc_val < 580) {
- button = BUTTON_LEFT;
- } else {
- button = BUTTON_NEXT;
- }
- } else { /* > 680 */
- if (adc_val < 840) {
- button = BUTTON_PREV;
- } else {
- if (adc_val < 920) {
- button = BUTTON_PLAY;
- }
- }
- }
+ if (adc_val < 580) { /* 480 - 580 */
+ button = BUTTON_LEFT;
+ } else { /* 580 - 690 */
+ button = BUTTON_NEXT;
+ }
+ } else { /* > 680 */
+ if (adc_val < 840) { /* 680 - 840 */
+ button = BUTTON_PREV;
+ } else {
+ if (adc_val < 920) { /* 840 - 920 */
+ button = BUTTON_PLAY;
+ }
+ }
+ }
}
return button | (GPIO_PCDR & POWEROFF_BUTTON);
}
+
+static int button_read_device_v2(void) {
+ int adc_val = adc_read(ADC_BUTTONS);
+ int adc_val2 = adc_read(ADC_EXTRA);
+ int button = 0;
+
+ /* Buttons on front panel */
+ if (adc_val < 520) { /* middle */
+ if (adc_val < 360) { /* 0 - 360 */
+ if (adc_val < 40) { /* 0 - 40 */
+ button |= BUTTON_UP;
+ } else { /* 40 - 360 */
+ button |= BUTTON_RIGHT;
+ }
+ } else { /* 360 - 520 */
+ button |= BUTTON_SELECT;
+ }
+ } else { /* >= 520 */
+ if (adc_val < 770) { /* 520 - 770 */
+ if (adc_val < 640) { /* 520 - 640 */
+ button |= BUTTON_DOWN;
+ } else { /* 640 - 770 */
+ button |= BUTTON_LEFT;
+ }
+ }
+ }
+
+ /* Buttons on top */
+ if (adc_val2 < 400) { /* 0 - 400 */
+ if (adc_val2 < 120) { /* 0 - 120 */
+ button |= BUTTON_NEXT;
+ } else { /* 120 - 400 */
+ button |= BUTTON_PREV;
+ }
+ } else { /* >= 400 */
+ if (adc_val2 < 560) { /* 400 - 560 */
+ button |= BUTTON_PLAY;
+ }
+ }
+ return button | (GPIO_PCDR & POWEROFF_BUTTON);
+}
+
+int button_read_device(void) {
+ if (kbd_type == KEYBOARD_V1) {
+ return button_read_device_v1();
+ } else {
+ return button_read_device_v2();
+ }
+}
+