aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/input
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2020-03-24 11:33:50 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2020-03-24 15:07:57 -0700
commit1a67448f1563c7fc5d3e19e6897e04a7b5424bf2 (patch)
tree3abee5b0b4e319c2c3413f0665fa4ff11fc5e4e6 /drivers/input
parentInput: goodix - add minimum firmware size check (diff)
downloadwireguard-linux-1a67448f1563c7fc5d3e19e6897e04a7b5424bf2.tar.xz
wireguard-linux-1a67448f1563c7fc5d3e19e6897e04a7b5424bf2.zip
Input: goodix - make goodix_send_cfg() take a raw buffer as argument
Make goodix_send_cfg() take a raw buffer as argument instead of a struct firmware *cfg, so that it can also be used to restore the config on resume if necessary. 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=199207 Reviewed-by: Bastien Nocera <hadess@hadess.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Link: https://lore.kernel.org/r/20200307121505.3707-10-hdegoede@redhat.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/goodix.c48
1 files changed, 22 insertions, 26 deletions
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index 7cca9998ab77..958a5d65e374 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -73,7 +73,7 @@ enum goodix_irq_pin_access_method {
struct goodix_chip_data {
u16 config_addr;
int config_len;
- int (*check_config)(struct goodix_ts_data *, const struct firmware *);
+ int (*check_config)(struct goodix_ts_data *ts, const u8 *cfg, int len);
void (*calc_config_checksum)(struct goodix_ts_data *ts);
};
@@ -103,9 +103,9 @@ struct goodix_ts_data {
};
static int goodix_check_cfg_8(struct goodix_ts_data *ts,
- const struct firmware *cfg);
+ const u8 *cfg, int len);
static int goodix_check_cfg_16(struct goodix_ts_data *ts,
- const struct firmware *cfg);
+ const u8 *cfg, int len);
static void goodix_calc_cfg_checksum_8(struct goodix_ts_data *ts);
static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts);
@@ -444,22 +444,21 @@ static int goodix_request_irq(struct goodix_ts_data *ts)
ts->irq_flags, ts->client->name, ts);
}
-static int goodix_check_cfg_8(struct goodix_ts_data *ts,
- const struct firmware *cfg)
+static int goodix_check_cfg_8(struct goodix_ts_data *ts, const u8 *cfg, int len)
{
- int i, raw_cfg_len = cfg->size - 2;
+ int i, raw_cfg_len = len - 2;
u8 check_sum = 0;
for (i = 0; i < raw_cfg_len; i++)
- check_sum += cfg->data[i];
+ check_sum += cfg[i];
check_sum = (~check_sum) + 1;
- if (check_sum != cfg->data[raw_cfg_len]) {
+ if (check_sum != cfg[raw_cfg_len]) {
dev_err(&ts->client->dev,
"The checksum of the config fw is not correct");
return -EINVAL;
}
- if (cfg->data[raw_cfg_len + 1] != 1) {
+ if (cfg[raw_cfg_len + 1] != 1) {
dev_err(&ts->client->dev,
"Config fw must have Config_Fresh register set");
return -EINVAL;
@@ -481,22 +480,22 @@ static void goodix_calc_cfg_checksum_8(struct goodix_ts_data *ts)
ts->config[raw_cfg_len + 1] = 1; /* Set "config_fresh" bit */
}
-static int goodix_check_cfg_16(struct goodix_ts_data *ts,
- const struct firmware *cfg)
+static int goodix_check_cfg_16(struct goodix_ts_data *ts, const u8 *cfg,
+ int len)
{
- int i, raw_cfg_len = cfg->size - 3;
+ int i, raw_cfg_len = len - 3;
u16 check_sum = 0;
for (i = 0; i < raw_cfg_len; i += 2)
- check_sum += get_unaligned_be16(&cfg->data[i]);
+ check_sum += get_unaligned_be16(&cfg[i]);
check_sum = (~check_sum) + 1;
- if (check_sum != get_unaligned_be16(&cfg->data[raw_cfg_len])) {
+ if (check_sum != get_unaligned_be16(&cfg[raw_cfg_len])) {
dev_err(&ts->client->dev,
"The checksum of the config fw is not correct");
return -EINVAL;
}
- if (cfg->data[raw_cfg_len + 2] != 1) {
+ if (cfg[raw_cfg_len + 2] != 1) {
dev_err(&ts->client->dev,
"Config fw must have Config_Fresh register set");
return -EINVAL;
@@ -524,17 +523,16 @@ static void goodix_calc_cfg_checksum_16(struct goodix_ts_data *ts)
* @ts: goodix_ts_data pointer
* @cfg: firmware config data
*/
-static int goodix_check_cfg(struct goodix_ts_data *ts,
- const struct firmware *cfg)
+static int goodix_check_cfg(struct goodix_ts_data *ts, const u8 *cfg, int len)
{
- if (cfg->size < GOODIX_CONFIG_MIN_LENGTH ||
- cfg->size > GOODIX_CONFIG_MAX_LENGTH) {
+ if (len < GOODIX_CONFIG_MIN_LENGTH ||
+ len > GOODIX_CONFIG_MAX_LENGTH) {
dev_err(&ts->client->dev,
"The length of the config fw is not correct");
return -EINVAL;
}
- return ts->chip->check_config(ts, cfg);
+ return ts->chip->check_config(ts, cfg, len);
}
/**
@@ -543,17 +541,15 @@ static int goodix_check_cfg(struct goodix_ts_data *ts,
* @ts: goodix_ts_data pointer
* @cfg: config firmware to write to device
*/
-static int goodix_send_cfg(struct goodix_ts_data *ts,
- const struct firmware *cfg)
+static int goodix_send_cfg(struct goodix_ts_data *ts, const u8 *cfg, int len)
{
int error;
- error = goodix_check_cfg(ts, cfg);
+ error = goodix_check_cfg(ts, cfg, len);
if (error)
return error;
- error = goodix_i2c_write(ts->client, ts->chip->config_addr, cfg->data,
- cfg->size);
+ error = goodix_i2c_write(ts->client, ts->chip->config_addr, cfg, len);
if (error) {
dev_err(&ts->client->dev, "Failed to write config data: %d",
error);
@@ -1094,7 +1090,7 @@ static void goodix_config_cb(const struct firmware *cfg, void *ctx)
if (cfg) {
/* send device configuration to the firmware */
- error = goodix_send_cfg(ts, cfg);
+ error = goodix_send_cfg(ts, cfg->data, cfg->size);
if (error)
goto err_release_cfg;
}