Commit c92067ae authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

 - the main change is a fix for my brain-dead patch to PS/2 button
   reporting for some protocols that made it in 4.17

 - there is a new driver for Spreadtum vibrator that I intended to send
   during merge window but ended up not sending the 2nd pull request.
   Given that this is a brand new driver we should not see regressions
   here

 - a fixup to Elantech PS/2 driver to avoid decoding errors on Thinkpad
   P52

 - addition of few more ACPI IDs for Silead and Elan drivers

 - RMI4 is switched to using IRQ domain code instead of rolling its own
   implementation

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: psmouse - fix button reporting for basic protocols
  Input: xpad - fix GPD Win 2 controller name
  Input: elan_i2c_smbus - fix more potential stack buffer overflows
  Input: elan_i2c - add ELAN0618 (Lenovo v330 15IKB) ACPI ID
  Input: elantech - fix V4 report decoding for module with middle key
  Input: elantech - enable middle button of touchpads on ThinkPad P52
  Input: do not assign new tracking ID when changing tool type
  Input: make input_report_slot_state() return boolean
  Input: synaptics-rmi4 - fix axis-swap behavior
  Input: synaptics-rmi4 - fix the error return code in rmi_probe_interrupts()
  Input: synaptics-rmi4 - convert irq distribution to irq_domain
  Input: silead - add MSSL0002 ACPI HID
  Input: goldfish_events - fix checkpatch warnings
  Input: add Spreadtrum vibrator driver
parents 896a3492 03ae3a9c
Spreadtrum SC27xx PMIC Vibrator
Required properties:
- compatible: should be "sprd,sc2731-vibrator".
- reg: address of vibrator control register.
Example :
sc2731_pmic: pmic@0 {
compatible = "sprd,sc2731";
reg = <0>;
spi-max-frequency = <26000000>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
#address-cells = <1>;
#size-cells = <0>;
vibrator@eb4 {
compatible = "sprd,sc2731-vibrator";
reg = <0xeb4>;
};
};
...@@ -131,8 +131,10 @@ EXPORT_SYMBOL(input_mt_destroy_slots); ...@@ -131,8 +131,10 @@ EXPORT_SYMBOL(input_mt_destroy_slots);
* inactive, or if the tool type is changed, a new tracking id is * inactive, or if the tool type is changed, a new tracking id is
* assigned to the slot. The tool type is only reported if the * assigned to the slot. The tool type is only reported if the
* corresponding absbit field is set. * corresponding absbit field is set.
*
* Returns true if contact is active.
*/ */
void input_mt_report_slot_state(struct input_dev *dev, bool input_mt_report_slot_state(struct input_dev *dev,
unsigned int tool_type, bool active) unsigned int tool_type, bool active)
{ {
struct input_mt *mt = dev->mt; struct input_mt *mt = dev->mt;
...@@ -140,22 +142,24 @@ void input_mt_report_slot_state(struct input_dev *dev, ...@@ -140,22 +142,24 @@ void input_mt_report_slot_state(struct input_dev *dev,
int id; int id;
if (!mt) if (!mt)
return; return false;
slot = &mt->slots[mt->slot]; slot = &mt->slots[mt->slot];
slot->frame = mt->frame; slot->frame = mt->frame;
if (!active) { if (!active) {
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
return; return false;
} }
id = input_mt_get_value(slot, ABS_MT_TRACKING_ID); id = input_mt_get_value(slot, ABS_MT_TRACKING_ID);
if (id < 0 || input_mt_get_value(slot, ABS_MT_TOOL_TYPE) != tool_type) if (id < 0)
id = input_mt_new_trkid(mt); id = input_mt_new_trkid(mt);
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id); input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type); input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);
return true;
} }
EXPORT_SYMBOL(input_mt_report_slot_state); EXPORT_SYMBOL(input_mt_report_slot_state);
......
...@@ -125,7 +125,7 @@ static const struct xpad_device { ...@@ -125,7 +125,7 @@ static const struct xpad_device {
u8 mapping; u8 mapping;
u8 xtype; u8 xtype;
} xpad_device[] = { } xpad_device[] = {
{ 0x0079, 0x18d4, "GPD Win 2 Controller", 0, XTYPE_XBOX360 }, { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 },
{ 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX },
{ 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX },
{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
......
...@@ -45,7 +45,7 @@ struct event_dev { ...@@ -45,7 +45,7 @@ struct event_dev {
static irqreturn_t events_interrupt(int irq, void *dev_id) static irqreturn_t events_interrupt(int irq, void *dev_id)
{ {
struct event_dev *edev = dev_id; struct event_dev *edev = dev_id;
unsigned type, code, value; unsigned int type, code, value;
type = __raw_readl(edev->addr + REG_READ); type = __raw_readl(edev->addr + REG_READ);
code = __raw_readl(edev->addr + REG_READ); code = __raw_readl(edev->addr + REG_READ);
...@@ -57,7 +57,7 @@ static irqreturn_t events_interrupt(int irq, void *dev_id) ...@@ -57,7 +57,7 @@ static irqreturn_t events_interrupt(int irq, void *dev_id)
} }
static void events_import_bits(struct event_dev *edev, static void events_import_bits(struct event_dev *edev,
unsigned long bits[], unsigned type, size_t count) unsigned long bits[], unsigned int type, size_t count)
{ {
void __iomem *addr = edev->addr; void __iomem *addr = edev->addr;
int i, j; int i, j;
...@@ -99,6 +99,7 @@ static void events_import_abs_params(struct event_dev *edev) ...@@ -99,6 +99,7 @@ static void events_import_abs_params(struct event_dev *edev)
for (j = 0; j < ARRAY_SIZE(val); j++) { for (j = 0; j < ARRAY_SIZE(val); j++) {
int offset = (i * ARRAY_SIZE(val) + j) * sizeof(u32); int offset = (i * ARRAY_SIZE(val) + j) * sizeof(u32);
val[j] = __raw_readl(edev->addr + REG_DATA + offset); val[j] = __raw_readl(edev->addr + REG_DATA + offset);
} }
...@@ -112,7 +113,7 @@ static int events_probe(struct platform_device *pdev) ...@@ -112,7 +113,7 @@ static int events_probe(struct platform_device *pdev)
struct input_dev *input_dev; struct input_dev *input_dev;
struct event_dev *edev; struct event_dev *edev;
struct resource *res; struct resource *res;
unsigned keymapnamelen; unsigned int keymapnamelen;
void __iomem *addr; void __iomem *addr;
int irq; int irq;
int i; int i;
...@@ -150,7 +151,7 @@ static int events_probe(struct platform_device *pdev) ...@@ -150,7 +151,7 @@ static int events_probe(struct platform_device *pdev)
for (i = 0; i < keymapnamelen; i++) for (i = 0; i < keymapnamelen; i++)
edev->name[i] = __raw_readb(edev->addr + REG_DATA + i); edev->name[i] = __raw_readb(edev->addr + REG_DATA + i);
pr_debug("events_probe() keymap=%s\n", edev->name); pr_debug("%s: keymap=%s\n", __func__, edev->name);
input_dev->name = edev->name; input_dev->name = edev->name;
input_dev->id.bustype = BUS_HOST; input_dev->id.bustype = BUS_HOST;
......
...@@ -841,4 +841,14 @@ config INPUT_RAVE_SP_PWRBUTTON ...@@ -841,4 +841,14 @@ config INPUT_RAVE_SP_PWRBUTTON
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called rave-sp-pwrbutton. module will be called rave-sp-pwrbutton.
config INPUT_SC27XX_VIBRA
tristate "Spreadtrum sc27xx vibrator support"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
select INPUT_FF_MEMLESS
help
This option enables support for Spreadtrum sc27xx vibrator driver.
To compile this driver as a module, choose M here. The module will
be called sc27xx_vibra.
endif endif
...@@ -66,6 +66,7 @@ obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o ...@@ -66,6 +66,7 @@ obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o
obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o
obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
obj-$(CONFIG_INPUT_RK805_PWRKEY) += rk805-pwrkey.o obj-$(CONFIG_INPUT_RK805_PWRKEY) += rk805-pwrkey.o
obj-$(CONFIG_INPUT_SC27XX_VIBRA) += sc27xx-vibra.o
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o
obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Spreadtrum Communications Inc.
*/
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/input.h>
#include <linux/workqueue.h>
#define CUR_DRV_CAL_SEL GENMASK(13, 12)
#define SLP_LDOVIBR_PD_EN BIT(9)
#define LDO_VIBR_PD BIT(8)
struct vibra_info {
struct input_dev *input_dev;
struct work_struct play_work;
struct regmap *regmap;
u32 base;
u32 strength;
bool enabled;
};
static void sc27xx_vibra_set(struct vibra_info *info, bool on)
{
if (on) {
regmap_update_bits(info->regmap, info->base, LDO_VIBR_PD, 0);
regmap_update_bits(info->regmap, info->base,
SLP_LDOVIBR_PD_EN, 0);
info->enabled = true;
} else {
regmap_update_bits(info->regmap, info->base, LDO_VIBR_PD,
LDO_VIBR_PD);
regmap_update_bits(info->regmap, info->base,
SLP_LDOVIBR_PD_EN, SLP_LDOVIBR_PD_EN);
info->enabled = false;
}
}
static int sc27xx_vibra_hw_init(struct vibra_info *info)
{
return regmap_update_bits(info->regmap, info->base, CUR_DRV_CAL_SEL, 0);
}
static void sc27xx_vibra_play_work(struct work_struct *work)
{
struct vibra_info *info = container_of(work, struct vibra_info,
play_work);
if (info->strength && !info->enabled)
sc27xx_vibra_set(info, true);
else if (info->strength == 0 && info->enabled)
sc27xx_vibra_set(info, false);
}
static int sc27xx_vibra_play(struct input_dev *input, void *data,
struct ff_effect *effect)
{
struct vibra_info *info = input_get_drvdata(input);
info->strength = effect->u.rumble.weak_magnitude;
schedule_work(&info->play_work);
return 0;
}
static void sc27xx_vibra_close(struct input_dev *input)
{
struct vibra_info *info = input_get_drvdata(input);
cancel_work_sync(&info->play_work);
if (info->enabled)
sc27xx_vibra_set(info, false);
}
static int sc27xx_vibra_probe(struct platform_device *pdev)
{
struct vibra_info *info;
int error;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!info->regmap) {
dev_err(&pdev->dev, "failed to get vibrator regmap.\n");
return -ENODEV;
}
error = device_property_read_u32(&pdev->dev, "reg", &info->base);
if (error) {
dev_err(&pdev->dev, "failed to get vibrator base address.\n");
return error;
}
info->input_dev = devm_input_allocate_device(&pdev->dev);
if (!info->input_dev) {
dev_err(&pdev->dev, "failed to allocate input device.\n");
return -ENOMEM;
}
info->input_dev->name = "sc27xx:vibrator";
info->input_dev->id.version = 0;
info->input_dev->close = sc27xx_vibra_close;
input_set_drvdata(info->input_dev, info);
input_set_capability(info->input_dev, EV_FF, FF_RUMBLE);
INIT_WORK(&info->play_work, sc27xx_vibra_play_work);
info->enabled = false;
error = sc27xx_vibra_hw_init(info);
if (error) {
dev_err(&pdev->dev, "failed to initialize the vibrator.\n");
return error;
}
error = input_ff_create_memless(info->input_dev, NULL,
sc27xx_vibra_play);
if (error) {
dev_err(&pdev->dev, "failed to register vibrator to FF.\n");
return error;
}
error = input_register_device(info->input_dev);
if (error) {
dev_err(&pdev->dev, "failed to register input device.\n");
return error;
}
return 0;
}
static const struct of_device_id sc27xx_vibra_of_match[] = {
{ .compatible = "sprd,sc2731-vibrator", },
{}
};
MODULE_DEVICE_TABLE(of, sc27xx_vibra_of_match);
static struct platform_driver sc27xx_vibra_driver = {
.driver = {
.name = "sc27xx-vibrator",
.of_match_table = sc27xx_vibra_of_match,
},
.probe = sc27xx_vibra_probe,
};
module_platform_driver(sc27xx_vibra_driver);
MODULE_DESCRIPTION("Spreadtrum SC27xx Vibrator Driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Xiaotong Lu <xiaotong.lu@spreadtrum.com>");
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#define ETP_DISABLE_POWER 0x0001 #define ETP_DISABLE_POWER 0x0001
#define ETP_PRESSURE_OFFSET 25 #define ETP_PRESSURE_OFFSET 25
#define ETP_CALIBRATE_MAX_LEN 3
/* IAP Firmware handling */ /* IAP Firmware handling */
#define ETP_PRODUCT_ID_FORMAT_STRING "%d.0" #define ETP_PRODUCT_ID_FORMAT_STRING "%d.0"
#define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin" #define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin"
......
...@@ -613,7 +613,7 @@ static ssize_t calibrate_store(struct device *dev, ...@@ -613,7 +613,7 @@ static ssize_t calibrate_store(struct device *dev,
int tries = 20; int tries = 20;
int retval; int retval;
int error; int error;
u8 val[3]; u8 val[ETP_CALIBRATE_MAX_LEN];
retval = mutex_lock_interruptible(&data->sysfs_mutex); retval = mutex_lock_interruptible(&data->sysfs_mutex);
if (retval) if (retval)
...@@ -1345,6 +1345,7 @@ static const struct acpi_device_id elan_acpi_id[] = { ...@@ -1345,6 +1345,7 @@ static const struct acpi_device_id elan_acpi_id[] = {
{ "ELAN060C", 0 }, { "ELAN060C", 0 },
{ "ELAN0611", 0 }, { "ELAN0611", 0 },
{ "ELAN0612", 0 }, { "ELAN0612", 0 },
{ "ELAN0618", 0 },
{ "ELAN1000", 0 }, { "ELAN1000", 0 },
{ } { }
}; };
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
static int elan_smbus_initialize(struct i2c_client *client) static int elan_smbus_initialize(struct i2c_client *client)
{ {
u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 }; u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 };
u8 values[ETP_SMBUS_HELLOPACKET_LEN] = { 0, 0, 0, 0, 0 }; u8 values[I2C_SMBUS_BLOCK_MAX] = {0};
int len, error; int len, error;
/* Get hello packet */ /* Get hello packet */
...@@ -117,12 +117,16 @@ static int elan_smbus_calibrate(struct i2c_client *client) ...@@ -117,12 +117,16 @@ static int elan_smbus_calibrate(struct i2c_client *client)
static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val) static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val)
{ {
int error; int error;
u8 buf[I2C_SMBUS_BLOCK_MAX] = {0};
BUILD_BUG_ON(ETP_CALIBRATE_MAX_LEN > sizeof(buf));
error = i2c_smbus_read_block_data(client, error = i2c_smbus_read_block_data(client,
ETP_SMBUS_CALIBRATE_QUERY, val); ETP_SMBUS_CALIBRATE_QUERY, buf);
if (error < 0) if (error < 0)
return error; return error;
memcpy(val, buf, ETP_CALIBRATE_MAX_LEN);
return 0; return 0;
} }
...@@ -472,6 +476,8 @@ static int elan_smbus_get_report(struct i2c_client *client, u8 *report) ...@@ -472,6 +476,8 @@ static int elan_smbus_get_report(struct i2c_client *client, u8 *report)
{ {
int len; int len;
BUILD_BUG_ON(I2C_SMBUS_BLOCK_MAX > ETP_SMBUS_REPORT_LEN);
len = i2c_smbus_read_block_data(client, len = i2c_smbus_read_block_data(client,
ETP_SMBUS_PACKET_QUERY, ETP_SMBUS_PACKET_QUERY,
&report[ETP_SMBUS_REPORT_OFFSET]); &report[ETP_SMBUS_REPORT_OFFSET]);
......
...@@ -799,7 +799,7 @@ static int elantech_packet_check_v4(struct psmouse *psmouse) ...@@ -799,7 +799,7 @@ static int elantech_packet_check_v4(struct psmouse *psmouse)
else if (ic_version == 7 && etd->info.samples[1] == 0x2A) else if (ic_version == 7 && etd->info.samples[1] == 0x2A)
sanity_check = ((packet[3] & 0x1c) == 0x10); sanity_check = ((packet[3] & 0x1c) == 0x10);
else else
sanity_check = ((packet[0] & 0x0c) == 0x04 && sanity_check = ((packet[0] & 0x08) == 0x00 &&
(packet[3] & 0x1c) == 0x10); (packet[3] & 0x1c) == 0x10);
if (!sanity_check) if (!sanity_check)
...@@ -1175,6 +1175,12 @@ static const struct dmi_system_id elantech_dmi_has_middle_button[] = { ...@@ -1175,6 +1175,12 @@ static const struct dmi_system_id elantech_dmi_has_middle_button[] = {
{ } { }
}; };
static const char * const middle_button_pnp_ids[] = {
"LEN2131", /* ThinkPad P52 w/ NFC */
"LEN2132", /* ThinkPad P52 */
NULL
};
/* /*
* Set the appropriate event bits for the input subsystem * Set the appropriate event bits for the input subsystem
*/ */
...@@ -1194,7 +1200,8 @@ static int elantech_set_input_params(struct psmouse *psmouse) ...@@ -1194,7 +1200,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
__clear_bit(EV_REL, dev->evbit); __clear_bit(EV_REL, dev->evbit);
__set_bit(BTN_LEFT, dev->keybit); __set_bit(BTN_LEFT, dev->keybit);
if (dmi_check_system(elantech_dmi_has_middle_button)) if (dmi_check_system(elantech_dmi_has_middle_button) ||
psmouse_matches_pnp_id(psmouse, middle_button_pnp_ids))
__set_bit(BTN_MIDDLE, dev->keybit); __set_bit(BTN_MIDDLE, dev->keybit);
__set_bit(BTN_RIGHT, dev->keybit); __set_bit(BTN_RIGHT, dev->keybit);
......
...@@ -192,8 +192,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) ...@@ -192,8 +192,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
else else
input_report_rel(dev, REL_WHEEL, -wheel); input_report_rel(dev, REL_WHEEL, -wheel);
input_report_key(dev, BTN_SIDE, BIT(4)); input_report_key(dev, BTN_SIDE, packet[3] & BIT(4));
input_report_key(dev, BTN_EXTRA, BIT(5)); input_report_key(dev, BTN_EXTRA, packet[3] & BIT(5));
break; break;
} }
break; break;
...@@ -203,13 +203,13 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) ...@@ -203,13 +203,13 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
input_report_rel(dev, REL_WHEEL, -(s8) packet[3]); input_report_rel(dev, REL_WHEEL, -(s8) packet[3]);
/* Extra buttons on Genius NewNet 3D */ /* Extra buttons on Genius NewNet 3D */
input_report_key(dev, BTN_SIDE, BIT(6)); input_report_key(dev, BTN_SIDE, packet[0] & BIT(6));
input_report_key(dev, BTN_EXTRA, BIT(7)); input_report_key(dev, BTN_EXTRA, packet[0] & BIT(7));
break; break;
case PSMOUSE_THINKPS: case PSMOUSE_THINKPS:
/* Extra button on ThinkingMouse */ /* Extra button on ThinkingMouse */
input_report_key(dev, BTN_EXTRA, BIT(3)); input_report_key(dev, BTN_EXTRA, packet[0] & BIT(3));
/* /*
* Without this bit of weirdness moving up gives wildly * Without this bit of weirdness moving up gives wildly
...@@ -223,7 +223,7 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) ...@@ -223,7 +223,7 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
* Cortron PS2 Trackball reports SIDE button in the * Cortron PS2 Trackball reports SIDE button in the
* 4th bit of the first byte. * 4th bit of the first byte.
*/ */
input_report_key(dev, BTN_SIDE, BIT(3)); input_report_key(dev, BTN_SIDE, packet[0] & BIT(3));
packet[0] |= BIT(3); packet[0] |= BIT(3);
break; break;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# #
config RMI4_CORE config RMI4_CORE
tristate "Synaptics RMI4 bus support" tristate "Synaptics RMI4 bus support"
select IRQ_DOMAIN
help help
Say Y here if you want to support the Synaptics RMI4 bus. This is Say Y here if you want to support the Synaptics RMI4 bus. This is
required for all RMI4 device support. required for all RMI4 device support.
......
...@@ -32,15 +32,15 @@ void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor, ...@@ -32,15 +32,15 @@ void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
if (obj->type == RMI_2D_OBJECT_NONE) if (obj->type == RMI_2D_OBJECT_NONE)
return; return;
if (axis_align->swap_axes)
swap(obj->x, obj->y);
if (axis_align->flip_x) if (axis_align->flip_x)
obj->x = sensor->max_x - obj->x; obj->x = sensor->max_x - obj->x;
if (axis_align->flip_y) if (axis_align->flip_y)
obj->y = sensor->max_y - obj->y; obj->y = sensor->max_y - obj->y;
if (axis_align->swap_axes)
swap(obj->x, obj->y);
/* /*
* Here checking if X offset or y offset are specified is * Here checking if X offset or y offset are specified is
* redundant. We just add the offsets or clip the values. * redundant. We just add the offsets or clip the values.
...@@ -120,15 +120,15 @@ void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y) ...@@ -120,15 +120,15 @@ void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y)
x = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)x)); x = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)x));
y = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)y)); y = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)y));
if (axis_align->swap_axes)
swap(x, y);
if (axis_align->flip_x) if (axis_align->flip_x)
x = min(RMI_2D_REL_POS_MAX, -x); x = min(RMI_2D_REL_POS_MAX, -x);
if (axis_align->flip_y) if (axis_align->flip_y)
y = min(RMI_2D_REL_POS_MAX, -y); y = min(RMI_2D_REL_POS_MAX, -y);
if (axis_align->swap_axes)
swap(x, y);
if (x || y) { if (x || y) {
input_report_rel(sensor->input, REL_X, x); input_report_rel(sensor->input, REL_X, x);
input_report_rel(sensor->input, REL_Y, y); input_report_rel(sensor->input, REL_Y, y);
...@@ -141,17 +141,10 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor) ...@@ -141,17 +141,10 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
struct input_dev *input = sensor->input; struct input_dev *input = sensor->input;
int res_x; int res_x;
int res_y; int res_y;
int max_x, max_y;
int input_flags = 0; int input_flags = 0;
if (sensor->report_abs) { if (sensor->report_abs) {
if (sensor->axis_align.swap_axes) {
swap(sensor->max_x, sensor->max_y);
swap(sensor->axis_align.clip_x_low,
sensor->axis_align.clip_y_low);
swap(sensor->axis_align.clip_x_high,
sensor->axis_align.clip_y_high);
}
sensor->min_x = sensor->axis_align.clip_x_low; sensor->min_x = sensor->axis_align.clip_x_low;
if (sensor->axis_align.clip_x_high) if (sensor->axis_align.clip_x_high)
sensor->max_x = min(sensor->max_x, sensor->max_x = min(sensor->max_x,
...@@ -163,14 +156,19 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor) ...@@ -163,14 +156,19 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
sensor->axis_align.clip_y_high); sensor->axis_align.clip_y_high);
set_bit(EV_ABS, input->evbit); set_bit(EV_ABS, input->evbit);
input_set_abs_params(input, ABS_MT_POSITION_X, 0, sensor->max_x,
0, 0); max_x = sensor->max_x;
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, sensor->max_y, max_y = sensor->max_y;
0, 0); if (sensor->axis_align.swap_axes)
swap(max_x, max_y);
input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
if (sensor->x_mm && sensor->y_mm) { if (sensor->x_mm && sensor->y_mm) {
res_x = (sensor->max_x - sensor->min_x) / sensor->x_mm; res_x = (sensor->max_x - sensor->min_x) / sensor->x_mm;
res_y = (sensor->max_y - sensor->min_y) / sensor->y_mm; res_y = (sensor->max_y - sensor->min_y) / sensor->y_mm;
if (sensor->axis_align.swap_axes)
swap(res_x, res_y);
input_abs_set_res(input, ABS_X, res_x); input_abs_set_res(input, ABS_X, res_x);
input_abs_set_res(input, ABS_Y, res_y); input_abs_set_res(input, ABS_Y, res_y);
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/rmi.h> #include <linux/rmi.h>
...@@ -167,6 +169,39 @@ static inline void rmi_function_of_probe(struct rmi_function *fn) ...@@ -167,6 +169,39 @@ static inline void rmi_function_of_probe(struct rmi_function *fn)
{} {}
#endif #endif
static struct irq_chip rmi_irq_chip = {
.name = "rmi4",
};
static int rmi_create_function_irq(struct rmi_function *fn,
struct rmi_function_handler *handler)
{
struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
int i, error;
for (i = 0; i < fn->num_of_irqs; i++) {
set_bit(fn->irq_pos + i, fn->irq_mask);
fn->irq[i] = irq_create_mapping(drvdata->irqdomain,
fn->irq_pos + i);
irq_set_chip_data(fn->irq[i], fn);
irq_set_chip_and_handler(fn->irq[i], &rmi_irq_chip,
handle_simple_irq);
irq_set_nested_thread(fn->irq[i], 1);
error = devm_request_threaded_irq(&fn->dev, fn->irq[i], NULL,
handler->attention, IRQF_ONESHOT,
dev_name(&fn->dev), fn);
if (error) {
dev_err(&fn->dev, "Error %d registering IRQ\n", error);
return error;
}
}
return 0;
}
static int rmi_function_probe(struct device *dev) static int rmi_function_probe(struct device *dev)
{ {
struct rmi_function *fn = to_rmi_function(dev); struct rmi_function *fn = to_rmi_function(dev);
...@@ -178,6 +213,13 @@ static int rmi_function_probe(struct device *dev) ...@@ -178,6 +213,13 @@ static int rmi_function_probe(struct device *dev)
if (handler->probe) { if (handler->probe) {
error = handler->probe(fn); error = handler->probe(fn);
if (error)
return error;
}
if (fn->num_of_irqs && handler->attention) {
error = rmi_create_function_irq(fn, handler);
if (error)
return error; return error;
} }
...@@ -230,12 +272,18 @@ int rmi_register_function(struct rmi_function *fn) ...@@ -230,12 +272,18 @@ int rmi_register_function(struct rmi_function *fn)
void rmi_unregister_function(struct rmi_function *fn) void rmi_unregister_function(struct rmi_function *fn)
{ {
int i;
rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n", rmi_dbg(RMI_DEBUG_CORE, &fn->dev, "Unregistering F%02X.\n",
fn->fd.function_number); fn->fd.function_number);
device_del(&fn->dev); device_del(&fn->dev);
of_node_put(fn->dev.of_node); of_node_put(fn->dev.of_node);
put_device(&fn->dev); put_device(&fn->dev);
for (i = 0; i < fn->num_of_irqs; i++)
irq_dispose_mapping(fn->irq[i]);
} }
/** /**
......
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
struct rmi_device; struct rmi_device;
/*
* The interrupt source count in the function descriptor can represent up to
* 6 interrupt sources in the normal manner.
*/
#define RMI_FN_MAX_IRQS 6
/** /**
* struct rmi_function - represents the implementation of an RMI4 * struct rmi_function - represents the implementation of an RMI4
* function for a particular device (basically, a driver for that RMI4 function) * function for a particular device (basically, a driver for that RMI4 function)
...@@ -26,6 +32,7 @@ struct rmi_device; ...@@ -26,6 +32,7 @@ struct rmi_device;
* @irq_pos: The position in the irq bitfield this function holds * @irq_pos: The position in the irq bitfield this function holds
* @irq_mask: For convenience, can be used to mask IRQ bits off during ATTN * @irq_mask: For convenience, can be used to mask IRQ bits off during ATTN
* interrupt handling. * interrupt handling.
* @irqs: assigned virq numbers (up to num_of_irqs)
* *
* @node: entry in device's list of functions * @node: entry in device's list of functions
*/ */
...@@ -36,6 +43,7 @@ struct rmi_function { ...@@ -36,6 +43,7 @@ struct rmi_function {
struct list_head node; struct list_head node;
unsigned int num_of_irqs; unsigned int num_of_irqs;
int irq[RMI_FN_MAX_IRQS];
unsigned int irq_pos; unsigned int irq_pos;
unsigned long irq_mask[]; unsigned long irq_mask[];
}; };
...@@ -76,7 +84,7 @@ struct rmi_function_handler { ...@@ -76,7 +84,7 @@ struct rmi_function_handler {
void (*remove)(struct rmi_function *fn); void (*remove)(struct rmi_function *fn);
int (*config)(struct rmi_function *fn); int (*config)(struct rmi_function *fn);
int (*reset)(struct rmi_function *fn); int (*reset)(struct rmi_function *fn);
int (*attention)(struct rmi_function *fn, unsigned long *irq_bits); irqreturn_t (*attention)(int irq, void *ctx);
int (*suspend)(struct rmi_function *fn); int (*suspend)(struct rmi_function *fn);
int (*resume)(struct rmi_function *fn); int (*resume)(struct rmi_function *fn);
}; };
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/irqdomain.h>
#include <uapi/linux/input.h> #include <uapi/linux/input.h>
#include <linux/rmi.h> #include <linux/rmi.h>
#include "rmi_bus.h" #include "rmi_bus.h"
...@@ -127,28 +128,11 @@ static int rmi_driver_process_config_requests(struct rmi_device *rmi_dev) ...@@ -127,28 +128,11 @@ static int rmi_driver_process_config_requests(struct rmi_device *rmi_dev)
return 0; return 0;
} }
static void process_one_interrupt(struct rmi_driver_data *data,
struct rmi_function *fn)
{
struct rmi_function_handler *fh;
if (!fn || !fn->dev.driver)
return;
fh = to_rmi_function_handler(fn->dev.driver);
if (fh->attention) {
bitmap_and(data->fn_irq_bits, data->irq_status, fn->irq_mask,
data->irq_count);
if (!bitmap_empty(data->fn_irq_bits, data->irq_count))
fh->attention(fn, data->fn_irq_bits);
}
}
static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
{ {
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
struct device *dev = &rmi_dev->dev; struct device *dev = &rmi_dev->dev;
struct rmi_function *entry; int i;
int error; int error;
if (!data) if (!data)
...@@ -173,16 +157,8 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) ...@@ -173,16 +157,8 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
*/ */
mutex_unlock(&data->irq_mutex); mutex_unlock(&data->irq_mutex);
/* for_each_set_bit(i, data->irq_status, data->irq_count)
* It would be nice to be able to use irq_chip to handle these handle_nested_irq(irq_find_mapping(data->irqdomain, i));
* nested IRQs. Unfortunately, most of the current customers for
* this driver are using older kernels (3.0.x) that don't support
* the features required for that. Once they've shifted to more
* recent kernels (say, 3.3 and higher), this should be switched to
* use irq_chip.
*/
list_for_each_entry(entry, &data->function_list, node)
process_one_interrupt(data, entry);
if (data->input) if (data->input)
input_sync(data->input); input_sync(data->input);
...@@ -1001,9 +977,13 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume); ...@@ -1001,9 +977,13 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume);
static int rmi_driver_remove(struct device *dev) static int rmi_driver_remove(struct device *dev)
{ {
struct rmi_device *rmi_dev = to_rmi_device(dev); struct rmi_device *rmi_dev = to_rmi_device(dev);
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
rmi_disable_irq(rmi_dev, false); rmi_disable_irq(rmi_dev, false);
irq_domain_remove(data->irqdomain);
data->irqdomain = NULL;
rmi_f34_remove_sysfs(rmi_dev); rmi_f34_remove_sysfs(rmi_dev);
rmi_free_function_list(rmi_dev); rmi_free_function_list(rmi_dev);
...@@ -1035,7 +1015,8 @@ int rmi_probe_interrupts(struct rmi_driver_data *data) ...@@ -1035,7 +1015,8 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
{ {
struct rmi_device *rmi_dev = data->rmi_dev; struct rmi_device *rmi_dev = data->rmi_dev;
struct device *dev = &rmi_dev->dev; struct device *dev = &rmi_dev->dev;
int irq_count; struct fwnode_handle *fwnode = rmi_dev->xport->dev->fwnode;
int irq_count = 0;
size_t size; size_t size;
int retval; int retval;
...@@ -1046,7 +1027,6 @@ int rmi_probe_interrupts(struct rmi_driver_data *data) ...@@ -1046,7 +1027,6 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
* being accessed. * being accessed.
*/ */
rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n", __func__); rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n", __func__);
irq_count = 0;
data->bootloader_mode = false; data->bootloader_mode = false;
retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_count_irqs); retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_count_irqs);
...@@ -1058,6 +1038,15 @@ int rmi_probe_interrupts(struct rmi_driver_data *data) ...@@ -1058,6 +1038,15 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
if (data->bootloader_mode) if (data->bootloader_mode)
dev_warn(dev, "Device in bootloader mode.\n"); dev_warn(dev, "Device in bootloader mode.\n");
/* Allocate and register a linear revmap irq_domain */
data->irqdomain = irq_domain_create_linear(fwnode, irq_count,
&irq_domain_simple_ops,
data);
if (!data->irqdomain) {
dev_err(&rmi_dev->dev, "Failed to create IRQ domain\n");
return -ENOMEM;
}
data->irq_count = irq_count; data->irq_count = irq_count;
data->num_of_irq_regs = (data->irq_count + 7) / 8; data->num_of_irq_regs = (data->irq_count + 7) / 8;
...@@ -1080,10 +1069,9 @@ int rmi_init_functions(struct rmi_driver_data *data) ...@@ -1080,10 +1069,9 @@ int rmi_init_functions(struct rmi_driver_data *data)
{ {
struct rmi_device *rmi_dev = data->rmi_dev; struct rmi_device *rmi_dev = data->rmi_dev;
struct device *dev = &rmi_dev->dev; struct device *dev = &rmi_dev->dev;
int irq_count; int irq_count = 0;
int retval; int retval;
irq_count = 0;
rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Creating functions.\n", __func__); rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Creating functions.\n", __func__);
retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_create_function); retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_create_function);
if (retval < 0) { if (retval < 0) {
......
...@@ -681,9 +681,9 @@ static int rmi_f01_resume(struct rmi_function *fn) ...@@ -681,9 +681,9 @@ static int rmi_f01_resume(struct rmi_function *fn)
return 0; return 0;
} }
static int rmi_f01_attention(struct rmi_function *fn, static irqreturn_t rmi_f01_attention(int irq, void *ctx)
unsigned long *irq_bits)
{ {
struct rmi_function *fn = ctx;
struct rmi_device *rmi_dev = fn->rmi_dev; struct rmi_device *rmi_dev = fn->rmi_dev;
int error; int error;
u8 device_status; u8 device_status;
...@@ -692,7 +692,7 @@ static int rmi_f01_attention(struct rmi_function *fn, ...@@ -692,7 +692,7 @@ static int rmi_f01_attention(struct rmi_function *fn,
if (error) { if (error) {
dev_err(&fn->dev, dev_err(&fn->dev,
"Failed to read device status: %d.\n", error); "Failed to read device status: %d.\n", error);
return error; return IRQ_RETVAL(error);
} }
if (RMI_F01_STATUS_BOOTLOADER(device_status)) if (RMI_F01_STATUS_BOOTLOADER(device_status))
...@@ -704,11 +704,11 @@ static int rmi_f01_attention(struct rmi_function *fn, ...@@ -704,11 +704,11 @@ static int rmi_f01_attention(struct rmi_function *fn,
error = rmi_dev->driver->reset_handler(rmi_dev); error = rmi_dev->driver->reset_handler(rmi_dev);
if (error) { if (error) {
dev_err(&fn->dev, "Device reset failed: %d\n", error); dev_err(&fn->dev, "Device reset failed: %d\n", error);
return error; return IRQ_RETVAL(error);
} }
} }
return 0; return IRQ_HANDLED;
} }
struct rmi_function_handler rmi_f01_handler = { struct rmi_function_handler rmi_f01_handler = {
......
...@@ -244,8 +244,9 @@ static int rmi_f03_config(struct rmi_function *fn) ...@@ -244,8 +244,9 @@ static int rmi_f03_config(struct rmi_function *fn)
return 0; return 0;
} }
static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits) static irqreturn_t rmi_f03_attention(int irq, void *ctx)
{ {
struct rmi_function *fn = ctx;
struct rmi_device *rmi_dev = fn->rmi_dev; struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
struct f03_data *f03 = dev_get_drvdata(&fn->dev); struct f03_data *f03 = dev_get_drvdata(&fn->dev);
...@@ -262,7 +263,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits) ...@@ -262,7 +263,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
/* First grab the data passed by the transport device */ /* First grab the data passed by the transport device */
if (drvdata->attn_data.size < ob_len) { if (drvdata->attn_data.size < ob_len) {
dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n"); dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
return 0; return IRQ_HANDLED;
} }
memcpy(obs, drvdata->attn_data.data, ob_len); memcpy(obs, drvdata->attn_data.data, ob_len);
...@@ -277,7 +278,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits) ...@@ -277,7 +278,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
"%s: Failed to read F03 output buffers: %d\n", "%s: Failed to read F03 output buffers: %d\n",
__func__, error); __func__, error);
serio_interrupt(f03->serio, 0, SERIO_TIMEOUT); serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
return error; return IRQ_RETVAL(error);
} }
} }
...@@ -303,7 +304,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits) ...@@ -303,7 +304,7 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
serio_interrupt(f03->serio, ob_data, serio_flags); serio_interrupt(f03->serio, ob_data, serio_flags);
} }
return 0; return IRQ_HANDLED;
} }
static void rmi_f03_remove(struct rmi_function *fn) static void rmi_f03_remove(struct rmi_function *fn)
......
...@@ -570,9 +570,7 @@ static inline u8 rmi_f11_parse_finger_state(const u8 *f_state, u8 n_finger) ...@@ -570,9 +570,7 @@ static inline u8 rmi_f11_parse_finger_state(const u8 *f_state, u8 n_finger)
} }
static void rmi_f11_finger_handler(struct f11_data *f11, static void rmi_f11_finger_handler(struct f11_data *f11,
struct rmi_2d_sensor *sensor, struct rmi_2d_sensor *sensor, int size)
unsigned long *irq_bits, int num_irq_regs,
int size)
{ {
const u8 *f_state = f11->data.f_state; const u8 *f_state = f11->data.f_state;
u8 finger_state; u8 finger_state;
...@@ -581,12 +579,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11, ...@@ -581,12 +579,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
int rel_fingers; int rel_fingers;
int abs_size = sensor->nbr_fingers * RMI_F11_ABS_BYTES; int abs_size = sensor->nbr_fingers * RMI_F11_ABS_BYTES;
int abs_bits = bitmap_and(f11->result_bits, irq_bits, f11->abs_mask, if (sensor->report_abs) {
num_irq_regs * 8);
int rel_bits = bitmap_and(f11->result_bits, irq_bits, f11->rel_mask,
num_irq_regs * 8);
if (abs_bits) {
if (abs_size > size) if (abs_size > size)
abs_fingers = size / RMI_F11_ABS_BYTES; abs_fingers = size / RMI_F11_ABS_BYTES;
else else
...@@ -604,19 +597,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11, ...@@ -604,19 +597,7 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
rmi_f11_abs_pos_process(f11, sensor, &sensor->objs[i], rmi_f11_abs_pos_process(f11, sensor, &sensor->objs[i],
finger_state, i); finger_state, i);
} }
}
if (rel_bits) {
if ((abs_size + sensor->nbr_fingers * RMI_F11_REL_BYTES) > size)
rel_fingers = (size - abs_size) / RMI_F11_REL_BYTES;
else
rel_fingers = sensor->nbr_fingers;
for (i = 0; i < rel_fingers; i++)
rmi_f11_rel_pos_report(f11, i);
}
if (abs_bits) {
/* /*
* the absolute part is made in 2 parts to allow the kernel * the absolute part is made in 2 parts to allow the kernel
* tracking to take place. * tracking to take place.
...@@ -638,7 +619,16 @@ static void rmi_f11_finger_handler(struct f11_data *f11, ...@@ -638,7 +619,16 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
} }
input_mt_sync_frame(sensor->input); input_mt_sync_frame(sensor->input);
} else if (sensor->report_rel) {
if ((abs_size + sensor->nbr_fingers * RMI_F11_REL_BYTES) > size)
rel_fingers = (size - abs_size) / RMI_F11_REL_BYTES;
else
rel_fingers = sensor->nbr_fingers;
for (i = 0; i < rel_fingers; i++)
rmi_f11_rel_pos_report(f11, i);
} }
} }
static int f11_2d_construct_data(struct f11_data *f11) static int f11_2d_construct_data(struct f11_data *f11)
...@@ -1276,8 +1266,9 @@ static int rmi_f11_config(struct rmi_function *fn) ...@@ -1276,8 +1266,9 @@ static int rmi_f11_config(struct rmi_function *fn)
return 0; return 0;
} }
static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits) static irqreturn_t rmi_f11_attention(int irq, void *ctx)
{ {
struct rmi_function *fn = ctx;
struct rmi_device *rmi_dev = fn->rmi_dev; struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
struct f11_data *f11 = dev_get_drvdata(&fn->dev); struct f11_data *f11 = dev_get_drvdata(&fn->dev);
...@@ -1303,13 +1294,12 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits) ...@@ -1303,13 +1294,12 @@ static int rmi_f11_attention(struct rmi_function *fn, unsigned long *irq_bits)
data_base_addr, f11->sensor.data_pkt, data_base_addr, f11->sensor.data_pkt,
f11->sensor.pkt_size); f11->sensor.pkt_size);
if (error < 0) if (error < 0)
return error; return IRQ_RETVAL(error);
} }
rmi_f11_finger_handler(f11, &f11->sensor, irq_bits, rmi_f11_finger_handler(f11, &f11->sensor, valid_bytes);
drvdata->num_of_irq_regs, valid_bytes);
return 0; return IRQ_HANDLED;
} }
static int rmi_f11_resume(struct rmi_function *fn) static int rmi_f11_resume(struct rmi_function *fn)
......
...@@ -197,10 +197,10 @@ static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size) ...@@ -197,10 +197,10 @@ static void rmi_f12_process_objects(struct f12_data *f12, u8 *data1, int size)
rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i); rmi_2d_sensor_abs_report(sensor, &sensor->objs[i], i);
} }
static int rmi_f12_attention(struct rmi_function *fn, static irqreturn_t rmi_f12_attention(int irq, void *ctx)
unsigned long *irq_nr_regs)
{ {
int retval; int retval;
struct rmi_function *fn = ctx;
struct rmi_device *rmi_dev = fn->rmi_dev; struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev); struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
struct f12_data *f12 = dev_get_drvdata(&fn->dev); struct f12_data *f12 = dev_get_drvdata(&fn->dev);
...@@ -222,7 +222,7 @@ static int rmi_f12_attention(struct rmi_function *fn, ...@@ -222,7 +222,7 @@ static int rmi_f12_attention(struct rmi_function *fn,
if (retval < 0) { if (retval < 0) {
dev_err(&fn->dev, "Failed to read object data. Code: %d.\n", dev_err(&fn->dev, "Failed to read object data. Code: %d.\n",
retval); retval);
return retval; return IRQ_RETVAL(retval);
} }
} }
...@@ -232,7 +232,7 @@ static int rmi_f12_attention(struct rmi_function *fn, ...@@ -232,7 +232,7 @@ static int rmi_f12_attention(struct rmi_function *fn,
input_mt_sync_frame(sensor->input); input_mt_sync_frame(sensor->input);
return 0; return IRQ_HANDLED;
} }
static int rmi_f12_write_control_regs(struct rmi_function *fn) static int rmi_f12_write_control_regs(struct rmi_function *fn)
......
...@@ -122,8 +122,9 @@ static void rmi_f30_report_button(struct rmi_function *fn, ...@@ -122,8 +122,9 @@ static void rmi_f30_report_button(struct rmi_function *fn,
} }
} }
static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits) static irqreturn_t rmi_f30_attention(int irq, void *ctx)
{ {
struct rmi_function *fn = ctx;
struct f30_data *f30 = dev_get_drvdata(&fn->dev); struct f30_data *f30 = dev_get_drvdata(&fn->dev);
struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev); struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
int error; int error;
...@@ -134,7 +135,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits) ...@@ -134,7 +135,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
if (drvdata->attn_data.size < f30->register_count) { if (drvdata->attn_data.size < f30->register_count) {
dev_warn(&fn->dev, dev_warn(&fn->dev,
"F30 interrupted, but data is missing\n"); "F30 interrupted, but data is missing\n");
return 0; return IRQ_HANDLED;
} }
memcpy(f30->data_regs, drvdata->attn_data.data, memcpy(f30->data_regs, drvdata->attn_data.data,
f30->register_count); f30->register_count);
...@@ -147,7 +148,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits) ...@@ -147,7 +148,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
dev_err(&fn->dev, dev_err(&fn->dev,
"%s: Failed to read F30 data registers: %d\n", "%s: Failed to read F30 data registers: %d\n",
__func__, error); __func__, error);
return error; return IRQ_RETVAL(error);
} }
} }
...@@ -159,7 +160,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits) ...@@ -159,7 +160,7 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
rmi_f03_commit_buttons(f30->f03); rmi_f03_commit_buttons(f30->f03);
} }
return 0; return IRQ_HANDLED;
} }
static int rmi_f30_config(struct rmi_function *fn) static int rmi_f30_config(struct rmi_function *fn)
......
...@@ -100,8 +100,9 @@ static int rmi_f34_command(struct f34_data *f34, u8 command, ...@@ -100,8 +100,9 @@ static int rmi_f34_command(struct f34_data *f34, u8 command,
return 0; return 0;
} }
static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits) static irqreturn_t rmi_f34_attention(int irq, void *ctx)
{ {
struct rmi_function *fn = ctx;
struct f34_data *f34 = dev_get_drvdata(&fn->dev); struct f34_data *f34 = dev_get_drvdata(&fn->dev);
int ret; int ret;
u8 status; u8 status;
...@@ -126,7 +127,7 @@ static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits) ...@@ -126,7 +127,7 @@ static int rmi_f34_attention(struct rmi_function *fn, unsigned long *irq_bits)
complete(&f34->v7.cmd_done); complete(&f34->v7.cmd_done);
} }
return 0; return IRQ_HANDLED;
} }
static int rmi_f34_write_blocks(struct f34_data *f34, const void *data, static int rmi_f34_write_blocks(struct f34_data *f34, const void *data,
......
...@@ -610,11 +610,6 @@ static void rmi_f54_work(struct work_struct *work) ...@@ -610,11 +610,6 @@ static void rmi_f54_work(struct work_struct *work)
mutex_unlock(&f54->data_mutex); mutex_unlock(&f54->data_mutex);
} }
static int rmi_f54_attention(struct rmi_function *fn, unsigned long *irqbits)
{
return 0;
}
static int rmi_f54_config(struct rmi_function *fn) static int rmi_f54_config(struct rmi_function *fn)
{ {
struct rmi_driver *drv = fn->rmi_dev->driver; struct rmi_driver *drv = fn->rmi_dev->driver;
...@@ -756,6 +751,5 @@ struct rmi_function_handler rmi_f54_handler = { ...@@ -756,6 +751,5 @@ struct rmi_function_handler rmi_f54_handler = {
.func = 0x54, .func = 0x54,
.probe = rmi_f54_probe, .probe = rmi_f54_probe,
.config = rmi_f54_config, .config = rmi_f54_config,
.attention = rmi_f54_attention,
.remove = rmi_f54_remove, .remove = rmi_f54_remove,
}; };
...@@ -603,6 +603,7 @@ static const struct acpi_device_id silead_ts_acpi_match[] = { ...@@ -603,6 +603,7 @@ static const struct acpi_device_id silead_ts_acpi_match[] = {
{ "GSL3692", 0 }, { "GSL3692", 0 },
{ "MSSL1680", 0 }, { "MSSL1680", 0 },
{ "MSSL0001", 0 }, { "MSSL0001", 0 },
{ "MSSL0002", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, silead_ts_acpi_match); MODULE_DEVICE_TABLE(acpi, silead_ts_acpi_match);
......
...@@ -100,7 +100,7 @@ static inline bool input_is_mt_axis(int axis) ...@@ -100,7 +100,7 @@ static inline bool input_is_mt_axis(int axis)
return axis == ABS_MT_SLOT || input_is_mt_value(axis); return axis == ABS_MT_SLOT || input_is_mt_value(axis);
} }
void input_mt_report_slot_state(struct input_dev *dev, bool input_mt_report_slot_state(struct input_dev *dev,
unsigned int tool_type, bool active); unsigned int tool_type, bool active);
void input_mt_report_finger_count(struct input_dev *dev, int count); void input_mt_report_finger_count(struct input_dev *dev, int count);
......
...@@ -354,6 +354,8 @@ struct rmi_driver_data { ...@@ -354,6 +354,8 @@ struct rmi_driver_data {
struct mutex irq_mutex; struct mutex irq_mutex;
struct input_dev *input; struct input_dev *input;
struct irq_domain *irqdomain;
u8 pdt_props; u8 pdt_props;
u8 num_rx_electrodes; u8 num_rx_electrodes;
......
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