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.tar.gz
rockbox-04fb4b77ac6badc53256c69475ff131eb24edc83.zip
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 c359f3d7df..d408b7415b 100644
--- a/firmware/target/arm/rk27xx/adc-target.h
+++ b/firmware/target/arm/rk27xx/adc-target.h
@@ -25,7 +25,12 @@
25 25
26#define ADC_BATTERY 0 26#define ADC_BATTERY 0
27#define ADC_BUTTONS 1 27#define ADC_BUTTONS 1
28#define ADC_UNKNOWN 2 28
29/* HiFiMAN HM-801 usually use this channel for second battery,
30 but some of them use it for buttons.
31 */
32#define ADC_EXTRA 2
33
29#define ADC_VREF 3 /* that is what datasheet says */ 34#define ADC_VREF 3 /* that is what datasheet says */
30 35
31#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */ 36#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 @@
24#include "button.h" 24#include "button.h"
25#include "adc.h" 25#include "adc.h"
26 26
27enum keyboard_type_t {
28 KEYBOARD_V1,
29 KEYBOARD_V2,
30};
31
32static enum keyboard_type_t kbd_type;
33
27void button_init_device(void) { 34void button_init_device(void) {
28 /* setup button gpio as input */ 35 /* setup button gpio as input */
29 GPIO_PCCON &= ~(POWEROFF_BUTTON); 36 GPIO_PCCON &= ~(POWEROFF_BUTTON);
37
38 /* identify keyboard type */
39 SCU_IOMUXB_CON &= ~(1<<2);
40 GPIO_PCCON |= (1<<4);
41 if (GPIO_PCDR & (1<<4)) {
42 kbd_type = KEYBOARD_V1;
43 } else {
44 kbd_type = KEYBOARD_V2;
45 }
30} 46}
31 47
32int button_read_device(void) { 48static int button_read_device_v1(void) {
33 int adc_val = adc_read(ADC_BUTTONS); 49 int adc_val = adc_read(ADC_BUTTONS);
34 int button = 0; 50 int button = 0;
35 51
36 if (adc_val < 480) { /* middle */ 52 if (adc_val < 480) { /* middle */
37 if (adc_val < 200) { /* 200 - 0 */ 53 if (adc_val < 200) { /* 0 - 200 */
38 if (adc_val < 30) { 54 if (adc_val < 30) {
39 button = BUTTON_UP; 55 button = BUTTON_UP;
40 } else { 56 } else { /* 30 - 200 */
41 button = BUTTON_RIGHT; /* 30 - 200 */ 57 button = BUTTON_RIGHT;
42 } 58 }
43 } else { /* 200 - 480 */ 59 } else { /* 200 - 480 */
44 if (adc_val < 370) { 60 if (adc_val < 370) { /* 200 - 370 */
45 button = BUTTON_SELECT; 61 button = BUTTON_SELECT;
46 } else { 62 } else { /* 370 - 480 */
47 button = BUTTON_DOWN; 63 button = BUTTON_DOWN;
48 } 64 }
49 } 65 }
50 } else { /* > 480 */ 66 } else { /* > 480 */
51 if (adc_val < 690) { /* 480 - 690 */ 67 if (adc_val < 690) { /* 480 - 690 */
52 if (adc_val < 580) { 68 if (adc_val < 580) { /* 480 - 580 */
53 button = BUTTON_LEFT; 69 button = BUTTON_LEFT;
54 } else { 70 } else { /* 580 - 690 */
55 button = BUTTON_NEXT; 71 button = BUTTON_NEXT;
56 } 72 }
57 } else { /* > 680 */ 73 } else { /* > 680 */
58 if (adc_val < 840) { 74 if (adc_val < 840) { /* 680 - 840 */
59 button = BUTTON_PREV; 75 button = BUTTON_PREV;
60 } else { 76 } else {
61 if (adc_val < 920) { 77 if (adc_val < 920) { /* 840 - 920 */
62 button = BUTTON_PLAY; 78 button = BUTTON_PLAY;
63 } 79 }
64 } 80 }
65 } 81 }
66 } 82 }
67 return button | (GPIO_PCDR & POWEROFF_BUTTON); 83 return button | (GPIO_PCDR & POWEROFF_BUTTON);
68} 84}
85
86static int button_read_device_v2(void) {
87 int adc_val = adc_read(ADC_BUTTONS);
88 int adc_val2 = adc_read(ADC_EXTRA);
89 int button = 0;
90
91 /* Buttons on front panel */
92 if (adc_val < 520) { /* middle */
93 if (adc_val < 360) { /* 0 - 360 */
94 if (adc_val < 40) { /* 0 - 40 */
95 button |= BUTTON_UP;
96 } else { /* 40 - 360 */
97 button |= BUTTON_RIGHT;
98 }
99 } else { /* 360 - 520 */
100 button |= BUTTON_SELECT;
101 }
102 } else { /* >= 520 */
103 if (adc_val < 770) { /* 520 - 770 */
104 if (adc_val < 640) { /* 520 - 640 */
105 button |= BUTTON_DOWN;
106 } else { /* 640 - 770 */
107 button |= BUTTON_LEFT;
108 }
109 }
110 }
111
112 /* Buttons on top */
113 if (adc_val2 < 400) { /* 0 - 400 */
114 if (adc_val2 < 120) { /* 0 - 120 */
115 button |= BUTTON_NEXT;
116 } else { /* 120 - 400 */
117 button |= BUTTON_PREV;
118 }
119 } else { /* >= 400 */
120 if (adc_val2 < 560) { /* 400 - 560 */
121 button |= BUTTON_PLAY;
122 }
123 }
124 return button | (GPIO_PCDR & POWEROFF_BUTTON);
125}
126
127int button_read_device(void) {
128 if (kbd_type == KEYBOARD_V1) {
129 return button_read_device_v1();
130 } else {
131 return button_read_device_v2();
132 }
133}
134