summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/SOURCES7
-rw-r--r--firmware/drivers/ft6x06.c115
-rw-r--r--firmware/export/config/fiiom3k.h2
-rw-r--r--firmware/export/ft6x06.h50
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c110
5 files changed, 210 insertions, 74 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index d28c189213..0a6d4d30c3 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1928,13 +1928,18 @@ target/hosted/sdl/filesystem-sdl.c
1928drivers/touchpad.c 1928drivers/touchpad.c
1929#endif 1929#endif
1930 1930
1931/* Hardware drivers */
1932#ifndef SIMULATOR
1931#ifdef HAVE_I2C_ASYNC 1933#ifdef HAVE_I2C_ASYNC
1932drivers/i2c-async.c 1934drivers/i2c-async.c
1933#endif 1935#endif
1934
1935#ifdef HAVE_AXP_PMU 1936#ifdef HAVE_AXP_PMU
1936drivers/axp-pmu.c 1937drivers/axp-pmu.c
1937#endif 1938#endif
1939#ifdef HAVE_FT6x06
1940drivers/ft6x06.c
1941#endif
1942#endif
1938 1943
1939/* firmware/kernel section */ 1944/* firmware/kernel section */
1940#ifdef HAVE_CORELOCK_OBJECT 1945#ifdef HAVE_CORELOCK_OBJECT
diff --git a/firmware/drivers/ft6x06.c b/firmware/drivers/ft6x06.c
new file mode 100644
index 0000000000..538ca10480
--- /dev/null
+++ b/firmware/drivers/ft6x06.c
@@ -0,0 +1,115 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "ft6x06.h"
23#include "kernel.h"
24#include "i2c-async.h"
25#include <string.h>
26
27struct ft6x06_driver {
28 /* i2c bus data */
29 int i2c_cookie;
30 i2c_descriptor i2c_desc;
31
32 /* callback for touch events */
33 ft6x06_event_cb event_cb;
34
35 /* buffer for I2C transfers */
36 uint8_t raw_data[6];
37};
38
39static struct ft6x06_driver ft_drv;
40struct ft6x06_state ft6x06_state;
41
42static void ft6x06_i2c_callback(int status, i2c_descriptor* desc)
43{
44 (void)desc;
45 if(status != I2C_STATUS_OK)
46 return;
47
48 int evt = ft_drv.raw_data[1] >> 6;
49 int tx = ft_drv.raw_data[2] | ((ft_drv.raw_data[1] & 0xf) << 8);
50 int ty = ft_drv.raw_data[4] | ((ft_drv.raw_data[3] & 0xf) << 8);
51
52 ft6x06_state.event = evt;
53#ifdef FT6x06_SWAP_AXES
54 ft6x06_state.pos_x = ty;
55 ft6x06_state.pos_y = tx;
56#else
57 ft6x06_state.pos_x = tx;
58 ft6x06_state.pos_y = ty;
59#endif
60
61 ft_drv.event_cb(evt, ft6x06_state.pos_x, ft6x06_state.pos_y);
62}
63
64static void ft6x06_dummy_event_cb(int evt, int tx, int ty)
65{
66 (void)evt;
67 (void)tx;
68 (void)ty;
69}
70
71void ft6x06_init(void)
72{
73 /* Initialize stuff */
74 memset(&ft_drv, 0, sizeof(ft_drv));
75 ft_drv.event_cb = ft6x06_dummy_event_cb;
76
77 ft6x06_state.event = FT6x06_EVT_NONE;
78 ft6x06_state.pos_x = 0;
79 ft6x06_state.pos_y = 0;
80
81 /* Reserve bus management cookie */
82 ft_drv.i2c_cookie = i2c_async_reserve_cookies(FT6x06_BUS, 1);
83
84 /* Prep an I2C descriptor to read touch data */
85 ft_drv.i2c_desc.slave_addr = FT6x06_ADDR;
86 ft_drv.i2c_desc.bus_cond = I2C_START | I2C_STOP;
87 ft_drv.i2c_desc.tran_mode = I2C_READ;
88 ft_drv.i2c_desc.buffer[0] = &ft_drv.raw_data[5];
89 ft_drv.i2c_desc.count[0] = 1;
90 ft_drv.i2c_desc.buffer[1] = &ft_drv.raw_data[0];
91 ft_drv.i2c_desc.count[1] = 5;
92 ft_drv.i2c_desc.callback = ft6x06_i2c_callback;
93 ft_drv.i2c_desc.arg = 0;
94 ft_drv.i2c_desc.next = NULL;
95
96 /* Set I2C register address */
97 ft_drv.raw_data[5] = 0x02;
98}
99
100void ft6x06_set_event_cb(ft6x06_event_cb cb)
101{
102 ft_drv.event_cb = cb ? cb : ft6x06_dummy_event_cb;
103}
104
105void ft6x06_enable(bool en)
106{
107 i2c_reg_write1(FT6x06_BUS, FT6x06_ADDR, 0xa5, en ? 0 : 3);
108}
109
110void ft6x06_irq_handler(void)
111{
112 /* We don't care if this fails, there's not much we can do about it */
113 i2c_async_queue(FT6x06_BUS, TIMEOUT_NOBLOCK, I2C_Q_ONCE,
114 ft_drv.i2c_cookie, &ft_drv.i2c_desc);
115}
diff --git a/firmware/export/config/fiiom3k.h b/firmware/export/config/fiiom3k.h
index a28efd43a5..849aa9c0a6 100644
--- a/firmware/export/config/fiiom3k.h
+++ b/firmware/export/config/fiiom3k.h
@@ -22,6 +22,8 @@
22 22
23/* Drivers */ 23/* Drivers */
24#define HAVE_I2C_ASYNC 24#define HAVE_I2C_ASYNC
25#define HAVE_FT6x06
26#define FT6x06_SWAP_AXES
25 27
26/* Buffer for plugins and codecs. */ 28/* Buffer for plugins and codecs. */
27#define PLUGIN_BUFFER_SIZE 0x200000 /* 2 MiB */ 29#define PLUGIN_BUFFER_SIZE 0x200000 /* 2 MiB */
diff --git a/firmware/export/ft6x06.h b/firmware/export/ft6x06.h
new file mode 100644
index 0000000000..de1fdd0979
--- /dev/null
+++ b/firmware/export/ft6x06.h
@@ -0,0 +1,50 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef __FT6x06_H__
23#define __FT6x06_H__
24
25#include "config.h"
26#include <stdbool.h>
27
28typedef void(*ft6x06_event_cb)(int, int, int);
29
30struct ft6x06_state {
31 int event;
32 int pos_x;
33 int pos_y;
34};
35
36enum ft6x06_event {
37 FT6x06_EVT_NONE = -1,
38 FT6x06_EVT_PRESS = 0,
39 FT6x06_EVT_RELEASE = 1,
40 FT6x06_EVT_CONTACT = 2,
41};
42
43extern struct ft6x06_state ft6x06_state;
44
45void ft6x06_init(void);
46void ft6x06_set_event_cb(ft6x06_event_cb fn);
47void ft6x06_enable(bool en);
48void ft6x06_irq_handler(void);
49
50#endif /* __FT6x06_H__ */
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c
index 4a853cd88f..4354257f7b 100644
--- a/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c
@@ -25,7 +25,9 @@
25#include "powermgmt.h" 25#include "powermgmt.h"
26#include "panic.h" 26#include "panic.h"
27#include "axp-pmu.h" 27#include "axp-pmu.h"
28#include "ft6x06.h"
28#include "gpio-x1000.h" 29#include "gpio-x1000.h"
30#include "irq-x1000.h"
29#include "i2c-x1000.h" 31#include "i2c-x1000.h"
30#include <string.h> 32#include <string.h>
31#include <stdbool.h> 33#include <stdbool.h>
@@ -35,12 +37,6 @@
35# include "font.h" 37# include "font.h"
36#endif 38#endif
37 39
38/* Touch event types */
39#define EVENT_NONE (-1)
40#define EVENT_PRESS 0
41#define EVENT_RELEASE 1
42#define EVENT_CONTACT 2
43
44/* FSM states */ 40/* FSM states */
45#define STATE_IDLE 0 41#define STATE_IDLE 0
46#define STATE_PRESS 1 42#define STATE_PRESS 1
@@ -66,17 +62,6 @@
66/* Number of touch samples to smooth before reading */ 62/* Number of touch samples to smooth before reading */
67#define TOUCH_SAMPLES 3 63#define TOUCH_SAMPLES 3
68 64
69static struct ft_driver {
70 int i2c_cookie;
71 i2c_descriptor i2c_desc;
72 uint8_t raw_data[6];
73 bool active;
74
75 /* Number of pixels squared which must be moved before
76 * a scrollbar pulse is generated */
77 int scroll_thresh_sqr;
78} ftd;
79
80static struct ft_state_machine { 65static struct ft_state_machine {
81 /* Current button state, used by button_read_device() */ 66 /* Current button state, used by button_read_device() */
82 int buttons; 67 int buttons;
@@ -105,6 +90,12 @@ static struct ft_state_machine {
105 90
106 /* Current touch position */ 91 /* Current touch position */
107 int cur_x, cur_y; 92 int cur_x, cur_y;
93
94 /* Motion threshold squared, in 'pixels', required to trigger scrolling */
95 int scroll_thresh_sqr;
96
97 /* Touchpad enabled state */
98 bool active;
108} fsm; 99} fsm;
109 100
110/* coordinates below this are the left hand buttons, 101/* coordinates below this are the left hand buttons,
@@ -210,9 +201,9 @@ static void ft_start_report_or_scroll(void)
210static void ft_step_state(uint32_t t, int evt, int tx, int ty) 201static void ft_step_state(uint32_t t, int evt, int tx, int ty)
211{ 202{
212 /* Generate a release event automatically in case we missed it */ 203 /* Generate a release event automatically in case we missed it */
213 if(evt == EVENT_NONE) { 204 if(evt == FT6x06_EVT_NONE) {
214 if(TICKS_SINCE(t, fsm.last_event_t) >= AUTORELEASE_TIME) { 205 if(TICKS_SINCE(t, fsm.last_event_t) >= AUTORELEASE_TIME) {
215 evt = EVENT_RELEASE; 206 evt = FT6x06_EVT_RELEASE;
216 tx = fsm.cur_x; 207 tx = fsm.cur_x;
217 ty = fsm.cur_y; 208 ty = fsm.cur_y;
218 } 209 }
@@ -220,7 +211,7 @@ static void ft_step_state(uint32_t t, int evt, int tx, int ty)
220 211
221 switch(fsm.state) { 212 switch(fsm.state) {
222 case STATE_IDLE: { 213 case STATE_IDLE: {
223 if(evt == EVENT_PRESS || evt == EVENT_CONTACT) { 214 if(evt == FT6x06_EVT_PRESS || evt == FT6x06_EVT_CONTACT) {
224 /* Move to REPORT or PRESS state */ 215 /* Move to REPORT or PRESS state */
225 if(ft_accum_touch(t, tx, ty)) 216 if(ft_accum_touch(t, tx, ty))
226 ft_start_report_or_scroll(); 217 ft_start_report_or_scroll();
@@ -230,10 +221,10 @@ static void ft_step_state(uint32_t t, int evt, int tx, int ty)
230 } break; 221 } break;
231 222
232 case STATE_PRESS: { 223 case STATE_PRESS: {
233 if(evt == EVENT_RELEASE) { 224 if(evt == FT6x06_EVT_RELEASE) {
234 /* Ignore if the number of samples is too low */ 225 /* Ignore if the number of samples is too low */
235 ft_go_idle(); 226 ft_go_idle();
236 } else if(evt == EVENT_PRESS || evt == EVENT_CONTACT) { 227 } else if(evt == FT6x06_EVT_PRESS || evt == FT6x06_EVT_CONTACT) {
237 /* Accumulate the touch position in the filter */ 228 /* Accumulate the touch position in the filter */
238 if(ft_accum_touch(t, tx, ty)) 229 if(ft_accum_touch(t, tx, ty))
239 ft_start_report_or_scroll(); 230 ft_start_report_or_scroll();
@@ -241,14 +232,14 @@ static void ft_step_state(uint32_t t, int evt, int tx, int ty)
241 } break; 232 } break;
242 233
243 case STATE_REPORT: { 234 case STATE_REPORT: {
244 if(evt == EVENT_RELEASE) 235 if(evt == FT6x06_EVT_RELEASE)
245 ft_go_idle(); 236 ft_go_idle();
246 else if(evt == EVENT_PRESS || evt == EVENT_CONTACT) 237 else if(evt == FT6x06_EVT_PRESS || evt == FT6x06_EVT_CONTACT)
247 ft_accum_touch(t, tx, ty); 238 ft_accum_touch(t, tx, ty);
248 } break; 239 } break;
249 240
250 case STATE_SCROLL_PRESS: { 241 case STATE_SCROLL_PRESS: {
251 if(evt == EVENT_RELEASE) { 242 if(evt == FT6x06_EVT_RELEASE) {
252 /* This _should_ synthesize a button press. 243 /* This _should_ synthesize a button press.
253 * 244 *
254 * - ft_start_report() will set the button bit based on the 245 * - ft_start_report() will set the button bit based on the
@@ -257,10 +248,10 @@ static void ft_step_state(uint32_t t, int evt, int tx, int ty)
257 * 248 *
258 * - The next button_read_device() will see the button bit 249 * - The next button_read_device() will see the button bit
259 * and report it back to Rockbox, then step the FSM with 250 * and report it back to Rockbox, then step the FSM with
260 * EVENT_NONE. 251 * FT6x06_EVT_NONE.
261 * 252 *
262 * - The EVENT_NONE stepping will eventually autogenerate a 253 * - The FT6x06_EVT_NONE stepping will eventually autogenerate
263 * RELEASE event and restore the button state back to 0 254 * a RELEASE event and restore the button state back to 0
264 * 255 *
265 * - There's a small logic hole in the REPORT state which 256 * - There's a small logic hole in the REPORT state which
266 * could cause it to miss an immediately repeated PRESS 257 * could cause it to miss an immediately repeated PRESS
@@ -271,7 +262,7 @@ static void ft_step_state(uint32_t t, int evt, int tx, int ty)
271 break; 262 break;
272 } 263 }
273 264
274 if(evt == EVENT_PRESS || evt == EVENT_CONTACT) 265 if(evt == FT6x06_EVT_PRESS || evt == FT6x06_EVT_CONTACT)
275 ft_accum_touch(t, tx, ty); 266 ft_accum_touch(t, tx, ty);
276 267
277 int dx = fsm.cur_x - fsm.orig_x; 268 int dx = fsm.cur_x - fsm.orig_x;
@@ -289,21 +280,21 @@ static void ft_step_state(uint32_t t, int evt, int tx, int ty)
289 } break; 280 } break;
290 281
291 case STATE_SCROLLING: { 282 case STATE_SCROLLING: {
292 if(evt == EVENT_RELEASE) { 283 if(evt == FT6x06_EVT_RELEASE) {
293 ft_go_idle(); 284 ft_go_idle();
294 break; 285 break;
295 } 286 }
296 287
297 if(evt == EVENT_PRESS || evt == EVENT_CONTACT) 288 if(evt == FT6x06_EVT_PRESS || evt == FT6x06_EVT_CONTACT)
298 ft_accum_touch(t, tx, ty); 289 ft_accum_touch(t, tx, ty);
299 290
300 int dx = fsm.cur_x - fsm.orig_x; 291 int dx = fsm.cur_x - fsm.orig_x;
301 int dy = fsm.cur_y - fsm.orig_y; 292 int dy = fsm.cur_y - fsm.orig_y;
302 int dp = (dx*dx) + (dy*dy); 293 int dp = (dx*dx) + (dy*dy);
303 if(dp >= ftd.scroll_thresh_sqr) { 294 if(dp >= fsm.scroll_thresh_sqr) {
304 /* avoid generating events if we're supposed to be inactive... 295 /* avoid generating events if we're supposed to be inactive...
305 * should not be necessary but better to be safe. */ 296 * should not be necessary but better to be safe. */
306 if(ftd.active) { 297 if(fsm.active) {
307 if(dy < 0) { 298 if(dy < 0) {
308 queue_post(&button_queue, BUTTON_SCROLL_BACK, 0); 299 queue_post(&button_queue, BUTTON_SCROLL_BACK, 0);
309 } else { 300 } else {
@@ -327,18 +318,8 @@ static void ft_step_state(uint32_t t, int evt, int tx, int ty)
327 } 318 }
328} 319}
329 320
330static void ft_i2c_callback(int status, i2c_descriptor* desc) 321static void ft_event_cb(int evt, int tx, int ty)
331{ 322{
332 (void)desc;
333 if(status != I2C_STATUS_OK)
334 return;
335
336 /* The panel is oriented such that its X axis is vertical,
337 * so swap the axes for reporting */
338 int evt = ftd.raw_data[1] >> 6;
339 int ty = ftd.raw_data[2] | ((ftd.raw_data[1] & 0xf) << 8);
340 int tx = ftd.raw_data[4] | ((ftd.raw_data[3] & 0xf) << 8);
341
342 /* TODO: convert the touch positions to linear positions. 323 /* TODO: convert the touch positions to linear positions.
343 * 324 *
344 * Points reported by the touch controller are distorted and non-linear, 325 * Points reported by the touch controller are distorted and non-linear,
@@ -346,36 +327,11 @@ static void ft_i2c_callback(int status, i2c_descriptor* desc)
346 * the middle of the touchpad than on the edges, so scrolling feels slow 327 * the middle of the touchpad than on the edges, so scrolling feels slow
347 * in the middle and faster near the edge. 328 * in the middle and faster near the edge.
348 */ 329 */
349
350 ft_step_state(__ost_read32(), evt, tx, ty); 330 ft_step_state(__ost_read32(), evt, tx, ty);
351} 331}
352 332
353/* ft6x06 interrupt pin */
354void GPIOB12(void)
355{
356 /* We don't care if this fails */
357 i2c_async_queue(FT6x06_BUS, TIMEOUT_NOBLOCK, I2C_Q_ONCE,
358 ftd.i2c_cookie, &ftd.i2c_desc);
359}
360
361static void ft_init(void) 333static void ft_init(void)
362{ 334{
363 /* Initialize the driver state */
364 ftd.i2c_cookie = i2c_async_reserve_cookies(FT6x06_BUS, 1);
365 ftd.i2c_desc.slave_addr = FT6x06_ADDR;
366 ftd.i2c_desc.bus_cond = I2C_START | I2C_STOP;
367 ftd.i2c_desc.tran_mode = I2C_READ;
368 ftd.i2c_desc.buffer[0] = &ftd.raw_data[5];
369 ftd.i2c_desc.count[0] = 1;
370 ftd.i2c_desc.buffer[1] = &ftd.raw_data[0];
371 ftd.i2c_desc.count[1] = 5;
372 ftd.i2c_desc.callback = ft_i2c_callback;
373 ftd.i2c_desc.arg = 0;
374 ftd.i2c_desc.next = NULL;
375 ftd.raw_data[5] = 0x02;
376 ftd.active = true;
377 touchpad_set_sensitivity(DEFAULT_TOUCHPAD_SENSITIVITY_SETTING);
378
379 /* Initialize the state machine */ 335 /* Initialize the state machine */
380 fsm.buttons = 0; 336 fsm.buttons = 0;
381 fsm.state = STATE_IDLE; 337 fsm.state = STATE_IDLE;
@@ -385,16 +341,24 @@ static void ft_init(void)
385 fsm.sum_x = fsm.sum_y = 0; 341 fsm.sum_x = fsm.sum_y = 0;
386 fsm.orig_x = fsm.orig_y = 0; 342 fsm.orig_x = fsm.orig_y = 0;
387 fsm.cur_x = fsm.cur_y = 0; 343 fsm.cur_x = fsm.cur_y = 0;
344 fsm.active = true;
345 touchpad_set_sensitivity(DEFAULT_TOUCHPAD_SENSITIVITY_SETTING);
388 346
389 /* Bring up I2C bus */ 347 /* Bring up I2C bus */
390 i2c_x1000_set_freq(FT6x06_BUS, I2C_FREQ_400K); 348 i2c_x1000_set_freq(FT6x06_BUS, I2C_FREQ_400K);
391 349
350 /* Driver init */
351 ft6x06_init();
352 ft6x06_set_event_cb(ft_event_cb);
353
392 /* Reset chip */ 354 /* Reset chip */
393 gpio_set_level(GPIO_FT6x06_RESET, 0); 355 gpio_set_level(GPIO_FT6x06_RESET, 0);
394 mdelay(5); 356 mdelay(5);
395 gpio_set_level(GPIO_FT6x06_RESET, 1); 357 gpio_set_level(GPIO_FT6x06_RESET, 1);
396 358
397 /* Configure the interrupt pin */ 359 /* Configure the interrupt pin */
360 system_set_irq_handler(GPIO_TO_IRQ(GPIO_FT6x06_INTERRUPT),
361 ft6x06_irq_handler);
398 gpio_set_function(GPIO_FT6x06_INTERRUPT, GPIOF_IRQ_EDGE(0)); 362 gpio_set_function(GPIO_FT6x06_INTERRUPT, GPIOF_IRQ_EDGE(0));
399 gpio_enable_irq(GPIO_FT6x06_INTERRUPT); 363 gpio_enable_irq(GPIO_FT6x06_INTERRUPT);
400} 364}
@@ -403,13 +367,13 @@ void touchpad_set_sensitivity(int level)
403{ 367{
404 int pixels = 40; 368 int pixels = 40;
405 pixels -= level; 369 pixels -= level;
406 ftd.scroll_thresh_sqr = pixels * pixels; 370 fsm.scroll_thresh_sqr = pixels * pixels;
407} 371}
408 372
409void touchpad_enable_device(bool en) 373void touchpad_enable_device(bool en)
410{ 374{
411 i2c_reg_write1(FT6x06_BUS, FT6x06_ADDR, 0xa5, en ? 0 : 3); 375 ft6x06_enable(en);
412 ftd.active = en; 376 fsm.active = en;
413} 377}
414 378
415/* Value of headphone detect register */ 379/* Value of headphone detect register */
@@ -467,7 +431,7 @@ void button_init_device(void)
467int button_read_device(void) 431int button_read_device(void)
468{ 432{
469 int r = fsm.buttons; 433 int r = fsm.buttons;
470 ft_step_state(__ost_read32(), EVENT_NONE, 0, 0); 434 ft_step_state(__ost_read32(), FT6x06_EVT_NONE, 0, 0);
471 435
472 /* Read GPIOs for physical buttons */ 436 /* Read GPIOs for physical buttons */
473 uint32_t a = REG_GPIO_PIN(GPIO_A); 437 uint32_t a = REG_GPIO_PIN(GPIO_A);