Commit dcde98da authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull input updates from Dmitry Torokhov:

 - a fixup for Goodix touchscreen driver allowing it to work on certain
   Cherry Trail devices

 - a fix for imbalanced enable/disable regulator in Elam touchpad driver
   that became apparent when used with Asus TF103C 2-in-1 dock

 - a couple new input keycodes used on newer keyboards

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  HID: add mapping for KEY_ALL_APPLICATIONS
  HID: add mapping for KEY_DICTATE
  Input: elan_i2c - fix regulator enable count imbalance after suspend/resume
  Input: elan_i2c - move regulator_[en|dis]able() out of elan_[en|dis]able_power()
  Input: goodix - workaround Cherry Trail devices with a bogus ACPI Interrupt() resource
  Input: goodix - use the new soc_intel_is_byt() helper
  Input: samsung-keypad - properly state IOMEM dependency
parents 0014404f 327b89f0
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -860,7 +860,9 @@ static const char *keys[KEY_MAX + 1] = {
	[KEY_F22] = "F22",			[KEY_F23] = "F23",
	[KEY_F24] = "F24",			[KEY_PLAYCD] = "PlayCD",
	[KEY_PAUSECD] = "PauseCD",		[KEY_PROG3] = "Prog3",
	[KEY_PROG4] = "Prog4",			[KEY_SUSPEND] = "Suspend",
	[KEY_PROG4] = "Prog4",
	[KEY_ALL_APPLICATIONS] = "AllApplications",
	[KEY_SUSPEND] = "Suspend",
	[KEY_CLOSE] = "Close",			[KEY_PLAY] = "Play",
	[KEY_FASTFORWARD] = "FastForward",	[KEY_BASSBOOST] = "BassBoost",
	[KEY_PRINT] = "Print",			[KEY_HP] = "HP",
@@ -969,6 +971,7 @@ static const char *keys[KEY_MAX + 1] = {
	[KEY_ASSISTANT] = "Assistant",
	[KEY_KBD_LAYOUT_NEXT] = "KbdLayoutNext",
	[KEY_EMOJI_PICKER] = "EmojiPicker",
	[KEY_DICTATE] = "Dictate",
	[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
	[KEY_BRIGHTNESS_MAX] = "BrightnessMax",
	[KEY_BRIGHTNESS_AUTO] = "BrightnessAuto",
+3 −0
Original line number Diff line number Diff line
@@ -992,6 +992,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
		case 0x0cd: map_key_clear(KEY_PLAYPAUSE);	break;
		case 0x0cf: map_key_clear(KEY_VOICECOMMAND);	break;

		case 0x0d8: map_key_clear(KEY_DICTATE);		break;
		case 0x0d9: map_key_clear(KEY_EMOJI_PICKER);	break;

		case 0x0e0: map_abs_clear(ABS_VOLUME);		break;
@@ -1083,6 +1084,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel

		case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT);	break;

		case 0x2a2: map_key_clear(KEY_ALL_APPLICATIONS);	break;

		case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV);		break;
		case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT);		break;
		case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP);		break;
+1 −1
Original line number Diff line number Diff line
@@ -556,7 +556,7 @@ config KEYBOARD_PMIC8XXX

config KEYBOARD_SAMSUNG
	tristate "Samsung keypad support"
	depends on HAVE_CLK
	depends on HAS_IOMEM && HAVE_CLK
	select INPUT_MATRIXKMAP
	help
	  Say Y here if you want to use the keypad on your Samsung mobile
+23 −41
Original line number Diff line number Diff line
@@ -186,55 +186,21 @@ static int elan_get_fwinfo(u16 ic_type, u8 iap_version, u16 *validpage_count,
	return 0;
}

static int elan_enable_power(struct elan_tp_data *data)
static int elan_set_power(struct elan_tp_data *data, bool on)
{
	int repeat = ETP_RETRY_COUNT;
	int error;

	error = regulator_enable(data->vcc);
	if (error) {
		dev_err(&data->client->dev,
			"failed to enable regulator: %d\n", error);
		return error;
	}

	do {
		error = data->ops->power_control(data->client, true);
		error = data->ops->power_control(data->client, on);
		if (error >= 0)
			return 0;

		msleep(30);
	} while (--repeat > 0);

	dev_err(&data->client->dev, "failed to enable power: %d\n", error);
	return error;
}

static int elan_disable_power(struct elan_tp_data *data)
{
	int repeat = ETP_RETRY_COUNT;
	int error;

	do {
		error = data->ops->power_control(data->client, false);
		if (!error) {
			error = regulator_disable(data->vcc);
			if (error) {
				dev_err(&data->client->dev,
					"failed to disable regulator: %d\n",
					error);
				/* Attempt to power the chip back up */
				data->ops->power_control(data->client, true);
				break;
			}

			return 0;
		}

		msleep(30);
	} while (--repeat > 0);

	dev_err(&data->client->dev, "failed to disable power: %d\n", error);
	dev_err(&data->client->dev, "failed to set power %s: %d\n",
		on ? "on" : "off", error);
	return error;
}

@@ -1399,9 +1365,19 @@ static int __maybe_unused elan_suspend(struct device *dev)
		/* Enable wake from IRQ */
		data->irq_wake = (enable_irq_wake(client->irq) == 0);
	} else {
		ret = elan_disable_power(data);
		ret = elan_set_power(data, false);
		if (ret)
			goto err;

		ret = regulator_disable(data->vcc);
		if (ret) {
			dev_err(dev, "error %d disabling regulator\n", ret);
			/* Attempt to power the chip back up */
			elan_set_power(data, true);
		}
	}

err:
	mutex_unlock(&data->sysfs_mutex);
	return ret;
}
@@ -1412,12 +1388,18 @@ static int __maybe_unused elan_resume(struct device *dev)
	struct elan_tp_data *data = i2c_get_clientdata(client);
	int error;

	if (device_may_wakeup(dev) && data->irq_wake) {
	if (!device_may_wakeup(dev)) {
		error = regulator_enable(data->vcc);
		if (error) {
			dev_err(dev, "error %d enabling regulator\n", error);
			goto err;
		}
	} else if (data->irq_wake) {
		disable_irq_wake(client->irq);
		data->irq_wake = false;
	}

	error = elan_enable_power(data);
	error = elan_set_power(data, true);
	if (error) {
		dev_err(dev, "power up when resuming failed: %d\n", error);
		goto err;
+17 −17
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_data/x86/soc.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/of.h>
@@ -805,21 +806,6 @@ static int goodix_reset(struct goodix_ts_data *ts)
}

#ifdef ACPI_GPIO_SUPPORT
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>

static const struct x86_cpu_id baytrail_cpu_ids[] = {
	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT, X86_FEATURE_ANY, },
	{}
};

static inline bool is_byt(void)
{
	const struct x86_cpu_id *id = x86_match_cpu(baytrail_cpu_ids);

	return !!id;
}

static const struct acpi_gpio_params first_gpio = { 0, 0, false };
static const struct acpi_gpio_params second_gpio = { 1, 0, false };

@@ -878,7 +864,7 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
	const struct acpi_gpio_mapping *gpio_mapping = NULL;
	struct device *dev = &ts->client->dev;
	LIST_HEAD(resources);
	int ret;
	int irq, ret;

	ts->gpio_count = 0;
	ts->gpio_int_idx = -1;
@@ -891,6 +877,20 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)

	acpi_dev_free_resource_list(&resources);

	/*
	 * CHT devices should have a GpioInt + a regular GPIO ACPI resource.
	 * Some CHT devices have a bug (where the also is bogus Interrupt
	 * resource copied from a previous BYT based generation). i2c-core-acpi
	 * will use the non-working Interrupt resource, fix this up.
	 */
	if (soc_intel_is_cht() && ts->gpio_count == 2 && ts->gpio_int_idx != -1) {
		irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0);
		if (irq > 0 && irq != ts->client->irq) {
			dev_warn(dev, "Overriding IRQ %d -> %d\n", ts->client->irq, irq);
			ts->client->irq = irq;
		}
	}

	if (ts->gpio_count == 2 && ts->gpio_int_idx == 0) {
		ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
		gpio_mapping = acpi_goodix_int_first_gpios;
@@ -903,7 +903,7 @@ static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
		dev_info(dev, "Using ACPI INTI and INTO methods for IRQ pin access\n");
		ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_METHOD;
		gpio_mapping = acpi_goodix_reset_only_gpios;
	} else if (is_byt() && ts->gpio_count == 2 && ts->gpio_int_idx == -1) {
	} else if (soc_intel_is_byt() && ts->gpio_count == 2 && ts->gpio_int_idx == -1) {
		dev_info(dev, "No ACPI GpioInt resource, assuming that the GPIO order is reset, int\n");
		ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
		gpio_mapping = acpi_goodix_int_last_gpios;
Loading