summaryrefslogtreecommitdiff
path: root/firmware/drivers/ft6x06.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/ft6x06.c')
-rw-r--r--firmware/drivers/ft6x06.c115
1 files changed, 115 insertions, 0 deletions
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}