diff --git a/firmware/target/arm/rk27xx/adc-target.h b/firmware/target/arm/rk27xx/adc-target.h index c359f3d7df..d408b7415b 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 8e3d46bf0d..d0323e6f4d 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(); + } +} +