diff options
Diffstat (limited to 'firmware/drivers/ft6x06.c')
-rw-r--r-- | firmware/drivers/ft6x06.c | 115 |
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 | |||
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 | } | ||