summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2020-09-12 05:03:12 -0400
committerWilliam Wilgus <me.theuser@yahoo.com>2020-09-13 16:23:24 +0000
commitc62493e98adfd27c16eb2adb2ecd22716813b705 (patch)
treec5d2a0fbdcf145584518289885e7676f82b20a29 /firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c
parent6b674a6a0a347bd4cb946b37b6e075dc2715f7ac (diff)
downloadrockbox-c62493e98adfd27c16eb2adb2ecd22716813b705.tar.gz
rockbox-c62493e98adfd27c16eb2adb2ecd22716813b705.zip
Xduoo X3 Add tree scrolling FS#13240, Emulate Multibutton presses
Fixes deficiencies with the button system on the X3 The x3 has an interesting button layout. Multiple key presses are NOT supported unless [BUTTON_POWER] is one of the combined keys As you can imagine this causes problems as the power button takes precedence in the button system and initiates a shutdown if the key is held too long instead of BUTTON_POWER use BUTTON_PWRALT in combination with other keys IF using as a prerequsite button then BUTTON_POWER should be used Multiple buttons are emulated by button_read_device but there are a few caveats to be aware of: Button Order Matters! different keys have different priorities, higher priority keys 'overide' the lower priority keys VOLUP[7] VOLDN[6] PREV[5] NEXT[4] PLAY[3] OPTION[2] HOME[1] There will be no true release or repeat events, the user can let off the button pressed initially and it will still continue to appear to be pressed as long as the second key is held Tree scrolling is PLAY+NEXT or PLAY+PREV Change-Id: I88dfee1c70a6a99659e8227f5becacc50cc43910
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c67
1 files changed, 49 insertions, 18 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c
index 0f845d96d3..0d251754dd 100644
--- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c
@@ -56,6 +56,8 @@
56#define ADC_MASK 0x0FFF 56#define ADC_MASK 0x0FFF
57 57
58static volatile unsigned short bat_val, key_val; 58static volatile unsigned short bat_val, key_val;
59static volatile int btn_last = BUTTON_NONE;
60static volatile long btn_last_tick;
59 61
60bool headphones_inserted(void) 62bool headphones_inserted(void)
61{ 63{
@@ -108,52 +110,82 @@ bool button_hold(void)
108} 110}
109 111
110/* NOTE: Due to how this is wired, button combinations are not allowed 112/* NOTE: Due to how this is wired, button combinations are not allowed
111 unless one of the two buttons is the POWER 113 * unless one of the two buttons is the POWER
112*/ 114 *
115 * Note --Update 2020
116 * by toggling BOP common I was able to remove BACK, OPTION, PLAY from the
117 * loop selectively and test which keys were pressed but this took two adc rounds
118 * and proved to be minimally useful for the added overhead
119 *
120 * NOW multiple button presses are emulated but button priority needs to be taken
121 * into consideration; higher priority keys 'overide' the lower priority keys
122 * VOLUP[7] VOLDN[6] PREV[5] NEXT[4] PLAY[3] OPTION[2] HOME[1]
123 */
113int button_read_device(void) 124int button_read_device(void)
114{ 125{
126 unsigned short key;
115 int btn = BUTTON_NONE; 127 int btn = BUTTON_NONE;
116 unsigned short key = (key_val & ADC_MASK); 128 int btn_pwr = BUTTON_NONE;
117 129
118 if (button_hold()) 130 if (button_hold())
119 return BUTTON_NONE; 131 return BUTTON_NONE;
120 132
121 if (KEY_IS_DOWN(PIN_BTN_POWER)) 133 if (KEY_IS_DOWN(PIN_BTN_POWER))
122 btn |= BUTTON_POWER; 134 btn_pwr = BUTTON_POWER;
123 135
124 if (!KEY_IS_DOWN(PIN_KEY_INT)) 136 if (!KEY_IS_DOWN(PIN_KEY_INT))
125 return btn; 137 {
138 __intc_mask_irq(IRQ_SADC);
139 REG_SADC_ADENA &= ~ADENA_AUXEN;
140 return btn_pwr;
141 }
142
143 key = (key_val & ADC_MASK);
144
145 /* Don't initiate a new request if we have one pending */
146 if(!(REG_SADC_ADENA & (ADENA_AUXEN)))
147 {
148 REG_SADC_ADENA |= ADENA_AUXEN;
149 }
126 150
127 if (key < 261) 151 if (key < 261)
128 btn |= BUTTON_VOL_UP; 152 btn = BUTTON_VOL_UP;
129 else 153 else
130 if (key < 653) 154 if (key < 653)
131 btn |= BUTTON_VOL_DOWN; 155 btn = BUTTON_VOL_DOWN;
132 else 156 else
133 if (key < 1101) 157 if (key < 1101)
134 btn |= BUTTON_PREV; 158 btn = BUTTON_PREV;
135 else 159 else
136 if (key < 1498) 160 if (key < 1498)
137 btn |= BUTTON_NEXT; 161 btn = BUTTON_NEXT;
138 else 162 else
139 if (key < 1839) 163 if (key < 1839)
140 btn |= BUTTON_PLAY; 164 btn = BUTTON_PLAY;
141 else 165 else
142 if (key < 2213) 166 if (key < 2213)
143 btn |= BUTTON_OPTION; 167 btn = BUTTON_OPTION;
144 else 168 else
145 if (key < 2600) 169 if (key < 2600)
146 btn |= BUTTON_HOME; 170 btn = BUTTON_HOME;
171
172 if (btn_last == BUTTON_NONE && TIME_AFTER(current_tick, btn_last_tick + HZ/20))
173 btn_last = btn;
174
175 if (btn_pwr != BUTTON_NONE)
176 btn |= BUTTON_PWRALT;
147 177
148 return btn; 178 return btn | btn_last;
149} 179}
150 180
151/* called on button press interrupt */ 181/* called on button press interrupt */
152void KEY_INT_IRQ(void) 182void KEY_INT_IRQ(void)
153{ 183{
154 /* Don't initiate a new request if we have one pending */ 184 btn_last = BUTTON_NONE;
155 if(!(REG_SADC_ADENA & (ADENA_AUXEN))) 185 key_val = ADC_MASK;
156 REG_SADC_ADENA |= ADENA_AUXEN; 186 __intc_unmask_irq(IRQ_SADC);
187 REG_SADC_ADENA |= ADENA_AUXEN;
188 btn_last_tick = current_tick;
157} 189}
158 190
159/* Notes on batteries 191/* Notes on batteries
@@ -238,6 +270,7 @@ void adc_init(void)
238 REG_SADC_ADCFG = ADCFG_VBAT_SEL | ADCFG_CMD_AUX(1); /* VBAT_SEL is undocumented but required! */ 270 REG_SADC_ADCFG = ADCFG_VBAT_SEL | ADCFG_CMD_AUX(1); /* VBAT_SEL is undocumented but required! */
239 REG_SADC_ADCLK = (199 << 16) | (1 << 8) | 61; 271 REG_SADC_ADCLK = (199 << 16) | (1 << 8) | 61;
240 system_enable_irq(IRQ_SADC); 272 system_enable_irq(IRQ_SADC);
273 REG_SADC_ADENA |= ADENA_AUXEN | ADENA_VBATEN;
241} 274}
242 275
243void adc_close(void) 276void adc_close(void)
@@ -260,8 +293,6 @@ void SADC(void)
260 if(state & ADCTRL_ARDYM) 293 if(state & ADCTRL_ARDYM)
261 { 294 {
262 key_val = REG_SADC_ADADAT; 295 key_val = REG_SADC_ADADAT;
263 if (KEY_IS_DOWN(PIN_KEY_INT)) /* key(s) are down kick off another read */
264 REG_SADC_ADENA = ADENA_AUXEN;
265 } 296 }
266 else if(UNLIKELY(state & ADCTRL_VRDYM)) 297 else if(UNLIKELY(state & ADCTRL_VRDYM))
267 { 298 {