Commit de956cae authored by Hans de Goede's avatar Hans de Goede Committed by Dmitry Torokhov

Input: goodix - save a copy of the config from goodix_read_config()

Save a copy of the config in goodix_read_config(), this is a preparation
patch for restoring the config if it was lost after a supend/resume cycle.

BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207Reviewed-by: default avatarBastien Nocera <hadess@hadess.net>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20200307121505.3707-8-hdegoede@redhat.comSigned-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent aebfc52c
...@@ -72,6 +72,7 @@ struct goodix_chip_data { ...@@ -72,6 +72,7 @@ struct goodix_chip_data {
u16 config_addr; u16 config_addr;
int config_len; int config_len;
int (*check_config)(struct goodix_ts_data *, const struct firmware *); int (*check_config)(struct goodix_ts_data *, const struct firmware *);
void (*calc_config_checksum)(struct goodix_ts_data *ts);
}; };
struct goodix_ts_data { struct goodix_ts_data {
...@@ -96,35 +97,42 @@ struct goodix_ts_data { ...@@ -96,35 +97,42 @@ struct goodix_ts_data {
unsigned long irq_flags; unsigned long irq_flags;
enum goodix_irq_pin_access_method irq_pin_access_method; enum goodix_irq_pin_access_method irq_pin_access_method;
unsigned int contact_size; unsigned int contact_size;
u8 config[GOODIX_CONFIG_MAX_LENGTH];
}; };
static int goodix_check_cfg_8(struct goodix_ts_data *ts, static int goodix_check_cfg_8(struct goodix_ts_data *ts,
const struct firmware *cfg); const struct firmware *cfg);
static int goodix_check_cfg_16(struct goodix_ts_data *ts, static int goodix_check_cfg_16(struct goodix_ts_data *ts,
const struct firmware *cfg); const struct firmware *cfg);
static void goodix_calc_cfg_checksum_8(struct goodix_ts_data *ts);
static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts);
static const struct goodix_chip_data gt1x_chip_data = { static const struct goodix_chip_data gt1x_chip_data = {
.config_addr = GOODIX_GT1X_REG_CONFIG_DATA, .config_addr = GOODIX_GT1X_REG_CONFIG_DATA,
.config_len = GOODIX_CONFIG_MAX_LENGTH, .config_len = GOODIX_CONFIG_MAX_LENGTH,
.check_config = goodix_check_cfg_16, .check_config = goodix_check_cfg_16,
.calc_config_checksum = goodix_calc_cfg_checksum_16,
}; };
static const struct goodix_chip_data gt911_chip_data = { static const struct goodix_chip_data gt911_chip_data = {
.config_addr = GOODIX_GT9X_REG_CONFIG_DATA, .config_addr = GOODIX_GT9X_REG_CONFIG_DATA,
.config_len = GOODIX_CONFIG_911_LENGTH, .config_len = GOODIX_CONFIG_911_LENGTH,
.check_config = goodix_check_cfg_8, .check_config = goodix_check_cfg_8,
.calc_config_checksum = goodix_calc_cfg_checksum_8,
}; };
static const struct goodix_chip_data gt967_chip_data = { static const struct goodix_chip_data gt967_chip_data = {
.config_addr = GOODIX_GT9X_REG_CONFIG_DATA, .config_addr = GOODIX_GT9X_REG_CONFIG_DATA,
.config_len = GOODIX_CONFIG_967_LENGTH, .config_len = GOODIX_CONFIG_967_LENGTH,
.check_config = goodix_check_cfg_8, .check_config = goodix_check_cfg_8,
.calc_config_checksum = goodix_calc_cfg_checksum_8,
}; };
static const struct goodix_chip_data gt9x_chip_data = { static const struct goodix_chip_data gt9x_chip_data = {
.config_addr = GOODIX_GT9X_REG_CONFIG_DATA, .config_addr = GOODIX_GT9X_REG_CONFIG_DATA,
.config_len = GOODIX_CONFIG_MAX_LENGTH, .config_len = GOODIX_CONFIG_MAX_LENGTH,
.check_config = goodix_check_cfg_8, .check_config = goodix_check_cfg_8,
.calc_config_checksum = goodix_calc_cfg_checksum_8,
}; };
static const unsigned long goodix_irq_flags[] = { static const unsigned long goodix_irq_flags[] = {
...@@ -458,6 +466,19 @@ static int goodix_check_cfg_8(struct goodix_ts_data *ts, ...@@ -458,6 +466,19 @@ static int goodix_check_cfg_8(struct goodix_ts_data *ts,
return 0; return 0;
} }
static void goodix_calc_cfg_checksum_8(struct goodix_ts_data *ts)
{
int i, raw_cfg_len = ts->chip->config_len - 2;
u8 check_sum = 0;
for (i = 0; i < raw_cfg_len; i++)
check_sum += ts->config[i];
check_sum = (~check_sum) + 1;
ts->config[raw_cfg_len] = check_sum;
ts->config[raw_cfg_len + 1] = 1; /* Set "config_fresh" bit */
}
static int goodix_check_cfg_16(struct goodix_ts_data *ts, static int goodix_check_cfg_16(struct goodix_ts_data *ts,
const struct firmware *cfg) const struct firmware *cfg)
{ {
...@@ -482,6 +503,19 @@ static int goodix_check_cfg_16(struct goodix_ts_data *ts, ...@@ -482,6 +503,19 @@ static int goodix_check_cfg_16(struct goodix_ts_data *ts,
return 0; return 0;
} }
static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts)
{
int i, raw_cfg_len = ts->chip->config_len - 3;
u16 check_sum = 0;
for (i = 0; i < raw_cfg_len; i += 2)
check_sum += get_unaligned_be16(&ts->config[i]);
check_sum = (~check_sum) + 1;
put_unaligned_be16(check_sum, &ts->config[raw_cfg_len]);
ts->config[raw_cfg_len + 2] = 1; /* Set "config_fresh" bit */
}
/** /**
* goodix_check_cfg - Checks if config fw is valid * goodix_check_cfg - Checks if config fw is valid
* *
...@@ -859,12 +893,11 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts) ...@@ -859,12 +893,11 @@ static int goodix_get_gpio_config(struct goodix_ts_data *ts)
*/ */
static void goodix_read_config(struct goodix_ts_data *ts) static void goodix_read_config(struct goodix_ts_data *ts)
{ {
u8 config[GOODIX_CONFIG_MAX_LENGTH];
int x_max, y_max; int x_max, y_max;
int error; int error;
error = goodix_i2c_read(ts->client, ts->chip->config_addr, error = goodix_i2c_read(ts->client, ts->chip->config_addr,
config, ts->chip->config_len); ts->config, ts->chip->config_len);
if (error) { if (error) {
dev_warn(&ts->client->dev, "Error reading config: %d\n", dev_warn(&ts->client->dev, "Error reading config: %d\n",
error); error);
...@@ -873,15 +906,17 @@ static void goodix_read_config(struct goodix_ts_data *ts) ...@@ -873,15 +906,17 @@ static void goodix_read_config(struct goodix_ts_data *ts)
return; return;
} }
ts->int_trigger_type = config[TRIGGER_LOC] & 0x03; ts->int_trigger_type = ts->config[TRIGGER_LOC] & 0x03;
ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f; ts->max_touch_num = ts->config[MAX_CONTACTS_LOC] & 0x0f;
x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); x_max = get_unaligned_le16(&ts->config[RESOLUTION_LOC]);
y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); y_max = get_unaligned_le16(&ts->config[RESOLUTION_LOC + 2]);
if (x_max && y_max) { if (x_max && y_max) {
input_abs_set_max(ts->input_dev, ABS_MT_POSITION_X, x_max - 1); input_abs_set_max(ts->input_dev, ABS_MT_POSITION_X, x_max - 1);
input_abs_set_max(ts->input_dev, ABS_MT_POSITION_Y, y_max - 1); input_abs_set_max(ts->input_dev, ABS_MT_POSITION_Y, y_max - 1);
} }
ts->chip->calc_config_checksum(ts);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment