1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include <securec.h>
10 #include "osal_mem.h"
11 #include "hdf_device_desc.h"
12 #include "hdf_log.h"
13 #include "hdf_touch.h"
14 #include "input_i2c_ops.h"
15 #include "touch_ft6336.h"
16
ChipInit(ChipDevice * device)17 static int32_t ChipInit(ChipDevice *device)
18 {
19 return HDF_SUCCESS;
20 }
21
ChipResume(ChipDevice * device)22 static int32_t ChipResume(ChipDevice *device)
23 {
24 return HDF_SUCCESS;
25 }
26
ChipSuspend(ChipDevice * device)27 static int32_t ChipSuspend(ChipDevice *device)
28 {
29 return HDF_SUCCESS;
30 }
31
ChipDetect(ChipDevice * device)32 static int32_t ChipDetect(ChipDevice *device)
33 {
34 uint8_t regAddr;
35 uint8_t regValue = 0;
36 int32_t ret;
37 InputI2cClient *i2cClient = &device->driver->i2cClient;
38
39 regAddr = FTS_REG_POINT_RATE;
40 ret = InputI2cWrite(i2cClient, ®Addr, 1);
41 CHIP_CHECK_RETURN(ret);
42 ret = InputI2cRead(i2cClient, ®Addr, 1, ®Value, 1);
43 CHIP_CHECK_RETURN(ret);
44 HDF_LOGI("%s: Report rate is %u * 10", __func__, regValue);
45
46 regAddr = FTS_REG_FW_VER;
47 ret = InputI2cWrite(i2cClient, ®Addr, 1);
48 CHIP_CHECK_RETURN(ret);
49 ret = InputI2cRead(i2cClient, ®Addr, 1, ®Value, 1);
50 CHIP_CHECK_RETURN(ret);
51 HDF_LOGI("%s: Firmware version = 0x%x", __func__, regValue);
52
53 regAddr = FTS_REG_CHIP_ID;
54 ret = InputI2cWrite(i2cClient, ®Addr, 1);
55 CHIP_CHECK_RETURN(ret);
56 ret = InputI2cRead(i2cClient, ®Addr, 1, ®Value, 1);
57 CHIP_CHECK_RETURN(ret);
58 HDF_LOGI("%s: Chip ID is %u", __func__, regValue);
59
60 (void)ChipInit(device);
61 (void)ChipResume(device);
62 (void)ChipSuspend(device);
63 return HDF_SUCCESS;
64 }
65
ParsePointData(FrameData * frame,uint8_t * buf,uint8_t pointNum)66 static int32_t ParsePointData(FrameData *frame, uint8_t *buf, uint8_t pointNum)
67 {
68 int32_t i;
69 for (i = 0; i < pointNum; i++) {
70 frame->fingers[i].x = (unsigned int)((buf[FT_X_H_POS + FT_POINT_SIZE * i] & HALF_BYTE_MASK)
71 << ONE_BYTE_OFFSET) | (unsigned int)buf[FT_X_L_POS + FT_POINT_SIZE * i];
72 frame->fingers[i].y = (unsigned int)((buf[FT_Y_H_POS + FT_POINT_SIZE * i] & HALF_BYTE_MASK)
73 << ONE_BYTE_OFFSET) | (unsigned int)buf[FT_Y_L_POS + FT_POINT_SIZE * i];
74 frame->fingers[i].trackId = (int)(buf[FT_FINGER_POS + FT_POINT_SIZE * i]) >> HALF_BYTE_OFFSET;
75 frame->fingers[i].status = (int)buf[FT_EVENT_POS + FT_POINT_SIZE * i] >> SIX_BIT_OFFSET;
76 frame->fingers[i].valid = true;
77 frame->definedEvent = frame->fingers[i].status;
78
79 if ((frame->fingers[i].status == TOUCH_DOWN || frame->fingers[i].status == TOUCH_CONTACT) && (pointNum == 0)) {
80 HDF_LOGE("%s: abnormal event data from driver chip", __func__);
81 return HDF_FAILURE;
82 }
83 }
84 if (pointNum == 0) {
85 frame->definedEvent = TOUCH_UP;
86 }
87 return HDF_SUCCESS;
88 }
89
ChipDataHandle(ChipDevice * device)90 static int32_t ChipDataHandle(ChipDevice *device)
91 {
92 uint8_t buf[POINT_BUFFER_LEN] = {0};
93 uint8_t reg = 0x0;
94 uint8_t pointNum;
95 int32_t ret;
96 InputI2cClient *i2cClient = &device->driver->i2cClient;
97 FrameData *frame = &device->driver->frameData;
98
99 ret = InputI2cRead(i2cClient, ®, 1, buf, POINT_BUFFER_LEN);
100 CHIP_CHECK_RETURN(ret);
101
102 OsalMutexLock(&device->driver->mutex);
103 (void)memset_s(frame, sizeof(FrameData), 0, sizeof(FrameData));
104 pointNum = buf[FT_POINT_NUM_POS] & HALF_BYTE_MASK;
105 if (pointNum > MAX_SUPPORT_POINT) {
106 pointNum = MAX_SUPPORT_POINT;
107 }
108
109 frame->realPointNum = pointNum;
110 ret = ParsePointData(frame, buf, pointNum);
111 if (ret != HDF_SUCCESS) {
112 OsalMutexUnlock(&device->driver->mutex);
113 return ret;
114 }
115 OsalMutexUnlock(&device->driver->mutex);
116 return HDF_SUCCESS;
117 }
118
119 static struct TouchChipOps g_ft6336ChipOps = {
120 .Init = ChipInit,
121 .Detect = ChipDetect,
122 .Resume = ChipResume,
123 .Suspend = ChipSuspend,
124 .DataHandle = ChipDataHandle,
125 };
126
FreeChipConfig(TouchChipCfg * config)127 static void FreeChipConfig(TouchChipCfg *config)
128 {
129 if (config->pwrSeq.pwrOn.buf != NULL) {
130 OsalMemFree(config->pwrSeq.pwrOn.buf);
131 }
132
133 if (config->pwrSeq.pwrOff.buf != NULL) {
134 OsalMemFree(config->pwrSeq.pwrOff.buf);
135 }
136
137 if (config->pwrSeq.resume.buf != NULL) {
138 OsalMemFree(config->pwrSeq.resume.buf);
139 }
140
141 if (config->pwrSeq.suspend.buf != NULL) {
142 OsalMemFree(config->pwrSeq.suspend.buf);
143 }
144
145 OsalMemFree(config);
146 }
147
ChipConfigInstance(struct HdfDeviceObject * device)148 static TouchChipCfg *ChipConfigInstance(struct HdfDeviceObject *device)
149 {
150 TouchChipCfg *chipCfg = (TouchChipCfg *)OsalMemAlloc(sizeof(TouchChipCfg));
151 if (chipCfg == NULL) {
152 HDF_LOGE("%s: instance chip config failed", __func__);
153 return NULL;
154 }
155 (void)memset_s(chipCfg, sizeof(TouchChipCfg), 0, sizeof(TouchChipCfg));
156
157 if (ParseTouchChipConfig(device->property, chipCfg) != HDF_SUCCESS) {
158 HDF_LOGE("%s: parse chip config failed", __func__);
159 OsalMemFree(chipCfg);
160 chipCfg = NULL;
161 }
162 return chipCfg;
163 }
164
ChipDeviceInstance(void)165 static ChipDevice *ChipDeviceInstance(void)
166 {
167 ChipDevice *chipDev = (ChipDevice *)OsalMemAlloc(sizeof(ChipDevice));
168 if (chipDev == NULL) {
169 HDF_LOGE("%s: instance chip device failed", __func__);
170 return NULL;
171 }
172 (void)memset_s(chipDev, sizeof(ChipDevice), 0, sizeof(ChipDevice));
173 return chipDev;
174 }
175
HdfFocalChipInit(struct HdfDeviceObject * device)176 static int32_t HdfFocalChipInit(struct HdfDeviceObject *device)
177 {
178 TouchChipCfg *chipCfg = NULL;
179 ChipDevice *chipDev = NULL;
180 HDF_LOGE("%s: enter", __func__);
181 if (device == NULL) {
182 return HDF_ERR_INVALID_PARAM;
183 }
184
185 chipCfg = ChipConfigInstance(device);
186 if (chipCfg == NULL) {
187 return HDF_ERR_MALLOC_FAIL;
188 }
189
190 chipDev = ChipDeviceInstance();
191 if (chipDev == NULL) {
192 goto EXIT;
193 }
194
195 chipDev->chipCfg = chipCfg;
196 chipDev->ops = &g_ft6336ChipOps;
197 chipDev->chipName = chipCfg->chipName;
198 chipDev->vendorName = chipCfg->vendorName;
199
200 if (RegisterTouchChipDevice(chipDev) != HDF_SUCCESS) {
201 goto EXIT1;
202 }
203 HDF_LOGI("%s: exit succ, chipName = %s", __func__, chipCfg->chipName);
204 return HDF_SUCCESS;
205
206 EXIT1:
207 OsalMemFree(chipDev);
208 EXIT:
209 FreeChipConfig(chipCfg);
210 return HDF_FAILURE;
211 }
212
213 struct HdfDriverEntry g_touchFocalChipEntry = {
214 .moduleVersion = 1,
215 .moduleName = "HDF_TOUCH_FT6336",
216 .Init = HdfFocalChipInit,
217 };
218
219 HDF_INIT(g_touchFocalChipEntry);