Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
torvalds committed Jun 27, 2018
2 parents 896a349 + 03ae3a9 commit c92067a
Show file tree
Hide file tree
Showing 27 changed files with 366 additions and 124 deletions.
23 changes: 23 additions & 0 deletions Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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>;
};
};
12 changes: 8 additions & 4 deletions drivers/input/input-mt.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,31 +131,35 @@ EXPORT_SYMBOL(input_mt_destroy_slots);
* 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
* 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)
{
struct input_mt *mt = dev->mt;
struct input_mt_slot *slot;
int id;

if (!mt)
return;
return false;

slot = &mt->slots[mt->slot];
slot->frame = mt->frame;

if (!active) {
input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
return;
return false;
}

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);

input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, id);
input_event(dev, EV_ABS, ABS_MT_TOOL_TYPE, tool_type);

return true;
}
EXPORT_SYMBOL(input_mt_report_slot_state);

Expand Down
2 changes: 1 addition & 1 deletion drivers/input/joystick/xpad.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static const struct xpad_device {
u8 mapping;
u8 xtype;
} 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, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX },
{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
Expand Down
9 changes: 5 additions & 4 deletions drivers/input/keyboard/goldfish_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct event_dev {
static irqreturn_t events_interrupt(int irq, void *dev_id)
{
struct event_dev *edev = dev_id;
unsigned type, code, value;
unsigned int type, code, value;

type = __raw_readl(edev->addr + REG_READ);
code = __raw_readl(edev->addr + REG_READ);
Expand All @@ -57,7 +57,7 @@ static irqreturn_t events_interrupt(int irq, void *dev_id)
}

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;
int i, j;
Expand Down Expand Up @@ -99,6 +99,7 @@ static void events_import_abs_params(struct event_dev *edev)

for (j = 0; j < ARRAY_SIZE(val); j++) {
int offset = (i * ARRAY_SIZE(val) + j) * sizeof(u32);

val[j] = __raw_readl(edev->addr + REG_DATA + offset);
}

Expand All @@ -112,7 +113,7 @@ static int events_probe(struct platform_device *pdev)
struct input_dev *input_dev;
struct event_dev *edev;
struct resource *res;
unsigned keymapnamelen;
unsigned int keymapnamelen;
void __iomem *addr;
int irq;
int i;
Expand Down Expand Up @@ -150,7 +151,7 @@ static int events_probe(struct platform_device *pdev)
for (i = 0; i < keymapnamelen; 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->id.bustype = BUS_HOST;
Expand Down
10 changes: 10 additions & 0 deletions drivers/input/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -841,4 +841,14 @@ config INPUT_RAVE_SP_PWRBUTTON
To compile this driver as a module, choose M here: the
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
1 change: 1 addition & 0 deletions drivers/input/misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o
obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o
obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.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_SIRFSOC_ONKEY) += sirfsoc-onkey.o
obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o
Expand Down
154 changes: 154 additions & 0 deletions drivers/input/misc/sc27xx-vibra.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// 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>");
2 changes: 2 additions & 0 deletions drivers/input/mouse/elan_i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#define ETP_DISABLE_POWER 0x0001
#define ETP_PRESSURE_OFFSET 25

#define ETP_CALIBRATE_MAX_LEN 3

/* IAP Firmware handling */
#define ETP_PRODUCT_ID_FORMAT_STRING "%d.0"
#define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin"
Expand Down
3 changes: 2 additions & 1 deletion drivers/input/mouse/elan_i2c_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ static ssize_t calibrate_store(struct device *dev,
int tries = 20;
int retval;
int error;
u8 val[3];
u8 val[ETP_CALIBRATE_MAX_LEN];

retval = mutex_lock_interruptible(&data->sysfs_mutex);
if (retval)
Expand Down Expand Up @@ -1345,6 +1345,7 @@ static const struct acpi_device_id elan_acpi_id[] = {
{ "ELAN060C", 0 },
{ "ELAN0611", 0 },
{ "ELAN0612", 0 },
{ "ELAN0618", 0 },
{ "ELAN1000", 0 },
{ }
};
Expand Down
10 changes: 8 additions & 2 deletions drivers/input/mouse/elan_i2c_smbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
static int elan_smbus_initialize(struct i2c_client *client)
{
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;

/* Get hello packet */
Expand Down Expand Up @@ -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)
{
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,
ETP_SMBUS_CALIBRATE_QUERY, val);
ETP_SMBUS_CALIBRATE_QUERY, buf);
if (error < 0)
return error;

memcpy(val, buf, ETP_CALIBRATE_MAX_LEN);
return 0;
}

Expand Down Expand Up @@ -472,6 +476,8 @@ static int elan_smbus_get_report(struct i2c_client *client, u8 *report)
{
int len;

BUILD_BUG_ON(I2C_SMBUS_BLOCK_MAX > ETP_SMBUS_REPORT_LEN);

len = i2c_smbus_read_block_data(client,
ETP_SMBUS_PACKET_QUERY,
&report[ETP_SMBUS_REPORT_OFFSET]);
Expand Down
11 changes: 9 additions & 2 deletions drivers/input/mouse/elantech.c
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ static int elantech_packet_check_v4(struct psmouse *psmouse)
else if (ic_version == 7 && etd->info.samples[1] == 0x2A)
sanity_check = ((packet[3] & 0x1c) == 0x10);
else
sanity_check = ((packet[0] & 0x0c) == 0x04 &&
sanity_check = ((packet[0] & 0x08) == 0x00 &&
(packet[3] & 0x1c) == 0x10);

if (!sanity_check)
Expand Down Expand Up @@ -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
*/
Expand All @@ -1194,7 +1200,8 @@ static int elantech_set_input_params(struct psmouse *psmouse)
__clear_bit(EV_REL, dev->evbit);

__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_RIGHT, dev->keybit);

Expand Down
Loading

0 comments on commit c92067a

Please sign in to comment.