aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-08-11 09:23:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-08-11 09:23:08 -0700
commit2ae08b36c06ea8df73a79f6b80ff7964e006e9e3 (patch)
tree5efdf98f3e7189f7256e97114ed6f3bcad1a7c8b /drivers/input/touchscreen
parentRevert "Makefile.extrawarn: re-enable -Wformat for clang" (diff)
parentMerge branch 'next' into for-linus (diff)
downloadlinux-dev-2ae08b36c06ea8df73a79f6b80ff7964e006e9e3.tar.xz
linux-dev-2ae08b36c06ea8df73a79f6b80ff7964e006e9e3.zip
Merge tag 'input-for-v5.20-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov: - changes to input core to properly queue synthetic events (such as autorepeat) and to release multitouch contacts when an input device is inhibited or suspended - reworked quirk handling in i8042 driver that consolidates multiple DMI tables into one and adds several quirks for TUXEDO line of laptops - update to mt6779 keypad to better reflect organization of the hardware - changes to mtk-pmic-keys driver preparing it to handle more variants - facelift of adp5588-keys driver - improvements to iqs7222 driver - adjustments to various DT binding documents for input devices - other assorted driver fixes. * tag 'input-for-v5.20-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (54 commits) Input: adc-joystick - fix ordering in adc_joystick_probe() dt-bindings: input: ariel-pwrbutton: use spi-peripheral-props.yaml Input: deactivate MT slots when inhibiting or suspending devices Input: properly queue synthetic events dt-bindings: input: iqs7222: Use central 'linux,code' definition Input: i8042 - add dritek quirk for Acer Aspire One AO532 dt-bindings: input: gpio-keys: accept also interrupt-extended dt-bindings: input: gpio-keys: reference input.yaml and document properties dt-bindings: input: gpio-keys: enforce node names to match all properties dt-bindings: input: Convert adc-keys to DT schema dt-bindings: input: Centralize 'linux,input-type' definition dt-bindings: input: Use common 'linux,keycodes' definition dt-bindings: input: Centralize 'linux,code' definition dt-bindings: input: Increase maximum keycode value to 0x2ff Input: mt6779-keypad - implement row/column selection Input: mt6779-keypad - match hardware matrix organization Input: i8042 - add additional TUXEDO devices to i8042 quirk tables Input: goodix - switch use of acpi_gpio_get_*_resource() APIs Input: i8042 - add TUXEDO devices to i8042 quirk tables Input: i8042 - add debug output for quirks ...
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c96
-rw-r--r--drivers/input/touchscreen/exc3000.c7
-rw-r--r--drivers/input/touchscreen/goodix.c22
-rw-r--r--drivers/input/touchscreen/zinitix.c112
4 files changed, 156 insertions, 81 deletions
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index bb2e1cbffba7..82beddb28761 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -24,6 +24,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/ratelimit.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
@@ -47,6 +48,8 @@
#define M09_REGISTER_NUM_X 0x94
#define M09_REGISTER_NUM_Y 0x95
+#define M12_REGISTER_REPORT_RATE 0x88
+
#define EV_REGISTER_THRESHOLD 0x40
#define EV_REGISTER_GAIN 0x41
#define EV_REGISTER_OFFSET_Y 0x45
@@ -127,9 +130,12 @@ struct edt_ft5x06_ts_data {
int max_support_points;
char name[EDT_NAME_LEN];
+ char fw_version[EDT_NAME_LEN];
struct edt_reg_addr reg_addr;
enum edt_ver version;
+ unsigned int crc_errors;
+ unsigned int header_errors;
};
struct edt_i2c_chip_data {
@@ -178,6 +184,7 @@ static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata,
crc ^= buf[i];
if (crc != buf[buflen-1]) {
+ tsdata->crc_errors++;
dev_err_ratelimited(&tsdata->client->dev,
"crc error: 0x%02x expected, got 0x%02x\n",
crc, buf[buflen-1]);
@@ -235,6 +242,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
if (tsdata->version == EDT_M06) {
if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
rdbuf[2] != datalen) {
+ tsdata->header_errors++;
dev_err_ratelimited(dev,
"Unexpected header: %02x%02x%02x!\n",
rdbuf[0], rdbuf[1], rdbuf[2]);
@@ -523,9 +531,55 @@ static EDT_ATTR(offset_y, S_IWUSR | S_IRUGO, NO_REGISTER, NO_REGISTER,
/* m06: range 20 to 80, m09: range 0 to 30, m12: range 1 to 255... */
static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
M09_REGISTER_THRESHOLD, EV_REGISTER_THRESHOLD, 0, 255);
-/* m06: range 3 to 14, m12: (0x64: 100Hz) */
+/* m06: range 3 to 14, m12: range 1 to 255 */
static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
- NO_REGISTER, NO_REGISTER, 0, 255);
+ M12_REGISTER_REPORT_RATE, NO_REGISTER, 0, 255);
+
+static ssize_t model_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+
+ return sysfs_emit(buf, "%s\n", tsdata->name);
+}
+
+static DEVICE_ATTR_RO(model);
+
+static ssize_t fw_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+
+ return sysfs_emit(buf, "%s\n", tsdata->fw_version);
+}
+
+static DEVICE_ATTR_RO(fw_version);
+
+/* m06 only */
+static ssize_t header_errors_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+
+ return sysfs_emit(buf, "%d\n", tsdata->header_errors);
+}
+
+static DEVICE_ATTR_RO(header_errors);
+
+/* m06 only */
+static ssize_t crc_errors_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+
+ return sysfs_emit(buf, "%d\n", tsdata->crc_errors);
+}
+
+static DEVICE_ATTR_RO(crc_errors);
static struct attribute *edt_ft5x06_attrs[] = {
&edt_ft5x06_attr_gain.dattr.attr,
@@ -534,6 +588,10 @@ static struct attribute *edt_ft5x06_attrs[] = {
&edt_ft5x06_attr_offset_y.dattr.attr,
&edt_ft5x06_attr_threshold.dattr.attr,
&edt_ft5x06_attr_report_rate.dattr.attr,
+ &dev_attr_model.attr,
+ &dev_attr_fw_version.attr,
+ &dev_attr_header_errors.attr,
+ &dev_attr_crc_errors.attr,
NULL
};
@@ -820,13 +878,13 @@ static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
#endif /* CONFIG_DEBUGFS */
static int edt_ft5x06_ts_identify(struct i2c_client *client,
- struct edt_ft5x06_ts_data *tsdata,
- char *fw_version)
+ struct edt_ft5x06_ts_data *tsdata)
{
u8 rdbuf[EDT_NAME_LEN];
char *p;
int error;
char *model_name = tsdata->name;
+ char *fw_version = tsdata->fw_version;
/* see what we find if we assume it is a M06 *
* if we get less than EDT_NAME_LEN, we don't want
@@ -1030,7 +1088,8 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
case EDT_M09:
case EDT_M12:
reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
- reg_addr->reg_report_rate = NO_REGISTER;
+ reg_addr->reg_report_rate = tsdata->version == EDT_M12 ?
+ M12_REGISTER_REPORT_RATE : NO_REGISTER;
reg_addr->reg_gain = M09_REGISTER_GAIN;
reg_addr->reg_offset = M09_REGISTER_OFFSET;
reg_addr->reg_offset_x = NO_REGISTER;
@@ -1081,7 +1140,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
struct input_dev *input;
unsigned long irq_flags;
int error;
- char fw_version[EDT_NAME_LEN];
+ u32 report_rate;
dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
@@ -1194,7 +1253,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
tsdata->input = input;
tsdata->factory_mode = false;
- error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
+ error = edt_ft5x06_ts_identify(client, tsdata);
if (error) {
dev_err(&client->dev, "touchscreen probe failed\n");
return error;
@@ -1210,9 +1269,30 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
edt_ft5x06_ts_get_parameters(tsdata);
+ if (tsdata->reg_addr.reg_report_rate != NO_REGISTER &&
+ !device_property_read_u32(&client->dev,
+ "report-rate-hz", &report_rate)) {
+ if (tsdata->version == EDT_M06)
+ tsdata->report_rate = clamp_val(report_rate, 30, 140);
+ else
+ tsdata->report_rate = clamp_val(report_rate, 1, 255);
+
+ if (report_rate != tsdata->report_rate)
+ dev_warn(&client->dev,
+ "report-rate %dHz is unsupported, use %dHz\n",
+ report_rate, tsdata->report_rate);
+
+ if (tsdata->version == EDT_M06)
+ tsdata->report_rate /= 10;
+
+ edt_ft5x06_register_write(tsdata,
+ tsdata->reg_addr.reg_report_rate,
+ tsdata->report_rate);
+ }
+
dev_dbg(&client->dev,
"Model \"%s\", Rev. \"%s\", %dx%d sensors\n",
- tsdata->name, fw_version, tsdata->num_x, tsdata->num_y);
+ tsdata->name, tsdata->fw_version, tsdata->num_x, tsdata->num_y);
input->name = tsdata->name;
input->id.bustype = BUS_I2C;
diff --git a/drivers/input/touchscreen/exc3000.c b/drivers/input/touchscreen/exc3000.c
index cbe0dd412912..4b7eee01c6aa 100644
--- a/drivers/input/touchscreen/exc3000.c
+++ b/drivers/input/touchscreen/exc3000.c
@@ -220,6 +220,7 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
{
u8 buf[EXC3000_LEN_VENDOR_REQUEST] = { 0x67, 0x00, 0x42, 0x00, 0x03 };
int ret;
+ unsigned long time_left;
mutex_lock(&data->query_lock);
@@ -233,9 +234,9 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
goto out_unlock;
if (response) {
- ret = wait_for_completion_timeout(&data->wait_event,
- timeout * HZ);
- if (ret <= 0) {
+ time_left = wait_for_completion_timeout(&data->wait_event,
+ timeout * HZ);
+ if (time_left == 0) {
ret = -ETIMEDOUT;
goto out_unlock;
}
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
index aa45a9fee6a0..d016505fc081 100644
--- a/drivers/input/touchscreen/goodix.c
+++ b/drivers/input/touchscreen/goodix.c
@@ -822,22 +822,16 @@ static int goodix_resource(struct acpi_resource *ares, void *data)
struct device *dev = &ts->client->dev;
struct acpi_resource_gpio *gpio;
- switch (ares->type) {
- case ACPI_RESOURCE_TYPE_GPIO:
- gpio = &ares->data.gpio;
- if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) {
- if (ts->gpio_int_idx == -1) {
- ts->gpio_int_idx = ts->gpio_count;
- } else {
- dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
- ts->gpio_int_idx = -2;
- }
+ if (acpi_gpio_get_irq_resource(ares, &gpio)) {
+ if (ts->gpio_int_idx == -1) {
+ ts->gpio_int_idx = ts->gpio_count;
+ } else {
+ dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
+ ts->gpio_int_idx = -2;
}
ts->gpio_count++;
- break;
- default:
- break;
- }
+ } else if (acpi_gpio_get_io_resource(ares, &gpio))
+ ts->gpio_count++;
return 0;
}
diff --git a/drivers/input/touchscreen/zinitix.c b/drivers/input/touchscreen/zinitix.c
index 8bd03278ad9a..52f9e9eaab14 100644
--- a/drivers/input/touchscreen/zinitix.c
+++ b/drivers/input/touchscreen/zinitix.c
@@ -15,75 +15,75 @@
/* Register Map */
-#define BT541_SWRESET_CMD 0x0000
-#define BT541_WAKEUP_CMD 0x0001
+#define ZINITIX_SWRESET_CMD 0x0000
+#define ZINITIX_WAKEUP_CMD 0x0001
-#define BT541_IDLE_CMD 0x0004
-#define BT541_SLEEP_CMD 0x0005
+#define ZINITIX_IDLE_CMD 0x0004
+#define ZINITIX_SLEEP_CMD 0x0005
-#define BT541_CLEAR_INT_STATUS_CMD 0x0003
-#define BT541_CALIBRATE_CMD 0x0006
-#define BT541_SAVE_STATUS_CMD 0x0007
-#define BT541_SAVE_CALIBRATION_CMD 0x0008
-#define BT541_RECALL_FACTORY_CMD 0x000f
+#define ZINITIX_CLEAR_INT_STATUS_CMD 0x0003
+#define ZINITIX_CALIBRATE_CMD 0x0006
+#define ZINITIX_SAVE_STATUS_CMD 0x0007
+#define ZINITIX_SAVE_CALIBRATION_CMD 0x0008
+#define ZINITIX_RECALL_FACTORY_CMD 0x000f
-#define BT541_THRESHOLD 0x0020
+#define ZINITIX_THRESHOLD 0x0020
-#define BT541_LARGE_PALM_REJECT_AREA_TH 0x003F
+#define ZINITIX_LARGE_PALM_REJECT_AREA_TH 0x003F
-#define BT541_DEBUG_REG 0x0115 /* 0~7 */
+#define ZINITIX_DEBUG_REG 0x0115 /* 0~7 */
-#define BT541_TOUCH_MODE 0x0010
-#define BT541_CHIP_REVISION 0x0011
-#define BT541_FIRMWARE_VERSION 0x0012
+#define ZINITIX_TOUCH_MODE 0x0010
+#define ZINITIX_CHIP_REVISION 0x0011
+#define ZINITIX_FIRMWARE_VERSION 0x0012
#define ZINITIX_USB_DETECT 0x116
-#define BT541_MINOR_FW_VERSION 0x0121
+#define ZINITIX_MINOR_FW_VERSION 0x0121
-#define BT541_VENDOR_ID 0x001C
-#define BT541_HW_ID 0x0014
+#define ZINITIX_VENDOR_ID 0x001C
+#define ZINITIX_HW_ID 0x0014
-#define BT541_DATA_VERSION_REG 0x0013
-#define BT541_SUPPORTED_FINGER_NUM 0x0015
-#define BT541_EEPROM_INFO 0x0018
-#define BT541_INITIAL_TOUCH_MODE 0x0019
+#define ZINITIX_DATA_VERSION_REG 0x0013
+#define ZINITIX_SUPPORTED_FINGER_NUM 0x0015
+#define ZINITIX_EEPROM_INFO 0x0018
+#define ZINITIX_INITIAL_TOUCH_MODE 0x0019
-#define BT541_TOTAL_NUMBER_OF_X 0x0060
-#define BT541_TOTAL_NUMBER_OF_Y 0x0061
+#define ZINITIX_TOTAL_NUMBER_OF_X 0x0060
+#define ZINITIX_TOTAL_NUMBER_OF_Y 0x0061
-#define BT541_DELAY_RAW_FOR_HOST 0x007f
+#define ZINITIX_DELAY_RAW_FOR_HOST 0x007f
-#define BT541_BUTTON_SUPPORTED_NUM 0x00B0
-#define BT541_BUTTON_SENSITIVITY 0x00B2
-#define BT541_DUMMY_BUTTON_SENSITIVITY 0X00C8
+#define ZINITIX_BUTTON_SUPPORTED_NUM 0x00B0
+#define ZINITIX_BUTTON_SENSITIVITY 0x00B2
+#define ZINITIX_DUMMY_BUTTON_SENSITIVITY 0X00C8
-#define BT541_X_RESOLUTION 0x00C0
-#define BT541_Y_RESOLUTION 0x00C1
+#define ZINITIX_X_RESOLUTION 0x00C0
+#define ZINITIX_Y_RESOLUTION 0x00C1
-#define BT541_POINT_STATUS_REG 0x0080
-#define BT541_ICON_STATUS_REG 0x00AA
+#define ZINITIX_POINT_STATUS_REG 0x0080
+#define ZINITIX_ICON_STATUS_REG 0x00AA
-#define BT541_POINT_COORD_REG (BT541_POINT_STATUS_REG + 2)
+#define ZINITIX_POINT_COORD_REG (ZINITIX_POINT_STATUS_REG + 2)
-#define BT541_AFE_FREQUENCY 0x0100
-#define BT541_DND_N_COUNT 0x0122
-#define BT541_DND_U_COUNT 0x0135
+#define ZINITIX_AFE_FREQUENCY 0x0100
+#define ZINITIX_DND_N_COUNT 0x0122
+#define ZINITIX_DND_U_COUNT 0x0135
-#define BT541_RAWDATA_REG 0x0200
+#define ZINITIX_RAWDATA_REG 0x0200
-#define BT541_EEPROM_INFO_REG 0x0018
+#define ZINITIX_EEPROM_INFO_REG 0x0018
-#define BT541_INT_ENABLE_FLAG 0x00f0
-#define BT541_PERIODICAL_INTERRUPT_INTERVAL 0x00f1
+#define ZINITIX_INT_ENABLE_FLAG 0x00f0
+#define ZINITIX_PERIODICAL_INTERRUPT_INTERVAL 0x00f1
-#define BT541_BTN_WIDTH 0x016d
+#define ZINITIX_BTN_WIDTH 0x016d
-#define BT541_CHECKSUM_RESULT 0x012c
+#define ZINITIX_CHECKSUM_RESULT 0x012c
-#define BT541_INIT_FLASH 0x01d0
-#define BT541_WRITE_FLASH 0x01d1
-#define BT541_READ_FLASH 0x01d2
+#define ZINITIX_INIT_FLASH 0x01d0
+#define ZINITIX_WRITE_FLASH 0x01d1
+#define ZINITIX_READ_FLASH 0x01d2
#define ZINITIX_INTERNAL_FLAG_02 0x011e
#define ZINITIX_INTERNAL_FLAG_03 0x011f
@@ -196,13 +196,13 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
int i;
int error;
- error = zinitix_write_cmd(client, BT541_SWRESET_CMD);
+ error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
if (error) {
dev_err(&client->dev, "Failed to write reset command\n");
return error;
}
- error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG, 0x0);
+ error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
if (error) {
dev_err(&client->dev,
"Failed to reset interrupt enable flag\n");
@@ -210,32 +210,32 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
}
/* initialize */
- error = zinitix_write_u16(client, BT541_X_RESOLUTION,
+ error = zinitix_write_u16(client, ZINITIX_X_RESOLUTION,
bt541->prop.max_x);
if (error)
return error;
- error = zinitix_write_u16(client, BT541_Y_RESOLUTION,
+ error = zinitix_write_u16(client, ZINITIX_Y_RESOLUTION,
bt541->prop.max_y);
if (error)
return error;
- error = zinitix_write_u16(client, BT541_SUPPORTED_FINGER_NUM,
+ error = zinitix_write_u16(client, ZINITIX_SUPPORTED_FINGER_NUM,
MAX_SUPPORTED_FINGER_NUM);
if (error)
return error;
- error = zinitix_write_u16(client, BT541_INITIAL_TOUCH_MODE,
+ error = zinitix_write_u16(client, ZINITIX_INITIAL_TOUCH_MODE,
bt541->zinitix_mode);
if (error)
return error;
- error = zinitix_write_u16(client, BT541_TOUCH_MODE,
+ error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,
bt541->zinitix_mode);
if (error)
return error;
- error = zinitix_write_u16(client, BT541_INT_ENABLE_FLAG,
+ error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG,
BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE |
BIT_UP);
if (error)
@@ -243,7 +243,7 @@ static int zinitix_init_touch(struct bt541_ts_data *bt541)
/* clear queue */
for (i = 0; i < 10; i++) {
- zinitix_write_cmd(client, BT541_CLEAR_INT_STATUS_CMD);
+ zinitix_write_cmd(client, ZINITIX_CLEAR_INT_STATUS_CMD);
udelay(10);
}
@@ -361,7 +361,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
memset(&touch_event, 0, sizeof(struct touch_event));
- error = zinitix_read_data(bt541->client, BT541_POINT_STATUS_REG,
+ error = zinitix_read_data(bt541->client, ZINITIX_POINT_STATUS_REG,
&touch_event, sizeof(struct touch_event));
if (error) {
dev_err(&client->dev, "Failed to read in touchpoint struct\n");
@@ -381,7 +381,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
input_sync(bt541->input_dev);
out:
- zinitix_write_cmd(bt541->client, BT541_CLEAR_INT_STATUS_CMD);
+ zinitix_write_cmd(bt541->client, ZINITIX_CLEAR_INT_STATUS_CMD);
return IRQ_HANDLED;
}