Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input fixes from Dmitry Torokhov: "The main change is that we are reverting blanket enablement of SMBus mode for devices with Elan touchpads that report BIOS release date as 2018+ because there are older boxes with updated BIOSes that still do not work well in SMbus mode. We will have to establish whitelist for SMBus mode it looks like" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Revert "Input: elantech - enable SMBus on new (2018+) systems" Input: synaptics-rmi4 - avoid processing unknown IRQs Input: soc_button_array - partial revert of support for newer surface devices Input: goodix - add support for 9-bytes reports Input: da9063 - fix capability and drop KEY_SLEEP
This commit is contained in:
@@ -232,10 +232,7 @@ static int da9063_onkey_probe(struct platform_device *pdev)
|
|||||||
onkey->input->phys = onkey->phys;
|
onkey->input->phys = onkey->phys;
|
||||||
onkey->input->dev.parent = &pdev->dev;
|
onkey->input->dev.parent = &pdev->dev;
|
||||||
|
|
||||||
if (onkey->key_power)
|
input_set_capability(onkey->input, EV_KEY, KEY_POWER);
|
||||||
input_set_capability(onkey->input, EV_KEY, KEY_POWER);
|
|
||||||
|
|
||||||
input_set_capability(onkey->input, EV_KEY, KEY_SLEEP);
|
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&onkey->work, da9063_poll_on);
|
INIT_DELAYED_WORK(&onkey->work, da9063_poll_on);
|
||||||
|
|
||||||
|
@@ -92,11 +92,18 @@ soc_button_device_create(struct platform_device *pdev,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index);
|
gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index);
|
||||||
if (gpio < 0 && gpio != -ENOENT) {
|
if (!gpio_is_valid(gpio)) {
|
||||||
error = gpio;
|
/*
|
||||||
goto err_free_mem;
|
* Skip GPIO if not present. Note we deliberately
|
||||||
} else if (!gpio_is_valid(gpio)) {
|
* ignore -EPROBE_DEFER errors here. On some devices
|
||||||
/* Skip GPIO if not present */
|
* Intel is using so called virtual GPIOs which are not
|
||||||
|
* GPIOs at all but some way for AML code to check some
|
||||||
|
* random status bits without need a custom opregion.
|
||||||
|
* In some cases the resources table we parse points to
|
||||||
|
* such a virtual GPIO, since these are not real GPIOs
|
||||||
|
* we do not have a driver for these so they will never
|
||||||
|
* show up, therefore we ignore -EPROBE_DEFER.
|
||||||
|
*/
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1827,31 +1827,6 @@ static int elantech_create_smbus(struct psmouse *psmouse,
|
|||||||
leave_breadcrumbs);
|
leave_breadcrumbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool elantech_use_host_notify(struct psmouse *psmouse,
|
|
||||||
struct elantech_device_info *info)
|
|
||||||
{
|
|
||||||
if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
switch (info->bus) {
|
|
||||||
case ETP_BUS_PS2_ONLY:
|
|
||||||
/* expected case */
|
|
||||||
break;
|
|
||||||
case ETP_BUS_SMB_HST_NTFY_ONLY:
|
|
||||||
case ETP_BUS_PS2_SMB_HST_NTFY:
|
|
||||||
/* SMbus implementation is stable since 2018 */
|
|
||||||
if (dmi_get_bios_year() >= 2018)
|
|
||||||
return true;
|
|
||||||
/* fall through */
|
|
||||||
default:
|
|
||||||
psmouse_dbg(psmouse,
|
|
||||||
"Ignoring SMBus bus provider %d\n", info->bus);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* elantech_setup_smbus - called once the PS/2 devices are enumerated
|
* elantech_setup_smbus - called once the PS/2 devices are enumerated
|
||||||
* and decides to instantiate a SMBus InterTouch device.
|
* and decides to instantiate a SMBus InterTouch device.
|
||||||
@@ -1871,7 +1846,7 @@ static int elantech_setup_smbus(struct psmouse *psmouse,
|
|||||||
* i2c_blacklist_pnp_ids.
|
* i2c_blacklist_pnp_ids.
|
||||||
* Old ICs are up to the user to decide.
|
* Old ICs are up to the user to decide.
|
||||||
*/
|
*/
|
||||||
if (!elantech_use_host_notify(psmouse, info) ||
|
if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version) ||
|
||||||
psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids))
|
psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
@@ -1891,6 +1866,34 @@ static int elantech_setup_smbus(struct psmouse *psmouse,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool elantech_use_host_notify(struct psmouse *psmouse,
|
||||||
|
struct elantech_device_info *info)
|
||||||
|
{
|
||||||
|
if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
switch (info->bus) {
|
||||||
|
case ETP_BUS_PS2_ONLY:
|
||||||
|
/* expected case */
|
||||||
|
break;
|
||||||
|
case ETP_BUS_SMB_ALERT_ONLY:
|
||||||
|
/* fall-through */
|
||||||
|
case ETP_BUS_PS2_SMB_ALERT:
|
||||||
|
psmouse_dbg(psmouse, "Ignoring SMBus provider through alert protocol.\n");
|
||||||
|
break;
|
||||||
|
case ETP_BUS_SMB_HST_NTFY_ONLY:
|
||||||
|
/* fall-through */
|
||||||
|
case ETP_BUS_PS2_SMB_HST_NTFY:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
psmouse_dbg(psmouse,
|
||||||
|
"Ignoring SMBus bus provider %d.\n",
|
||||||
|
info->bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int elantech_init_smbus(struct psmouse *psmouse)
|
int elantech_init_smbus(struct psmouse *psmouse)
|
||||||
{
|
{
|
||||||
struct elantech_device_info info;
|
struct elantech_device_info info;
|
||||||
|
@@ -146,7 +146,7 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&data->irq_mutex);
|
mutex_lock(&data->irq_mutex);
|
||||||
bitmap_and(data->irq_status, data->irq_status, data->current_irq_mask,
|
bitmap_and(data->irq_status, data->irq_status, data->fn_irq_bits,
|
||||||
data->irq_count);
|
data->irq_count);
|
||||||
/*
|
/*
|
||||||
* At this point, irq_status has all bits that are set in the
|
* At this point, irq_status has all bits that are set in the
|
||||||
@@ -385,6 +385,8 @@ static int rmi_driver_set_irq_bits(struct rmi_device *rmi_dev,
|
|||||||
bitmap_copy(data->current_irq_mask, data->new_irq_mask,
|
bitmap_copy(data->current_irq_mask, data->new_irq_mask,
|
||||||
data->num_of_irq_regs);
|
data->num_of_irq_regs);
|
||||||
|
|
||||||
|
bitmap_or(data->fn_irq_bits, data->fn_irq_bits, mask, data->irq_count);
|
||||||
|
|
||||||
error_unlock:
|
error_unlock:
|
||||||
mutex_unlock(&data->irq_mutex);
|
mutex_unlock(&data->irq_mutex);
|
||||||
return error;
|
return error;
|
||||||
@@ -398,6 +400,8 @@ static int rmi_driver_clear_irq_bits(struct rmi_device *rmi_dev,
|
|||||||
struct device *dev = &rmi_dev->dev;
|
struct device *dev = &rmi_dev->dev;
|
||||||
|
|
||||||
mutex_lock(&data->irq_mutex);
|
mutex_lock(&data->irq_mutex);
|
||||||
|
bitmap_andnot(data->fn_irq_bits,
|
||||||
|
data->fn_irq_bits, mask, data->irq_count);
|
||||||
bitmap_andnot(data->new_irq_mask,
|
bitmap_andnot(data->new_irq_mask,
|
||||||
data->current_irq_mask, mask, data->irq_count);
|
data->current_irq_mask, mask, data->irq_count);
|
||||||
|
|
||||||
|
@@ -53,6 +53,7 @@ struct goodix_ts_data {
|
|||||||
const char *cfg_name;
|
const char *cfg_name;
|
||||||
struct completion firmware_loading_complete;
|
struct completion firmware_loading_complete;
|
||||||
unsigned long irq_flags;
|
unsigned long irq_flags;
|
||||||
|
unsigned int contact_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GOODIX_GPIO_INT_NAME "irq"
|
#define GOODIX_GPIO_INT_NAME "irq"
|
||||||
@@ -62,6 +63,7 @@ struct goodix_ts_data {
|
|||||||
#define GOODIX_MAX_WIDTH 4096
|
#define GOODIX_MAX_WIDTH 4096
|
||||||
#define GOODIX_INT_TRIGGER 1
|
#define GOODIX_INT_TRIGGER 1
|
||||||
#define GOODIX_CONTACT_SIZE 8
|
#define GOODIX_CONTACT_SIZE 8
|
||||||
|
#define GOODIX_MAX_CONTACT_SIZE 9
|
||||||
#define GOODIX_MAX_CONTACTS 10
|
#define GOODIX_MAX_CONTACTS 10
|
||||||
|
|
||||||
#define GOODIX_CONFIG_MAX_LENGTH 240
|
#define GOODIX_CONFIG_MAX_LENGTH 240
|
||||||
@@ -144,6 +146,19 @@ static const struct dmi_system_id rotated_screen[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct dmi_system_id nine_bytes_report[] = {
|
||||||
|
#if defined(CONFIG_DMI) && defined(CONFIG_X86)
|
||||||
|
{
|
||||||
|
.ident = "Lenovo YogaBook",
|
||||||
|
/* YB1-X91L/F and YB1-X90L/F */
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* goodix_i2c_read - read data from a register of the i2c slave device.
|
* goodix_i2c_read - read data from a register of the i2c slave device.
|
||||||
*
|
*
|
||||||
@@ -249,7 +264,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
|
|||||||
max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT);
|
max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT);
|
||||||
do {
|
do {
|
||||||
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR,
|
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR,
|
||||||
data, GOODIX_CONTACT_SIZE + 1);
|
data, ts->contact_size + 1);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(&ts->client->dev, "I2C transfer error: %d\n",
|
dev_err(&ts->client->dev, "I2C transfer error: %d\n",
|
||||||
error);
|
error);
|
||||||
@@ -262,12 +277,12 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
|
|||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
|
|
||||||
if (touch_num > 1) {
|
if (touch_num > 1) {
|
||||||
data += 1 + GOODIX_CONTACT_SIZE;
|
data += 1 + ts->contact_size;
|
||||||
error = goodix_i2c_read(ts->client,
|
error = goodix_i2c_read(ts->client,
|
||||||
GOODIX_READ_COOR_ADDR +
|
GOODIX_READ_COOR_ADDR +
|
||||||
1 + GOODIX_CONTACT_SIZE,
|
1 + ts->contact_size,
|
||||||
data,
|
data,
|
||||||
GOODIX_CONTACT_SIZE *
|
ts->contact_size *
|
||||||
(touch_num - 1));
|
(touch_num - 1));
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
@@ -286,7 +301,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
|
static void goodix_ts_report_touch_8b(struct goodix_ts_data *ts, u8 *coor_data)
|
||||||
{
|
{
|
||||||
int id = coor_data[0] & 0x0F;
|
int id = coor_data[0] & 0x0F;
|
||||||
int input_x = get_unaligned_le16(&coor_data[1]);
|
int input_x = get_unaligned_le16(&coor_data[1]);
|
||||||
@@ -301,6 +316,21 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
|
|||||||
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
|
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void goodix_ts_report_touch_9b(struct goodix_ts_data *ts, u8 *coor_data)
|
||||||
|
{
|
||||||
|
int id = coor_data[1] & 0x0F;
|
||||||
|
int input_x = get_unaligned_le16(&coor_data[3]);
|
||||||
|
int input_y = get_unaligned_le16(&coor_data[5]);
|
||||||
|
int input_w = get_unaligned_le16(&coor_data[7]);
|
||||||
|
|
||||||
|
input_mt_slot(ts->input_dev, id);
|
||||||
|
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
|
||||||
|
touchscreen_report_pos(ts->input_dev, &ts->prop,
|
||||||
|
input_x, input_y, true);
|
||||||
|
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
|
||||||
|
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* goodix_process_events - Process incoming events
|
* goodix_process_events - Process incoming events
|
||||||
*
|
*
|
||||||
@@ -311,7 +341,7 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
|
|||||||
*/
|
*/
|
||||||
static void goodix_process_events(struct goodix_ts_data *ts)
|
static void goodix_process_events(struct goodix_ts_data *ts)
|
||||||
{
|
{
|
||||||
u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
|
u8 point_data[1 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
|
||||||
int touch_num;
|
int touch_num;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -326,8 +356,12 @@ static void goodix_process_events(struct goodix_ts_data *ts)
|
|||||||
input_report_key(ts->input_dev, KEY_LEFTMETA, point_data[0] & BIT(4));
|
input_report_key(ts->input_dev, KEY_LEFTMETA, point_data[0] & BIT(4));
|
||||||
|
|
||||||
for (i = 0; i < touch_num; i++)
|
for (i = 0; i < touch_num; i++)
|
||||||
goodix_ts_report_touch(ts,
|
if (ts->contact_size == 9)
|
||||||
&point_data[1 + GOODIX_CONTACT_SIZE * i]);
|
goodix_ts_report_touch_9b(ts,
|
||||||
|
&point_data[1 + ts->contact_size * i]);
|
||||||
|
else
|
||||||
|
goodix_ts_report_touch_8b(ts,
|
||||||
|
&point_data[1 + ts->contact_size * i]);
|
||||||
|
|
||||||
input_mt_sync_frame(ts->input_dev);
|
input_mt_sync_frame(ts->input_dev);
|
||||||
input_sync(ts->input_dev);
|
input_sync(ts->input_dev);
|
||||||
@@ -730,6 +764,13 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
|
|||||||
"Applying '180 degrees rotated screen' quirk\n");
|
"Applying '180 degrees rotated screen' quirk\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dmi_check_system(nine_bytes_report)) {
|
||||||
|
ts->contact_size = 9;
|
||||||
|
|
||||||
|
dev_dbg(&ts->client->dev,
|
||||||
|
"Non-standard 9-bytes report format quirk\n");
|
||||||
|
}
|
||||||
|
|
||||||
error = input_mt_init_slots(ts->input_dev, ts->max_touch_num,
|
error = input_mt_init_slots(ts->input_dev, ts->max_touch_num,
|
||||||
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
|
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -810,6 +851,7 @@ static int goodix_ts_probe(struct i2c_client *client,
|
|||||||
ts->client = client;
|
ts->client = client;
|
||||||
i2c_set_clientdata(client, ts);
|
i2c_set_clientdata(client, ts);
|
||||||
init_completion(&ts->firmware_loading_complete);
|
init_completion(&ts->firmware_loading_complete);
|
||||||
|
ts->contact_size = GOODIX_CONTACT_SIZE;
|
||||||
|
|
||||||
error = goodix_get_gpio_config(ts);
|
error = goodix_get_gpio_config(ts);
|
||||||
if (error)
|
if (error)
|
||||||
|
Reference in New Issue
Block a user