diff options
-rw-r--r-- | firmware/SOURCES | 7 | ||||
-rw-r--r-- | firmware/drivers/ft6x06.c | 115 | ||||
-rw-r--r-- | firmware/export/config/fiiom3k.h | 2 | ||||
-rw-r--r-- | firmware/export/ft6x06.h | 50 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c | 110 |
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 | |||
1928 | drivers/touchpad.c | 1928 | drivers/touchpad.c |
1929 | #endif | 1929 | #endif |
1930 | 1930 | ||
1931 | /* Hardware drivers */ | ||
1932 | #ifndef SIMULATOR | ||
1931 | #ifdef HAVE_I2C_ASYNC | 1933 | #ifdef HAVE_I2C_ASYNC |
1932 | drivers/i2c-async.c | 1934 | drivers/i2c-async.c |
1933 | #endif | 1935 | #endif |
1934 | |||
1935 | #ifdef HAVE_AXP_PMU | 1936 | #ifdef HAVE_AXP_PMU |
1936 | drivers/axp-pmu.c | 1937 | drivers/axp-pmu.c |
1937 | #endif | 1938 | #endif |
1939 | #ifdef HAVE_FT6x06 | ||
1940 | drivers/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 | |||
27 | struct 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 | |||
39 | static struct ft6x06_driver ft_drv; | ||
40 | struct ft6x06_state ft6x06_state; | ||
41 | |||
42 | static 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 | |||
64 | static void ft6x06_dummy_event_cb(int evt, int tx, int ty) | ||
65 | { | ||
66 | (void)evt; | ||
67 | (void)tx; | ||
68 | (void)ty; | ||
69 | } | ||
70 | |||
71 | void 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 | |||
100 | void ft6x06_set_event_cb(ft6x06_event_cb cb) | ||
101 | { | ||
102 | ft_drv.event_cb = cb ? cb : ft6x06_dummy_event_cb; | ||
103 | } | ||
104 | |||
105 | void ft6x06_enable(bool en) | ||
106 | { | ||
107 | i2c_reg_write1(FT6x06_BUS, FT6x06_ADDR, 0xa5, en ? 0 : 3); | ||
108 | } | ||
109 | |||
110 | void 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 | |||
28 | typedef void(*ft6x06_event_cb)(int, int, int); | ||
29 | |||
30 | struct ft6x06_state { | ||
31 | int event; | ||
32 | int pos_x; | ||
33 | int pos_y; | ||
34 | }; | ||
35 | |||
36 | enum ft6x06_event { | ||
37 | FT6x06_EVT_NONE = -1, | ||
38 | FT6x06_EVT_PRESS = 0, | ||
39 | FT6x06_EVT_RELEASE = 1, | ||
40 | FT6x06_EVT_CONTACT = 2, | ||
41 | }; | ||
42 | |||
43 | extern struct ft6x06_state ft6x06_state; | ||
44 | |||
45 | void ft6x06_init(void); | ||
46 | void ft6x06_set_event_cb(ft6x06_event_cb fn); | ||
47 | void ft6x06_enable(bool en); | ||
48 | void 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 | ||
69 | static 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 | |||
80 | static struct ft_state_machine { | 65 | static 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) | |||
210 | static void ft_step_state(uint32_t t, int evt, int tx, int ty) | 201 | static 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 | ||
330 | static void ft_i2c_callback(int status, i2c_descriptor* desc) | 321 | static 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 */ | ||
354 | void 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 | |||
361 | static void ft_init(void) | 333 | static 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 | ||
409 | void touchpad_enable_device(bool en) | 373 | void 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) | |||
467 | int button_read_device(void) | 431 | int 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); |