1 /*
2  * Copyright (c) 2022 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 "osal_io.h"
12 #include "hdf_device_desc.h"
13 #include "hdf_log.h"
14 #include "hdf_touch.h"
15 #include "event_hub.h"
16 #include "input_i2c_ops.h"
17 #include "touch_ft5406.h"
18 
19 static FT5406TouchData *g_touchData = NULL;
20 
ChipInit(ChipDevice * device)21 static int32_t ChipInit(ChipDevice *device)
22 {
23     (void)device;
24     return HDF_SUCCESS;
25 }
26 
ChipResume(ChipDevice * device)27 static int32_t ChipResume(ChipDevice *device)
28 {
29     (void)device;
30     return HDF_SUCCESS;
31 }
32 
ChipSuspend(ChipDevice * device)33 static int32_t ChipSuspend(ChipDevice *device)
34 {
35     (void)device;
36     return HDF_SUCCESS;
37 }
38 
ChipDetect(ChipDevice * device)39 static int32_t ChipDetect(ChipDevice *device)
40 {
41     uint8_t regAddr;
42     uint8_t regValue[FTS_REG_IDX_MAX] = {0};
43     int32_t ret;
44     InputI2cClient *i2cClient = &device->driver->i2cClient;
45     const int idx0 = 0;
46     const int idx1 = 1;
47     const int idx2 = 2;
48 
49     regAddr = FTS_REG_FW_VER;
50     ret = InputI2cRead(i2cClient, &regAddr, 1, &regValue[idx0], 1);
51     CHIP_CHECK_RETURN(ret);
52 
53     regAddr = FTS_REG_FW_MIN_VER;
54     ret = InputI2cRead(i2cClient, &regAddr, 1, &regValue[idx1], 1);
55     CHIP_CHECK_RETURN(ret);
56 
57     regAddr = FTS_REG_FW_SUB_MIN_VER;
58     ret = InputI2cRead(i2cClient, &regAddr, 1, &regValue[idx2], 1);
59     CHIP_CHECK_RETURN(ret);
60 
61     HDF_LOGI("%s: Firmware version = %d.%d.%d", __func__, regValue[idx0], \
62         regValue[idx1], regValue[idx2]);
63 
64     (void)ChipInit(device);
65     (void)ChipResume(device);
66     (void)ChipSuspend(device);
67 
68     return HDF_SUCCESS;
69 }
70 
ParsePointData(ChipDevice * device,FrameData * frame,uint8_t pointNum)71 static int32_t ParsePointData(ChipDevice *device, FrameData *frame, uint8_t pointNum)
72 {
73     int32_t i;
74     int32_t ret;
75     uint8_t regAddr;
76     uint8_t touchId;
77     short fingersX;
78     short fingersY;
79     uint8_t buf[POINT_BUFFER_LEN] = { 0 };
80     InputI2cClient *i2cClient = &device->driver->i2cClient;
81 
82     for (i = 0; i < pointNum; i++) {
83         regAddr = FTS_REG_X_H + (i * FT_POINT_SIZE);
84         ret = InputI2cRead(i2cClient, &regAddr, 1, buf, POINT_BUFFER_LEN);
85         if (ret != HDF_SUCCESS) {
86             HDF_LOGE("Unable to fetch data, error: %d\n", ret);
87             return ret;
88         }
89 
90         touchId = (buf[FT_POINT_NUM_POS]) >> HALF_BYTE_OFFSET;
91         if (touchId >= MAX_SUPPORT_POINT) {
92             break;
93         }
94 
95         fingersX = (short) (buf[FT_X_H_POS] & 0x0F) << ONE_BYTE_OFFSET;
96         frame->fingers[i].x = fingersX | (short) buf[FT_X_L_POS];
97         fingersY = (short) (buf[FT_Y_H_POS] & 0x0F) << ONE_BYTE_OFFSET;
98         frame->fingers[i].y = fingersY | (short) buf[FT_Y_L_POS];
99         frame->fingers[i].x = device->boardCfg->attr.resolutionX - frame->fingers[i].x - 1;
100         frame->fingers[i].y = device->boardCfg->attr.resolutionY - frame->fingers[i].y - 1;
101         frame->fingers[i].trackId = touchId;
102         frame->fingers[i].status = buf[FT_EVENT_POS] >> SIX_BIT_OFFSET;
103         frame->fingers[i].valid = true;
104         frame->definedEvent = frame->fingers[i].status;
105 
106         if ((frame->fingers[i].status == TOUCH_DOWN || frame->fingers[i].status == TOUCH_CONTACT) && (pointNum == 0)) {
107             HDF_LOGE("%s: abnormal event data from driver chip", __func__);
108             return HDF_FAILURE;
109         }
110     }
111 
112     return HDF_SUCCESS;
113 }
114 
ChipDataHandle(ChipDevice * device)115 static int32_t ChipDataHandle(ChipDevice *device)
116 {
117     uint8_t reg = FTS_REG_STATUS;
118     uint8_t touchStatus = 0;
119     static uint8_t lastTouchStatus = 0;
120     uint8_t pointNum = 0;
121     int32_t ret = HDF_SUCCESS;
122     InputI2cClient *i2cClient = &device->driver->i2cClient;
123     FrameData *frame = &device->driver->frameData;
124 
125     ret = InputI2cRead(i2cClient, &reg, 1, &touchStatus, 1);
126     CHECK_RETURN_VALUE(ret);
127 
128     OsalMutexLock(&device->driver->mutex);
129     (void)memset_s(frame, sizeof(FrameData), 0, sizeof(FrameData));
130 
131     pointNum = touchStatus & HALF_BYTE_MASK;
132     if (pointNum == 0) {
133         if (lastTouchStatus == 1) {
134             lastTouchStatus = 0;
135             frame->realPointNum = 0;
136             frame->definedEvent = TOUCH_UP;
137             ret = HDF_SUCCESS;
138         } else {
139             ret = HDF_FAILURE;
140         }
141 
142         OsalMutexUnlock(&device->driver->mutex);
143         return ret;
144     }
145 
146     if (lastTouchStatus != touchStatus) {
147         lastTouchStatus = touchStatus;
148     }
149 
150     frame->realPointNum = pointNum;
151     frame->definedEvent = TOUCH_DOWN;
152 
153     ret = ParsePointData(device, frame, pointNum);
154     if (ret != HDF_SUCCESS) {
155         HDF_LOGE("%s: ParsePointData fail", __func__);
156         OsalMutexUnlock(&device->driver->mutex);
157         return ret;
158     }
159 
160     OsalMutexUnlock(&device->driver->mutex);
161     return ret;
162 }
163 
UpdateFirmware(ChipDevice * device)164 static int32_t UpdateFirmware(ChipDevice *device)
165 {
166     return HDF_SUCCESS;
167 }
168 
SetAbility(ChipDevice * device)169 static void SetAbility(ChipDevice *device)
170 {
171     device->driver->inputDev->abilitySet.devProp[0] = SET_BIT(INPUT_PROP_DIRECT);
172     device->driver->inputDev->abilitySet.eventType[0] = SET_BIT(EV_SYN) |
173         SET_BIT(EV_KEY) | SET_BIT(EV_ABS);
174     device->driver->inputDev->abilitySet.absCode[0] = SET_BIT(ABS_X) | SET_BIT(ABS_Y);
175     device->driver->inputDev->abilitySet.absCode[1] = SET_BIT(ABS_MT_POSITION_X) |
176         SET_BIT(ABS_MT_POSITION_Y) | SET_BIT(ABS_MT_TRACKING_ID);
177     device->driver->inputDev->abilitySet.keyCode[KEY_CODE_4TH] = SET_BIT(KEY_UP) | SET_BIT(KEY_DOWN);
178     device->driver->inputDev->attrSet.axisInfo[ABS_X].min = 0;
179     device->driver->inputDev->attrSet.axisInfo[ABS_X].max = device->boardCfg->attr.resolutionX - 1;
180     device->driver->inputDev->attrSet.axisInfo[ABS_X].range = 0;
181     device->driver->inputDev->attrSet.axisInfo[ABS_Y].min = 0;
182     device->driver->inputDev->attrSet.axisInfo[ABS_Y].max = device->boardCfg->attr.resolutionY - 1;
183     device->driver->inputDev->attrSet.axisInfo[ABS_Y].range = 0;
184     device->driver->inputDev->attrSet.axisInfo[ABS_MT_POSITION_X].min = 0;
185     device->driver->inputDev->attrSet.axisInfo[ABS_MT_POSITION_X].max = device->boardCfg->attr.resolutionX - 1;
186     device->driver->inputDev->attrSet.axisInfo[ABS_MT_POSITION_X].range = 0;
187     device->driver->inputDev->attrSet.axisInfo[ABS_MT_POSITION_Y].min = 0;
188     device->driver->inputDev->attrSet.axisInfo[ABS_MT_POSITION_Y].max = device->boardCfg->attr.resolutionY - 1;
189     device->driver->inputDev->attrSet.axisInfo[ABS_MT_POSITION_Y].range = 0;
190     device->driver->inputDev->attrSet.axisInfo[ABS_MT_TRACKING_ID].max = MAX_SUPPORT_POINT;
191 }
192 
193 static struct TouchChipOps g_ft5406ChipOps = {
194     .Init = ChipInit,
195     .Detect = ChipDetect,
196     .Resume = ChipResume,
197     .Suspend = ChipSuspend,
198     .DataHandle = ChipDataHandle,
199     .UpdateFirmware = UpdateFirmware,
200     .SetAbility = SetAbility,
201 };
202 
ChipTimer(struct timer_list * t)203 static void ChipTimer(struct timer_list *t)
204 {
205     FT5406TouchData *touchData = from_timer(touchData, t, timer);
206 
207     schedule_work(&touchData->work_poll);
208     mod_timer(&touchData->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS));
209 }
210 
ChipWorkPoll(struct work_struct * work)211 static void ChipWorkPoll(struct work_struct *work)
212 {
213     FT5406TouchData *touchData = container_of(work, FT5406TouchData, work_poll);
214     TouchDriver *driver = (TouchDriver *)touchData->data;
215     InputDevice *dev = driver->inputDev;
216     FrameData *frame = &driver->frameData;
217     int32_t ret;
218     int32_t i;
219 
220     ret = ChipDataHandle(driver->device);
221     if (ret == HDF_SUCCESS) {
222         OsalMutexLock(&driver->mutex);
223         for (i = 0; i < MAX_FINGERS_NUM; i++) {
224             if (frame->fingers[i].valid) {
225                 input_report_abs(dev, ABS_MT_POSITION_X, frame->fingers[i].x);
226                 input_report_abs(dev, ABS_MT_POSITION_Y, frame->fingers[i].y);
227                 input_report_abs(dev, ABS_MT_TRACKING_ID, frame->fingers[i].trackId);
228                 input_mt_sync(dev);
229             }
230         }
231 
232         if ((frame->definedEvent == TOUCH_DOWN) || (frame->definedEvent == TOUCH_CONTACT)) {
233             input_report_key(dev, BTN_TOUCH, 1); // BTN_TOUCH DOWN
234         } else {
235             input_report_key(dev, BTN_TOUCH, 0); // BTN_TOUCH UP
236         }
237         OsalMutexUnlock(&driver->mutex);
238         input_sync(dev);
239     }
240 }
241 
FreeChipConfig(TouchChipCfg * config)242 static void FreeChipConfig(TouchChipCfg *config)
243 {
244     if (config->pwrSeq.pwrOn.buf != NULL) {
245         OsalMemFree(config->pwrSeq.pwrOn.buf);
246     }
247 
248     if (config->pwrSeq.pwrOff.buf != NULL) {
249         OsalMemFree(config->pwrSeq.pwrOff.buf);
250     }
251 
252     if (config->pwrSeq.resume.buf != NULL) {
253         OsalMemFree(config->pwrSeq.resume.buf);
254     }
255 
256     if (config->pwrSeq.suspend.buf != NULL) {
257         OsalMemFree(config->pwrSeq.suspend.buf);
258     }
259 
260     OsalMemFree(config);
261 }
262 
ChipConfigInstance(struct HdfDeviceObject * device)263 static TouchChipCfg *ChipConfigInstance(struct HdfDeviceObject *device)
264 {
265     TouchChipCfg *chipCfg = (TouchChipCfg *)OsalMemAlloc(sizeof(TouchChipCfg));
266     if (chipCfg == NULL) {
267         HDF_LOGE("%s: instance chip config failed", __func__);
268         return NULL;
269     }
270     (void)memset_s(chipCfg, sizeof(TouchChipCfg), 0, sizeof(TouchChipCfg));
271 
272     if (ParseTouchChipConfig(device->property, chipCfg) != HDF_SUCCESS) {
273         HDF_LOGE("%s: parse chip config failed", __func__);
274         OsalMemFree(chipCfg);
275         chipCfg = NULL;
276     }
277     return chipCfg;
278 }
279 
ChipDeviceInstance(void)280 static ChipDevice *ChipDeviceInstance(void)
281 {
282     ChipDevice *chipDev = (ChipDevice *)OsalMemAlloc(sizeof(ChipDevice));
283     if (chipDev == NULL) {
284         HDF_LOGE("%s: instance chip device failed", __func__);
285         return NULL;
286     }
287     (void)memset_s(chipDev, sizeof(ChipDevice), 0, sizeof(ChipDevice));
288     return chipDev;
289 }
290 
HdfFocalChipInit(struct HdfDeviceObject * device)291 static int32_t HdfFocalChipInit(struct HdfDeviceObject *device)
292 {
293     TouchChipCfg *chipCfg = NULL;
294     ChipDevice *chipDev = NULL;
295 
296     if (device == NULL) {
297         HDF_LOGE("%s: device is NULL", __func__);
298         return HDF_ERR_INVALID_PARAM;
299     }
300 
301     chipCfg = ChipConfigInstance(device);
302     if (chipCfg == NULL) {
303         HDF_LOGE("%s: ChipConfigInstance is NULL", __func__);
304         return HDF_ERR_MALLOC_FAIL;
305     }
306 
307     chipDev = ChipDeviceInstance();
308     if (chipDev == NULL) {
309         HDF_LOGE("%s: ChipDeviceInstance fail", __func__);
310         FreeChipConfig(chipCfg);
311         return HDF_FAILURE;
312     }
313 
314     chipDev->chipCfg = chipCfg;
315     chipDev->ops = &g_ft5406ChipOps;
316     chipDev->chipName = chipCfg->chipName;
317     chipDev->vendorName = chipCfg->vendorName;
318     device->priv = (void *)chipDev;
319 
320     if (RegisterTouchChipDevice(chipDev) != HDF_SUCCESS) {
321         HDF_LOGE("%s: RegisterTouchChipDevice fail", __func__);
322         OsalMemFree(chipDev);
323         FreeChipConfig(chipCfg);
324         return HDF_FAILURE;
325     }
326 
327     g_touchData = (FT5406TouchData *)OsalMemAlloc(sizeof(FT5406TouchData));
328     if (g_touchData == NULL) {
329         HDF_LOGE("OsalMemAlloc touchData failed!");
330         OsalMemFree(chipDev);
331         FreeChipConfig(chipCfg);
332         return HDF_FAILURE;
333     }
334 
335     (void)memset_s(g_touchData, sizeof(FT5406TouchData), 0, sizeof(FT5406TouchData));
336 
337     if (chipDev->driver != NULL) {
338         g_touchData->data = chipDev->driver;
339     }
340 
341     INIT_WORK(&g_touchData->work_poll, ChipWorkPoll);
342     timer_setup(&g_touchData->timer, ChipTimer, 0);
343     g_touchData->timer.expires = jiffies + msecs_to_jiffies(POLL_INTERVAL_MS);
344     add_timer(&g_touchData->timer);
345 
346     HDF_LOGI("%s: exit succ, chipName = %s", __func__, chipCfg->chipName);
347     return HDF_SUCCESS;
348 }
349 
HdfFocalChipRelease(struct HdfDeviceObject * device)350 static void HdfFocalChipRelease(struct HdfDeviceObject *device)
351 {
352     HDF_LOGI("HdfFocalChipRelease enter.");
353 
354     if (device == NULL || device->priv == NULL || g_touchData == NULL) {
355         HDF_LOGE("%s: param is null", __func__);
356         return;
357     }
358 
359     del_timer_sync(&g_touchData->timer);
360     cancel_work_sync(&g_touchData->work_poll);
361 
362     OsalMemFree(g_touchData);
363     g_touchData = NULL;
364 
365     return;
366 }
367 
368 struct HdfDriverEntry g_touchFocalChipEntry = {
369     .moduleVersion = 1,
370     .moduleName = "HDF_TOUCH_FT5406",
371     .Init = HdfFocalChipInit,
372     .Release = HdfFocalChipRelease,
373 };
374 
375 HDF_INIT(g_touchFocalChipEntry);
376