123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /*
- * Goodix Touchscreen Driver
- * Copyright (C) 2020 - 2021 Goodix, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be a reference
- * to you, when you are integrating the GOODiX's CTP IC into your system,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- */
- #include "goodix_ts_core.h"
- bool debug_log_flag = false;
- /*****************************************************************************
- * goodix_append_checksum
- * @summary
- * Calcualte data checksum with the specified mode.
- *
- * @param data
- * data need to be calculate
- * @param len
- * data length
- * @param mode
- * calculate for u8 or u16 checksum
- * @return
- * return the data checksum value.
- *
- *****************************************************************************/
- u32 goodix_append_checksum(u8 *data, int len, int mode)
- {
- u32 checksum = 0;
- int i;
- checksum = 0;
- if (mode == CHECKSUM_MODE_U8_LE) {
- for (i = 0; i < len; i++)
- checksum += data[i];
- } else {
- for (i = 0; i < len; i+=2)
- checksum += (data[i] + (data[i+1] << 8));
- }
- if (mode == CHECKSUM_MODE_U8_LE) {
- data[len] = checksum & 0xff;
- data[len + 1] = (checksum >> 8) & 0xff;
- return 0xFFFF & checksum;
- }
- data[len] = checksum & 0xff;
- data[len + 1] = (checksum >> 8) & 0xff;
- data[len + 2] = (checksum >> 16) & 0xff;
- data[len + 3] = (checksum >> 24) & 0xff;
- return checksum;
- }
- /* checksum_cmp: check data valid or not
- * @data: data need to be check
- * @size: data length need to be check(include the checksum bytes)
- * @mode: compare with U8 or U16 mode
- * */
- int checksum_cmp(const u8 *data, int size, int mode)
- {
- u32 cal_checksum = 0;
- u32 r_checksum = 0;
- u32 i;
- if (((mode == CHECKSUM_MODE_U8_LE) && (size < 2)) ||
- ((mode == CHECKSUM_MODE_U16_LE) && (size < 4)) ||
- ((mode == CHECKSUM_MODE_U16_LE) && (size % 2 != 0)))
- return 1;
- if (mode == CHECKSUM_MODE_U8_LE) {
- for (i = 0; i < size - 2; i++)
- cal_checksum += data[i];
- r_checksum += data[i++];
- r_checksum += (data[i] << 8);
- return (cal_checksum & 0xFFFF) == r_checksum ? 0 : 1;
- }
- if (mode == CHECKSUM_MODE_U16_LE) {
- for (i = 0; i < size - 4; i += 2)
- cal_checksum += data[i] + (data[i + 1] << 8);
- r_checksum += data[i++];
- r_checksum += (data[i++] << 8);
- r_checksum += (data[i++] << 16);
- r_checksum += (data[i] << 24);
- return cal_checksum == r_checksum ? 0 : 1;
- }
- return 1;
- }
- /* return 1 if all data is zero or ff
- * else return 0
- */
- int is_risk_data(const u8 *data, int size)
- {
- int i;
- int zero_count = 0;
- int ff_count = 0;
- for (i = 0; i < size; i++) {
- if (data[i] == 0)
- zero_count++;
- else if (data[i] == 0xff)
- ff_count++;
- }
- if (zero_count == size || ff_count == size) {
- ts_info("warning data is all %s\n",
- zero_count == size ? "zero" : "0xff");
- return 1;
- }
- return 0;
- }
- /* get config id form config file */
- #define CONFIG_ID_OFFSET 30
- u32 goodix_get_file_config_id(u8 *ic_config)
- {
- if (!ic_config)
- return 0;
- return le32_to_cpup((__le32 *)&ic_config[CONFIG_ID_OFFSET]);
- }
- /* matrix transpose */
- void goodix_rotate_abcd2cbad(int tx, int rx, s16 *data)
- {
- s16 *temp_buf = NULL;
- int size = tx * rx;
- int i;
- int j;
- int col;
- temp_buf = kcalloc(size, sizeof(s16), GFP_KERNEL);
- if (!temp_buf) {
- ts_err("malloc failed");
- return;
- }
- for (i = 0, j = 0, col = 0; i < size; i++) {
- temp_buf[i] = data[j++ * rx + col];
- if (j == tx) {
- j = 0;
- col++;
- }
- }
- memcpy(data, temp_buf, size * sizeof(s16));
- kfree(temp_buf);
- }
- /* get ic type */
- int goodix_get_ic_type(struct device_node *node)
- {
- const char *name_tmp;
- int ret;
- ret = of_property_read_string(node, "compatible", &name_tmp);
- if (ret < 0) {
- ts_err("get compatible failed");
- return ret;
- }
- if (strstr(name_tmp, "9897")) {
- ts_info("ic type is BerlinA");
- ret = IC_TYPE_BERLIN_A;
- } else if (strstr(name_tmp, "9966") || strstr(name_tmp, "7986")) {
- ts_info("ic type is BerlinB");
- ret = IC_TYPE_BERLIN_B;
- } else if (strstr(name_tmp, "9916")) {
- ts_info("ic type is BerlinD");
- ret = IC_TYPE_BERLIN_D;
- } else {
- ts_info("can't find valid ic_type");
- ret = -EINVAL;
- }
- return ret;
- }
- /* get touch type */
- int goodix_get_touch_type(struct device_node *node)
- {
- const char *touch_type;
- int ret;
- ret = of_property_read_string(node, "goodix,touch-type", &touch_type);
- if (ret) {
- ts_err("No touch type found\n");
- return -EINVAL;
- }
- if (!strcmp(touch_type, "primary"))
- ret = PRIMARY_TOUCH_IDX;
- else if (!strcmp(touch_type, "secondary"))
- ret = SECONDARY_TOUCH_IDX;
- else
- ret = -EINVAL;
- return ret;
- }
|