1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_gt9xx.h"
9 static uint8_t g_i2c_addr;
10 
gt9xx_read_data(gt9xx_context_t * context,uint16_t addr,uint8_t * buf,uint32_t size)11 hpm_stat_t gt9xx_read_data(gt9xx_context_t *context, uint16_t addr, uint8_t *buf, uint32_t size)
12 {
13     uint8_t r[2];
14     r[0] = addr >> 8;
15     r[1] = addr & 0xFF;
16     return i2c_master_address_read(context->ptr, g_i2c_addr, r, sizeof(r), buf, size);
17 }
18 
gt9xx_write_data(gt9xx_context_t * context,uint16_t addr,uint8_t * buf,uint32_t size)19 hpm_stat_t gt9xx_write_data(gt9xx_context_t *context, uint16_t addr, uint8_t *buf, uint32_t size)
20 {
21     uint8_t r[2];
22     r[0] = addr >> 8;
23     r[1] = addr & 0xFF;
24 
25     return i2c_master_address_write(context->ptr, g_i2c_addr, r, sizeof(r), buf, size);
26 }
27 
gt9xx_read_register(gt9xx_context_t * context,uint16_t reg,uint8_t * buf)28 hpm_stat_t gt9xx_read_register(gt9xx_context_t *context, uint16_t reg, uint8_t *buf)
29 {
30     return gt9xx_read_data(context, reg, buf, 1);
31 }
32 
gt9xx_write_register(gt9xx_context_t * context,uint16_t reg,uint8_t val)33 hpm_stat_t gt9xx_write_register(gt9xx_context_t *context, uint16_t reg, uint8_t val)
34 {
35     return gt9xx_write_data(context, reg, &val, 1);
36 }
37 
gt9xx_soft_reset(gt9xx_context_t * context)38 hpm_stat_t gt9xx_soft_reset(gt9xx_context_t *context)
39 {
40     return gt9xx_write_register(context, GT9XX_CMD, 0);
41 }
42 
gt9xx_calcualte_config_data_checksum(uint8_t * config)43 static uint8_t gt9xx_calcualte_config_data_checksum(uint8_t *config)
44 {
45     uint8_t checksum = 0;
46     for (uint32_t i = 0; i < GT9XX_CONFIG_DATA_SIZE - 2; i++) {
47         checksum += config[i];
48     }
49     return (~checksum + 1);
50 }
51 
gt9xx_read_config(gt9xx_context_t * context,uint8_t * buf,uint8_t size)52 hpm_stat_t gt9xx_read_config(gt9xx_context_t *context, uint8_t *buf, uint8_t size)
53 {
54     return gt9xx_read_data(context, GT9XX_CONFIG, buf, size);
55 }
56 
gt9xx_init(gt9xx_context_t * context,uint16_t width,uint16_t height)57 hpm_stat_t gt9xx_init(gt9xx_context_t *context, uint16_t width, uint16_t height)
58 {
59     hpm_stat_t stat = status_success;
60     uint8_t config[GT9XX_CONFIG_DATA_SIZE] = {0};
61 
62 #ifdef GT9XX_I2C_ADDR
63     g_i2c_addr = GT9XX_I2C_ADDR;
64     stat = gt9xx_read_data(context, GT9XX_CONFIG, config, sizeof(config));
65     if (stat != status_success) {
66         return stat;
67     }
68 #elif !GT9XX_NO_AUTO_PROBE
69     g_i2c_addr = GT9XX_I2C_ADDR0;
70     stat = gt9xx_read_data(context, GT9XX_CONFIG, config, sizeof(config));
71     if (stat != status_success) {
72         printf("0x%x failed to init GT9XX", g_i2c_addr);
73         g_i2c_addr = GT9XX_I2C_ADDR1;
74         printf(", try 0x%x\n", g_i2c_addr);
75         stat = gt9xx_read_data(context, GT9XX_CONFIG, config, sizeof(config));
76     }
77     if (stat != status_success) {
78         return stat;
79     }
80 #else
81     g_i2c_addr = GT9XX_I2C_ADDR0;
82     stat = gt9xx_read_data(context, GT9XX_CONFIG, config, sizeof(config));
83     if (stat != status_success) {
84         return stat;
85     }
86 #endif
87 
88     if (config[GT9XX_CONFIG_DATA_SIZE - 2] != gt9xx_calcualte_config_data_checksum(config)) {
89         return status_fail;
90     }
91 
92     /* < 90: fixed config; >=90 custom config */
93     if (config[GT9XX_CONFIG_DATA_CONFIG_VERSION] < 90) {
94         printf("ERR: GTXXX custom config can't be supported\n");
95         return status_fail;
96     } else {
97         context->abs_x_max = config[GT9XX_CONFIG_DATA_RESOLUTION_XH];
98         context->abs_x_max <<= 8;
99         context->abs_x_max |= config[GT9XX_CONFIG_DATA_RESOLUTION_XL];
100 
101         context->abs_y_max = config[GT9XX_CONFIG_DATA_RESOLUTION_YH];
102         context->abs_y_max <<= 8;
103         context->abs_y_max |= config[GT9XX_CONFIG_DATA_RESOLUTION_YL];
104     }
105     /* stat = gt9xx_read_data(context, GT9XX_ID_B0, (uint8_t*)&val, sizeof(val)); */
106     /* if (stat != status_success) { */
107         /* return stat; */
108     /* } */
109 
110     /* if (val != GT9XX_PRODUCT_ID) { */
111         /* return status_fail; */
112     /* } */
113 
114     config[GT9XX_CONFIG_DATA_RESOLUTION_XL] = width & 0xFF;
115     config[GT9XX_CONFIG_DATA_RESOLUTION_XH] = width >> 8;
116     config[GT9XX_CONFIG_DATA_RESOLUTION_YL] = height & 0xFF;
117     config[GT9XX_CONFIG_DATA_RESOLUTION_YH] = height >> 8;
118     config[GT9XX_CONFIG_DATA_TOUCH_NUMBER] = 5;
119     config[GT9XX_CONFIG_DATA_MODULE_SWITCH1] = (config[GT9XX_CONFIG_DATA_MODULE_SWITCH1] & ~0x3);
120 
121     config[GT9XX_CONFIG_DATA_SIZE - 2] = gt9xx_calcualte_config_data_checksum(config);
122     config[GT9XX_CONFIG_DATA_SIZE - 1] = 1;
123     /*
124      * for (uint8_t i = 0; i < 5; i++) {
125      *     gt9xx_write_data(context, GT9XX_CONFIG, config, GT9XX_CONFIG_DATA_SIZE);
126      * }
127      */
128     gt9xx_write_register(context, GT9XX_CMD, GT9XX_CMD_SOFT_RESET);
129     return status_success;
130 }
131 
gt9xx_read_touch_data(gt9xx_context_t * context,gt9xx_touch_data_t * touch_data)132 hpm_stat_t gt9xx_read_touch_data(gt9xx_context_t *context,
133                                   gt9xx_touch_data_t *touch_data)
134 {
135     hpm_stat_t stat = status_success;
136 
137     stat = gt9xx_read_data(context, GT9XX_STATUS,
138             (uint8_t *)touch_data, sizeof(gt9xx_touch_data_t));
139     if (stat != status_success) {
140         return stat;
141     }
142 
143     return stat;
144 }
145