1 /*
2 * Copyright (c) 2020 NXP
3 * Copyright (c) 2020 Mark Olsson <mark@markolsson.se>
4 * Copyright (c) 2020 Teslabs Engineering S.L.
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #define DT_DRV_COMPAT goodix_gt911
10
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/drivers/i2c.h>
13 #include <zephyr/input/input.h>
14 #include <zephyr/sys/byteorder.h>
15
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(gt911, CONFIG_INPUT_LOG_LEVEL);
18
19 /* GT911 used registers */
20 #define DEVICE_ID BSWAP_16(0x8140U)
21 #define REG_STATUS BSWAP_16(0x814EU)
22
23 /* REG_TD_STATUS: Touch points. */
24 #define TOUCH_POINTS_MSK 0x0FU
25
26 /* REG_TD_STATUS: Pressed. */
27 #define TOUCH_STATUS_MSK (1 << 7U)
28
29 /* The GT911's config */
30 #define REG_GT911_CONFIG BSWAP_16(0x8047U)
31 #define REG_CONFIG_VERSION REG_GT911_CONFIG
32 #define REG_CONFIG_TOUCH_NUM_OFFSET 0x5
33 #define REG_CONFIG_SIZE 186U
34 #define GT911_PRODUCT_ID 0x00313139U
35
36 /* Points registers */
37 #define REG_POINT_0 0x814F
38 #define POINT_OFFSET 0x8
39 #define REG_POINT_ADDR(n) BSWAP_16(REG_POINT_0 + POINT_OFFSET * n)
40
41 /** GT911 configuration (DT). */
42 struct gt911_config {
43 /** I2C bus. */
44 struct i2c_dt_spec bus;
45 struct gpio_dt_spec rst_gpio;
46 /** Interrupt GPIO information. */
47 struct gpio_dt_spec int_gpio;
48 /* Alternate fallback I2C address */
49 uint8_t alt_addr;
50 };
51
52 /** GT911 data. */
53 struct gt911_data {
54 /** Device pointer. */
55 const struct device *dev;
56 /** Work queue (for deferred read). */
57 struct k_work work;
58 /** Actual device I2C address */
59 uint8_t actual_address;
60 #ifdef CONFIG_INPUT_GT911_INTERRUPT
61 /** Interrupt GPIO callback. */
62 struct gpio_callback int_gpio_cb;
63 #else
64 /** Timer (polling mode). */
65 struct k_timer timer;
66 #endif
67 };
68
69 /** gt911 point reg */
70 struct gt911_point_reg {
71 uint8_t id; /*!< Track ID. */
72 uint8_t low_x; /*!< Low byte of x coordinate. */
73 uint8_t high_x; /*!< High byte of x coordinate. */
74 uint8_t low_y; /*!< Low byte of y coordinate. */
75 uint8_t high_y; /*!< High byte of x coordinate. */
76 uint8_t low_size; /*!< Low byte of point size. */
77 uint8_t high_size; /*!< High byte of point size. */
78 uint8_t reserved; /*!< Reserved. */
79 };
80
81 /*
82 * Device-specific wrappers around i2c_write_dt and i2c_write_read_dt.
83 * These wrappers handle the case where the GT911 did not accept the requested
84 * I2C address, and the alternate I2C address is used.
85 */
gt911_i2c_write(const struct device * dev,const uint8_t * buf,uint32_t num_bytes)86 static int gt911_i2c_write(const struct device *dev, const uint8_t *buf, uint32_t num_bytes)
87 {
88 const struct gt911_config *config = dev->config;
89 struct gt911_data *data = dev->data;
90
91 return i2c_write(config->bus.bus, buf, num_bytes, data->actual_address);
92 }
93
gt911_i2c_write_read(const struct device * dev,const void * write_buf,size_t num_write,void * read_buf,size_t num_read)94 static int gt911_i2c_write_read(const struct device *dev, const void *write_buf, size_t num_write,
95 void *read_buf, size_t num_read)
96 {
97 const struct gt911_config *config = dev->config;
98 struct gt911_data *data = dev->data;
99
100 return i2c_write_read(config->bus.bus, data->actual_address, write_buf, num_write, read_buf,
101 num_read);
102 }
103
gt911_process(const struct device * dev)104 static int gt911_process(const struct device *dev)
105 {
106 int r;
107 uint16_t reg_addr;
108 uint8_t status;
109 uint8_t i;
110 uint8_t j;
111 uint16_t row;
112 uint16_t col;
113 uint8_t points;
114 static uint8_t prev_points;
115 struct gt911_point_reg point_reg[CONFIG_INPUT_GT911_MAX_TOUCH_POINTS];
116 static struct gt911_point_reg prev_point_reg[CONFIG_INPUT_GT911_MAX_TOUCH_POINTS];
117
118 /* obtain number of touch points */
119 reg_addr = REG_STATUS;
120 r = gt911_i2c_write_read(dev, ®_addr, sizeof(reg_addr), &status, sizeof(status));
121 if (r < 0) {
122 return r;
123 }
124
125 if (!(status & TOUCH_STATUS_MSK)) {
126 /* Status bit not set, ignore this event */
127 return 0;
128 }
129
130 /*
131 * Note- since we program the max number of touch inputs during init,
132 * the controller won't report more than the maximum number of touch
133 * points we are configured to support
134 */
135 points = status & TOUCH_POINTS_MSK;
136
137 /* need to clear the status */
138 uint8_t clear_buffer[3] = {(uint8_t)REG_STATUS, (uint8_t)(REG_STATUS >> 8), 0};
139
140 r = gt911_i2c_write(dev, clear_buffer, sizeof(clear_buffer));
141 if (r < 0) {
142 return r;
143 }
144
145 /* current points array */
146 for (i = 0; i < points; i++) {
147 reg_addr = REG_POINT_ADDR(i);
148 r = gt911_i2c_write_read(dev, ®_addr, sizeof(reg_addr), &point_reg[i],
149 sizeof(point_reg[i]));
150
151 if (r < 0) {
152 return r;
153 }
154 }
155
156 /* touch events */
157 for (i = 0; i < points; i++) {
158 if (CONFIG_INPUT_GT911_MAX_TOUCH_POINTS > 1) {
159 input_report_abs(dev, INPUT_ABS_MT_SLOT, point_reg[i].id, true, K_FOREVER);
160 }
161
162 row = ((point_reg[i].high_y) << 8U) | point_reg[i].low_y;
163 col = ((point_reg[i].high_x) << 8U) | point_reg[i].low_x;
164
165 input_report_abs(dev, INPUT_ABS_X, col, false, K_FOREVER);
166 input_report_abs(dev, INPUT_ABS_Y, row, false, K_FOREVER);
167 input_report_key(dev, INPUT_BTN_TOUCH, 1, true, K_FOREVER);
168 }
169
170 /* release events */
171 for (i = 0; i < prev_points; i++) {
172 /* We look for the prev_point in the current points list */
173 for (j = 0; j < points; j++) {
174 if (prev_point_reg[i].id == point_reg[j].id) {
175 break;
176 }
177 }
178
179 if (j == points) {
180 if (CONFIG_INPUT_GT911_MAX_TOUCH_POINTS > 1) {
181 input_report_abs(dev, INPUT_ABS_MT_SLOT, prev_point_reg[i].id, true,
182 K_FOREVER);
183 }
184 row = ((prev_point_reg[i].high_y) << 8U) | prev_point_reg[i].low_y;
185 col = ((prev_point_reg[i].high_x) << 8U) | prev_point_reg[i].low_x;
186 input_report_abs(dev, INPUT_ABS_X, col, false, K_FOREVER);
187 input_report_abs(dev, INPUT_ABS_Y, row, false, K_FOREVER);
188 input_report_key(dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER);
189 }
190 }
191
192 memcpy(prev_point_reg, point_reg, sizeof(point_reg));
193 prev_points = points;
194
195 return 0;
196 }
197
gt911_work_handler(struct k_work * work)198 static void gt911_work_handler(struct k_work *work)
199 {
200 struct gt911_data *data = CONTAINER_OF(work, struct gt911_data, work);
201
202 gt911_process(data->dev);
203 }
204
205 #ifdef CONFIG_INPUT_GT911_INTERRUPT
gt911_isr_handler(const struct device * dev,struct gpio_callback * cb,uint32_t pins)206 static void gt911_isr_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
207 {
208 struct gt911_data *data = CONTAINER_OF(cb, struct gt911_data, int_gpio_cb);
209
210 k_work_submit(&data->work);
211 }
212 #else
gt911_timer_handler(struct k_timer * timer)213 static void gt911_timer_handler(struct k_timer *timer)
214 {
215 struct gt911_data *data = CONTAINER_OF(timer, struct gt911_data, timer);
216
217 k_work_submit(&data->work);
218 }
219 #endif
220
gt911_get_firmware_checksum(const uint8_t * firmware)221 static uint8_t gt911_get_firmware_checksum(const uint8_t *firmware)
222 {
223 uint8_t sum = 0;
224 uint16_t i = 0;
225
226 for (i = 0; i < REG_CONFIG_SIZE - 2U; i++) {
227 sum += (*firmware);
228 firmware++;
229 }
230
231 return (~sum + 1U);
232 }
233
gt911_verify_firmware(const uint8_t * firmware)234 static bool gt911_verify_firmware(const uint8_t *firmware)
235 {
236 return ((firmware[REG_CONFIG_VERSION - REG_GT911_CONFIG] != 0U) &&
237 (gt911_get_firmware_checksum(firmware) == firmware[REG_CONFIG_SIZE - 2U]));
238 }
239
gt911_init(const struct device * dev)240 static int gt911_init(const struct device *dev)
241 {
242 const struct gt911_config *config = dev->config;
243 struct gt911_data *data = dev->data;
244
245 if (!i2c_is_ready_dt(&config->bus)) {
246 LOG_ERR("I2C controller device not ready");
247 return -ENODEV;
248 }
249
250 data->dev = dev;
251 data->actual_address = config->bus.addr;
252
253 k_work_init(&data->work, gt911_work_handler);
254
255 int r;
256
257 if (!gpio_is_ready_dt(&config->int_gpio)) {
258 LOG_ERR("Interrupt GPIO controller device not ready");
259 return -ENODEV;
260 }
261
262 if (config->rst_gpio.port != NULL) {
263 if (!gpio_is_ready_dt(&config->rst_gpio)) {
264 LOG_ERR("Reset GPIO controller device not ready");
265 return -ENODEV;
266 }
267
268 r = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_ACTIVE);
269 if (r < 0) {
270 LOG_ERR("Could not configure reset GPIO pin");
271 return r;
272 }
273 }
274
275 /*
276 * We need to configure the int-pin to 0, in order to enter the
277 * AddressMode0. Keeping the INT pin low during the reset sequence
278 * should result in the device selecting an I2C address of 0x5D.
279 * Note that if an alternate I2C address is set, we will probe
280 * for the alternate address if 0x5D does not work. This is useful
281 * for boards that do not route the INT pin, or only permit it
282 * to be used as an input
283 */
284 r = gpio_pin_configure_dt(&config->int_gpio, GPIO_OUTPUT_INACTIVE);
285 if (r < 0) {
286 LOG_ERR("Could not configure int GPIO pin");
287 return r;
288 }
289 /* Delay at least 10 ms after power on before we configure gt911 */
290 k_sleep(K_MSEC(20));
291 if (config->rst_gpio.port != NULL) {
292 /* reset the device and confgiure the addr mode0 */
293 gpio_pin_set_dt(&config->rst_gpio, 1);
294 /* hold down at least 1us, 1ms here */
295 k_sleep(K_MSEC(1));
296 gpio_pin_set_dt(&config->rst_gpio, 0);
297 /* hold down at least 5ms. This is the point the INT pin must be low. */
298 k_sleep(K_MSEC(5));
299 }
300 /* hold down 50ms to make sure the address available */
301 k_sleep(K_MSEC(50));
302
303 r = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT);
304 if (r < 0) {
305 LOG_ERR("Could not configure interrupt GPIO pin");
306 return r;
307 }
308
309 #ifdef CONFIG_INPUT_GT911_INTERRUPT
310 r = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE);
311 if (r < 0) {
312 LOG_ERR("Could not configure interrupt GPIO interrupt.");
313 return r;
314 }
315
316 gpio_init_callback(&data->int_gpio_cb, gt911_isr_handler, BIT(config->int_gpio.pin));
317 #else
318 k_timer_init(&data->timer, gt911_timer_handler, NULL);
319 #endif
320
321 /* check the Device ID first: '911' */
322 uint32_t reg_id = 0;
323 uint16_t reg_addr = DEVICE_ID;
324
325 if (config->alt_addr != 0x0) {
326 /*
327 * The level of the INT pin during reset is used by the GT911
328 * to select the I2C address mode. If an alternate I2C address
329 * is set, we should probe the GT911 to determine which address
330 * it actually selected. This is useful for boards that do not
331 * route the INT pin, or can only read it as an input (IE when
332 * using a level shifter).
333 */
334 r = gt911_i2c_write_read(dev, ®_addr, sizeof(reg_addr), ®_id, sizeof(reg_id));
335 if (r < 0) {
336 /* Try alternate address */
337 data->actual_address = config->alt_addr;
338 r = gt911_i2c_write_read(dev, ®_addr, sizeof(reg_addr), ®_id,
339 sizeof(reg_id));
340 LOG_INF("Device did not accept I2C address, "
341 "updated to 0x%02X",
342 data->actual_address);
343 }
344 } else {
345 r = gt911_i2c_write_read(dev, ®_addr, sizeof(reg_addr), ®_id, sizeof(reg_id));
346 }
347 if (r < 0) {
348 LOG_ERR("Device did not respond to I2C request");
349 return r;
350 }
351 if (reg_id != GT911_PRODUCT_ID) {
352 LOG_ERR("The Device ID is not correct");
353 return -ENODEV;
354 }
355
356 /* need to setup the firmware first: read and write */
357 uint8_t gt911_config_firmware[REG_CONFIG_SIZE + 2] = {(uint8_t)REG_GT911_CONFIG,
358 (uint8_t)(REG_GT911_CONFIG >> 8)};
359
360 reg_addr = REG_GT911_CONFIG;
361 r = gt911_i2c_write_read(dev, ®_addr, sizeof(reg_addr), gt911_config_firmware + 2,
362 REG_CONFIG_SIZE);
363 if (r < 0) {
364 return r;
365 }
366 if (!gt911_verify_firmware(gt911_config_firmware + 2)) {
367 return -ENODEV;
368 }
369
370 gt911_config_firmware[REG_CONFIG_TOUCH_NUM_OFFSET + 2] =
371 CONFIG_INPUT_GT911_MAX_TOUCH_POINTS;
372
373 gt911_config_firmware[REG_CONFIG_SIZE] =
374 gt911_get_firmware_checksum(gt911_config_firmware + 2);
375 gt911_config_firmware[REG_CONFIG_SIZE + 1] = 1;
376
377 r = gt911_i2c_write(dev, gt911_config_firmware, sizeof(gt911_config_firmware));
378 if (r < 0) {
379 return r;
380 }
381
382 #ifdef CONFIG_INPUT_GT911_INTERRUPT
383 r = gpio_add_callback(config->int_gpio.port, &data->int_gpio_cb);
384 if (r < 0) {
385 LOG_ERR("Could not set gpio callback");
386 return r;
387 }
388 #else
389 k_timer_start(&data->timer, K_MSEC(CONFIG_INPUT_GT911_PERIOD_MS),
390 K_MSEC(CONFIG_INPUT_GT911_PERIOD_MS));
391 #endif
392
393 return 0;
394 }
395
396 #define GT911_INIT(index) \
397 static const struct gt911_config gt911_config_##index = { \
398 .bus = I2C_DT_SPEC_INST_GET(index), \
399 .rst_gpio = GPIO_DT_SPEC_INST_GET_OR(index, reset_gpios, {0}), \
400 .int_gpio = GPIO_DT_SPEC_INST_GET(index, irq_gpios), \
401 .alt_addr = DT_INST_PROP_OR(index, alt_addr, 0), \
402 }; \
403 static struct gt911_data gt911_data_##index; \
404 DEVICE_DT_INST_DEFINE(index, gt911_init, NULL, >911_data_##index, >911_config_##index, \
405 POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL);
406
407 DT_INST_FOREACH_STATUS_OKAY(GT911_INIT)
408