Commit 43d01209 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:

 - a new driver for STM FingerTip touchscreen

 - a new driver for D-Link DIR-685 touch keys

 - updated list of supported devices in xpad driver

 - other assorted updates and fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (23 commits)
  MAINTAINERS: update input subsystem patterns
  Input: introduce KEY_ASSISTANT
  Input: xpad - sync supported devices with XBCD
  Input: xpad - sync supported devices with 360Controller
  Input: xen-kbdfront - use string constants from PV protocol
  Input: stmfts - mark all PM functions as __maybe_unused
  Input: add support for the STMicroelectronics FingerTip touchscreen
  Input: add D-Link DIR-685 touchkeys driver
  Input: s3c2410_ts - handle return value of clk_prepare_enable
  Input: axp20x-pek - add wakeup support
  Input: synaptics-rmi4 - use %phN to form F34 configuration ID
  Input: synaptics-rmi4 - change a char type to u8
  Input: sparse-keymap - remove sparse_keymap_free()
  Input: tsc2007 - move header file out of I2C realm
  Input: mms114 - move header file out of I2C realm
  Input: mcs - move header file out of I2C realm
  Input: lm8323 - move header file out of I2C realm
  Input: elantech - force relative mode on a certain module
  Input: elan_i2c - add support for fetching chip type on newer hardware
  Input: elan_i2c - check if device is there before really probing
  ...
parents 2ceedf97 ede2e7cd
* D-Link DIR-685 Touchkeys
This is a I2C one-off touchkey controller based on the Cypress Semiconductor
CY8C214 MCU with some firmware in its internal 8KB flash. The circuit
board inside the router is named E119921.
The touchkey device node should be placed inside an I2C bus node.
Required properties:
- compatible: must be "dlink,dir685-touchkeys"
- reg: the I2C address of the touchkeys
- interrupts: reference to the interrupt number
Example:
touchkeys@26 {
compatible = "dlink,dir685-touchkeys";
reg = <0x26>;
interrupt-parent = <&gpio0>;
interrupts = <17 IRQ_TYPE_EDGE_FALLING>;
};
* ST-Microelectronics FingerTip touchscreen controller
The ST-Microelectronics FingerTip device provides a basic touchscreen
functionality. Along with it the user can enable the touchkey which can work as
a basic HOME and BACK key for phones.
The driver supports also hovering as an absolute single touch event with x, y, z
coordinates.
Required properties:
- compatible : must be "st,stmfts"
- reg : I2C slave address, (e.g. 0x49)
- interrupt-parent : the phandle to the interrupt controller which provides
the interrupt
- interrupts : interrupt specification
- avdd-supply : analogic power supply
- vdd-supply : power supply
- touchscreen-size-x : see touchscreen.txt
- touchscreen-size-y : see touchscreen.txt
Optional properties:
- touch-key-connected : specifies whether the touchkey feature is connected
- ledvdd-supply : power supply to the touch key leds
Example:
i2c@00000000 {
/* ... */
touchscreen@49 {
compatible = "st,stmfts";
reg = <0x49>;
interrupt-parent = <&gpa1>;
interrupts = <1 IRQ_TYPE_NONE>;
touchscreen-size-x = <1599>;
touchscreen-size-y = <2559>;
touch-key-connected;
avdd-supply = <&ldo30_reg>;
vdd-supply = <&ldo31_reg>;
ledvdd-supply = <&ldo33_reg>;
};
};
......@@ -3846,6 +3846,12 @@ S: Supported
F: drivers/input/touchscreen/cyttsp*
F: include/linux/input/cyttsp.h
D-LINK DIR-685 TOUCHKEYS DRIVER
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-input@vger.kernel.org
S: Supported
F: drivers/input/dlink-dir685-touchkeys.c
DALLAS/MAXIM DS1685-FAMILY REAL TIME CLOCK
M: Joshua Kinard <kumba@gentoo.org>
S: Maintained
......@@ -6689,8 +6695,10 @@ S: Maintained
F: drivers/input/
F: include/linux/input.h
F: include/uapi/linux/input.h
F: include/uapi/linux/input-event-codes.h
F: include/linux/input/
F: Documentation/devicetree/bindings/input/
F: Documentation/input/
INPUT MULTITOUCH (MT) PROTOCOL
M: Henrik Rydberg <rydberg@bitmath.org>
......
......@@ -24,7 +24,7 @@
#include <linux/usb/r8a66597.h>
#include <linux/usb/renesas_usbhs.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
#include <linux/platform_data/tsc2007.h>
#include <linux/spi/spi.h>
#include <linux/spi/sh_msiof.h>
#include <linux/spi/mmc_spi.h>
......
......@@ -481,7 +481,7 @@ EXPORT_SYMBOL(input_inject_event);
void input_alloc_absinfo(struct input_dev *dev)
{
if (!dev->absinfo)
dev->absinfo = kcalloc(ABS_CNT, sizeof(struct input_absinfo),
dev->absinfo = kcalloc(ABS_CNT, sizeof(*dev->absinfo),
GFP_KERNEL);
WARN(!dev->absinfo, "%s(): kcalloc() failed?\n", __func__);
......@@ -1126,7 +1126,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
* If no output was produced print a single 0.
*/
if (skip_empty)
seq_puts(seq, "0");
seq_putc(seq, '0');
seq_putc(seq, '\n');
}
......@@ -1144,7 +1144,7 @@ static int input_devices_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : "");
seq_printf(seq, "S: Sysfs=%s\n", path ? path : "");
seq_printf(seq, "U: Uniq=%s\n", dev->uniq ? dev->uniq : "");
seq_printf(seq, "H: Handlers=");
seq_puts(seq, "H: Handlers=");
list_for_each_entry(handle, &dev->h_list, d_node)
seq_printf(seq, "%s ", handle->name);
......@@ -1783,7 +1783,7 @@ struct input_dev *input_allocate_device(void)
static atomic_t input_no = ATOMIC_INIT(-1);
struct input_dev *dev;
dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev) {
dev->dev.type = &input_dev_type;
dev->dev.class = &input_class;
......@@ -1849,7 +1849,7 @@ struct input_dev *devm_input_allocate_device(struct device *dev)
struct input_devres *devres;
devres = devres_alloc(devm_input_device_release,
sizeof(struct input_devres), GFP_KERNEL);
sizeof(*devres), GFP_KERNEL);
if (!devres)
return NULL;
......@@ -2099,7 +2099,7 @@ int input_register_device(struct input_dev *dev)
if (dev->devres_managed) {
devres = devres_alloc(devm_input_device_unregister,
sizeof(struct input_devres), GFP_KERNEL);
sizeof(*devres), GFP_KERNEL);
if (!devres)
return -ENOMEM;
......
This diff is collapsed.
......@@ -178,6 +178,17 @@ config KEYBOARD_CLPS711X
To compile this driver as a module, choose M here: the
module will be called clps711x-keypad.
config KEYBOARD_DLINK_DIR685
tristate "D-Link DIR-685 touchkeys support"
depends on I2C
default ARCH_GEMINI
help
If you say yes here you get support for the D-Link DIR-685
touchkeys.
To compile this driver as a module, choose M here: the
module will be called dlink-dir685-touchkeys.
config KEYBOARD_LKKBD
tristate "DECstation/VAXstation LK201/LK401 keyboard"
select SERIO
......
......@@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_CAP11XX) += cap11xx.o
obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o
obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o
obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o
obj-$(CONFIG_KEYBOARD_DLINK_DIR685) += dlink-dir685-touchkeys.o
obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
obj-$(CONFIG_KEYBOARD_GOLDFISH_EVENTS) += goldfish_events.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
......
/*
* D-Link DIR-685 router I2C-based Touchkeys input driver
* Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
*
* This is a one-off touchkey controller based on the Cypress Semiconductor
* CY8C214 MCU with some firmware in its internal 8KB flash. The circuit
* board inside the router is named E119921
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/bitops.h>
struct dir685_touchkeys {
struct device *dev;
struct i2c_client *client;
struct input_dev *input;
unsigned long cur_key;
u16 codes[7];
};
static irqreturn_t dir685_tk_irq_thread(int irq, void *data)
{
struct dir685_touchkeys *tk = data;
const int num_bits = min_t(int, ARRAY_SIZE(tk->codes), 16);
unsigned long changed;
u8 buf[6];
unsigned long key;
int i;
int err;
memset(buf, 0, sizeof(buf));
err = i2c_master_recv(tk->client, buf, sizeof(buf));
if (err != sizeof(buf)) {
dev_err(tk->dev, "short read %d\n", err);
return IRQ_HANDLED;
}
dev_dbg(tk->dev, "IN: %*ph\n", (int)sizeof(buf), buf);
key = be16_to_cpup((__be16 *) &buf[4]);
/* Figure out if any bits went high or low since last message */
changed = tk->cur_key ^ key;
for_each_set_bit(i, &changed, num_bits) {
dev_dbg(tk->dev, "key %d is %s\n", i,
test_bit(i, &key) ? "down" : "up");
input_report_key(tk->input, tk->codes[i], test_bit(i, &key));
}
/* Store currently down keys */
tk->cur_key = key;
input_sync(tk->input);
return IRQ_HANDLED;
}
static int dir685_tk_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct dir685_touchkeys *tk;
struct device *dev = &client->dev;
u8 bl_data[] = { 0xa7, 0x40 };
int err;
int i;
tk = devm_kzalloc(&client->dev, sizeof(*tk), GFP_KERNEL);
if (!tk)
return -ENOMEM;
tk->input = devm_input_allocate_device(dev);
if (!tk->input)
return -ENOMEM;
tk->client = client;
tk->dev = dev;
tk->input->keycodesize = sizeof(u16);
tk->input->keycodemax = ARRAY_SIZE(tk->codes);
tk->input->keycode = tk->codes;
tk->codes[0] = KEY_UP;
tk->codes[1] = KEY_DOWN;
tk->codes[2] = KEY_LEFT;
tk->codes[3] = KEY_RIGHT;
tk->codes[4] = KEY_ENTER;
tk->codes[5] = KEY_WPS_BUTTON;
/*
* This key appears in the vendor driver, but I have
* not been able to activate it.
*/
tk->codes[6] = KEY_RESERVED;
__set_bit(EV_KEY, tk->input->evbit);
for (i = 0; i < ARRAY_SIZE(tk->codes); i++)
__set_bit(tk->codes[i], tk->input->keybit);
__clear_bit(KEY_RESERVED, tk->input->keybit);
tk->input->name = "D-Link DIR-685 touchkeys";
tk->input->id.bustype = BUS_I2C;
err = input_register_device(tk->input);
if (err)
return err;
/* Set the brightness to max level */
err = i2c_master_send(client, bl_data, sizeof(bl_data));
if (err != sizeof(bl_data))
dev_warn(tk->dev, "error setting brightness level\n");
if (!client->irq) {
dev_err(dev, "no IRQ on the I2C device\n");
return -ENODEV;
}
err = devm_request_threaded_irq(dev, client->irq,
NULL, dir685_tk_irq_thread,
IRQF_ONESHOT,
"dir685-tk", tk);
if (err) {
dev_err(dev, "can't request IRQ\n");
return err;
}
return 0;
}
static const struct i2c_device_id dir685_tk_id[] = {
{ "dir685tk", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, dir685_tk_id);
#ifdef CONFIG_OF
static const struct of_device_id dir685_tk_of_match[] = {
{ .compatible = "dlink,dir685-touchkeys" },
{},
};
MODULE_DEVICE_TABLE(of, dir685_tk_of_match);
#endif
static struct i2c_driver dir685_tk_i2c_driver = {
.driver = {
.name = "dlin-dir685-touchkeys",
.of_match_table = of_match_ptr(dir685_tk_of_match),
},
.probe = dir685_tk_probe,
.id_table = dir685_tk_id,
};
module_i2c_driver(dir685_tk_i2c_driver);
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
MODULE_DESCRIPTION("D-Link DIR-685 touchkeys driver");
MODULE_LICENSE("GPL");
......@@ -30,8 +30,8 @@
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/leds.h>
#include <linux/platform_data/lm8323.h>
#include <linux/pm.h>
#include <linux/i2c/lm8323.h>
#include <linux/slab.h>
/* Commands to send to the chip. */
......
......@@ -13,11 +13,11 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c/mcs.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/platform_data/mcs.h>
#include <linux/pm.h>
/* MCS5000 Touchkey */
......
......@@ -253,6 +253,9 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
return error;
}
if (axp20x_pek->axp20x->variant == AXP288_ID)
enable_irq_wake(axp20x_pek->irq_dbr);
return 0;
}
......@@ -331,10 +334,35 @@ static int axp20x_pek_probe(struct platform_device *pdev)
return 0;
}
static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
{
struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
if (axp20x_pek->axp20x->variant != AXP288_ID)
return 0;
/*
* Clear interrupts from button presses during suspend, to avoid
* a wakeup power-button press getting reported to userspace.
*/
regmap_write(axp20x_pek->axp20x->regmap,
AXP20X_IRQ1_STATE + AXP288_IRQ_POKN / 8,
BIT(AXP288_IRQ_POKN % 8));
return 0;
}
static const struct dev_pm_ops axp20x_pek_pm_ops = {
#ifdef CONFIG_PM_SLEEP
.resume_noirq = axp20x_pek_resume_noirq,
#endif
};
static struct platform_driver axp20x_pek_driver = {
.probe = axp20x_pek_probe,
.driver = {
.name = "axp20x-pek",
.pm = &axp20x_pek_pm_ops,
},
};
module_platform_driver(axp20x_pek_driver);
......
......@@ -135,14 +135,17 @@ static int xenkbd_probe(struct xenbus_device *dev,
goto error_nomem;
/* Set input abs params to match backend screen res */
abs = xenbus_read_unsigned(dev->otherend, "feature-abs-pointer", 0);
ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend, "width",
abs = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_FEAT_ABS_POINTER, 0);
ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_WIDTH,
ptr_size[KPARAM_X]);
ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend, "height",
ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_HEIGHT,
ptr_size[KPARAM_Y]);
if (abs) {
ret = xenbus_write(XBT_NIL, dev->nodename,
"request-abs-pointer", "1");
XENKBD_FIELD_REQ_ABS_POINTER, "1");
if (ret) {
pr_warn("xenkbd: can't request abs-pointer\n");
abs = 0;
......@@ -271,14 +274,15 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
xenbus_dev_fatal(dev, ret, "starting transaction");
goto error_irqh;
}
ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_REF, "%lu",
virt_to_gfn(info->page));
if (ret)
goto error_xenbus;
ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref);
ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_RING_GREF,
"%u", info->gref);
if (ret)
goto error_xenbus;
ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
ret = xenbus_printf(xbt, dev->nodename, XENKBD_FIELD_EVT_CHANNEL, "%u",
evtchn);
if (ret)
goto error_xenbus;
......@@ -353,7 +357,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
}
static const struct xenbus_device_id xenkbd_ids[] = {
{ "vkbd" },
{ XENKBD_DRIVER_NAME },
{ "" }
};
......@@ -390,4 +394,4 @@ module_exit(xenkbd_cleanup);
MODULE_DESCRIPTION("Xen virtual keyboard/pointer device frontend");
MODULE_LICENSE("GPL");
MODULE_ALIAS("xen:vkbd");
MODULE_ALIAS("xen:" XENKBD_DRIVER_NAME);
......@@ -58,7 +58,7 @@ struct elan_transport_ops {
int (*get_version)(struct i2c_client *client, bool iap, u8 *version);
int (*get_sm_version)(struct i2c_client *client,
u8* ic_type, u8 *version);
u16 *ic_type, u8 *version);
int (*get_checksum)(struct i2c_client *client, bool iap, u16 *csum);
int (*get_product_id)(struct i2c_client *client, u16 *id);
......@@ -82,6 +82,7 @@ struct elan_transport_ops {
int (*get_report)(struct i2c_client *client, u8 *report);
int (*get_pressure_adjustment)(struct i2c_client *client,
int *adjustment);
int (*get_pattern)(struct i2c_client *client, u8 *pattern);
};
extern const struct elan_transport_ops elan_smbus_ops, elan_i2c_ops;
......
......@@ -5,7 +5,7 @@
*
* Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
* Author: KT Liao <kt.liao@emc.com.tw>
* Version: 1.6.2
* Version: 1.6.3
*
* Based on cyapa driver:
* copyright (c) 2011-2012 Cypress Semiconductor, Inc.
......@@ -41,7 +41,7 @@
#include "elan_i2c.h"
#define DRIVER_NAME "elan_i2c"
#define ELAN_DRIVER_VERSION "1.6.2"
#define ELAN_DRIVER_VERSION "1.6.3"
#define ELAN_VENDOR_ID 0x04f3
#define ETP_MAX_PRESSURE 255
#define ETP_FWIDTH_REDUCE 90
......@@ -78,6 +78,7 @@ struct elan_tp_data {
unsigned int x_res;
unsigned int y_res;
u8 pattern;
u16 product_id;
u8 fw_version;
u8 sm_version;
......@@ -85,7 +86,7 @@ struct elan_tp_data {
u16 fw_checksum;
int pressure_adjustment;
u8 mode;
u8 ic_type;
u16 ic_type;
u16 fw_validpage_count;
u16 fw_signature_address;
......@@ -96,10 +97,10 @@ struct elan_tp_data {
bool baseline_ready;
};
static int elan_get_fwinfo(u8 iap_version, u16 *validpage_count,
static int elan_get_fwinfo(u16 ic_type, u16 *validpage_count,
u16 *signature_address)
{
switch (iap_version) {
switch (ic_type) {
case 0x00:
case 0x06:
case 0x08:
......@@ -119,6 +120,9 @@ static int elan_get_fwinfo(u8 iap_version, u16 *validpage_count,
case 0x0E:
*validpage_count = 640;
break;
case 0x10:
*validpage_count = 1024;
break;
default:
/* unknown ic type clear value */
*validpage_count = 0;
......@@ -305,6 +309,7 @@ static int elan_initialize(struct elan_tp_data *data)
static int elan_query_device_info(struct elan_tp_data *data)
{
int error;
u16 ic_type;
error = data->ops->get_version(data->client, false, &data->fw_version);
if (error)
......@@ -324,7 +329,16 @@ static int elan_query_device_info(struct elan_tp_data *data)
if (error)
return error;
error = elan_get_fwinfo(data->iap_version, &data->fw_validpage_count,
error = data->ops->get_pattern(data->client, &data->pattern);
if (error)
return error;
if (data->pattern == 0x01)
ic_type = data->ic_type;
else
ic_type = data->iap_version;
error = elan_get_fwinfo(ic_type, &data->fw_validpage_count,
&data->fw_signature_address);
if (error)
dev_warn(&data->client->dev,
......@@ -1077,6 +1091,13 @@ static int elan_probe(struct i2c_client *client,
return error;
}
/* Make sure there is something at this address */
error = i2c_smbus_read_byte(client);
if (error < 0) {
dev_dbg(&client->dev, "nothing at this address: %d\n", error);
return -ENXIO;
}
/* Initialize the touchpad. */
error = elan_initialize(data);
if (error)
......@@ -1101,10 +1122,13 @@ static int elan_probe(struct i2c_client *client,
"Elan Touchpad Extra Information:\n"
" Max ABS X,Y: %d,%d\n"
" Width X,Y: %d,%d\n"
" Resolution X,Y: %d,%d (dots/mm)\n",
" Resolution X,Y: %d,%d (dots/mm)\n"
" ic type: 0x%x\n"
" info pattern: 0x%x\n",
data->max_x, data->max_y,
data->width_x, data->width_y,
data->x_res, data->y_res);
data->x_res, data->y_res,
data->ic_type, data->pattern);
/* Set up input device properties based on queried parameters. */
error = elan_setup_input_device(data);
......
......@@ -34,9 +34,12 @@
#define ETP_I2C_DESC_CMD 0x0001
#define ETP_I2C_REPORT_DESC_CMD 0x0002
#define ETP_I2C_STAND_CMD 0x0005
#define ETP_I2C_PATTERN_CMD 0x0100
#define ETP_I2C_UNIQUEID_CMD 0x0101
#define ETP_I2C_FW_VERSION_CMD 0x0102
#define ETP_I2C_SM_VERSION_CMD 0x0103
#define ETP_I2C_IC_TYPE_CMD 0x0103
#define ETP_I2C_OSM_VERSION_CMD 0x0103
#define ETP_I2C_NSM_VERSION_CMD 0x0104
#define ETP_I2C_XY_TRACENUM_CMD 0x0105
#define ETP_I2C_MAX_X_AXIS_CMD 0x0106
#define ETP_I2C_MAX_Y_AXIS_CMD 0x0107
......@@ -239,12 +242,34 @@ static int elan_i2c_get_baseline_data(struct i2c_client *client,
return 0;
}
static int elan_i2c_get_pattern(struct i2c_client *client, u8 *pattern)
{
int error;
u8 val[3];
error = elan_i2c_read_cmd(client, ETP_I2C_PATTERN_CMD, val);
if (error) {
dev_err(&client->dev, "failed to get pattern: %d\n", error);
return error;
}
*pattern = val[1];
return 0;
}
static int elan_i2c_get_version(struct i2c_client *client,
bool iap, u8 *version)
{
int error;
u8 pattern_ver;
u8 val[3];
error = elan_i2c_get_pattern(client, &pattern_ver);
if (error) {
dev_err(&client->dev, "failed to get pattern version\n");
return error;
}
error = elan_i2c_read_cmd(client,
iap ? ETP_I2C_IAP_VERSION_CMD :
ETP_I2C_FW_VERSION_CMD,
......@@ -255,24 +280,54 @@ static int elan_i2c_get_version(struct i2c_client *client,
return error;
}
if (pattern_ver == 0x01)
*version = iap ? val[1] : val[0];
else
*version = val[0];
return 0;
}
static int elan_i2c_get_sm_version(struct i2c_client *client,
u8 *ic_type, u8 *version)
u16 *ic_type, u8 *version)
{
int error;
u8 pattern_ver;
u8 val[3];
error = elan_i2c_read_cmd(client, ETP_I2C_SM_VERSION_CMD, val);
error = elan_i2c_get_pattern(client, &pattern_ver);
if (error) {
dev_err(&client->dev, "failed to get SM version: %d\n", error);
dev_err(&client->dev, "failed to get pattern version\n");
return error;
}
if (pattern_ver == 0x01) {
error = elan_i2c_read_cmd(client, ETP_I2C_IC_TYPE_CMD, val);
if (error) {
dev_err(&client->dev, "failed to get ic type: %d\n",
error);
return error;
}
*ic_type = be16_to_cpup((__be16 *)val);
error = elan_i2c_read_cmd(client, ETP_I2C_NSM_VERSION_CMD,
val);
if (error) {
dev_err(&client->dev, "failed to get SM version: %d\n",
error);
return error;
}
*version = val[1];
} else {
error = elan_i2c_read_cmd(client, ETP_I2C_OSM_VERSION_CMD, val);
if (error) {
dev_err(&client->dev, "failed to get SM version: %d\n",
error);
return error;
}
*version = val[0];
*ic_type = val[1];
}
return 0;
}
......@@ -641,5 +696,7 @@ const struct elan_transport_ops elan_i2c_ops = {
.write_fw_block = elan_i2c_write_fw_block,
.finish_fw_update = elan_i2c_finish_fw_update,
.get_pattern = elan_i2c_get_pattern,
.get_report = elan_i2c_get_report,
};
......@@ -166,7 +166,7 @@ static int elan_smbus_get_version(struct i2c_client *client,
}
static int elan_smbus_get_sm_version(struct i2c_client *client,
u8 *ic_type, u8 *version)
u16 *ic_type, u8 *version)
{
int error;
u8 val[3];
......@@ -495,6 +495,12 @@ static int elan_smbus_finish_fw_update(struct i2c_client *client,
return 0;
}
static int elan_smbus_get_pattern(struct i2c_client *client, u8 *pattern)
{
*pattern = 0;
return 0;
}
const struct elan_transport_ops elan_smbus_ops = {
.initialize = elan_smbus_initialize,
.sleep_control = elan_smbus_sleep_control,
......@@ -524,4 +530,5 @@ const struct elan_transport_ops elan_smbus_ops = {
.finish_fw_update = elan_smbus_finish_fw_update,
.get_report = elan_smbus_get_report,
.get_pattern = elan_smbus_get_pattern,
};
......@@ -1711,6 +1711,17 @@ int elantech_init(struct psmouse *psmouse)
etd->samples[0], etd->samples[1], etd->samples[2]);
}
if (etd->samples[1] == 0x74 && etd->hw_version == 0x03) {
/*
* This module has a bug which makes absolute mode
* unusable, so let's abort so we'll be using standard
* PS/2 protocol.
*/
psmouse_info(psmouse,
"absolute mode broken, forcing standard PS/2 protocol\n");
goto init_fail;
}
if (elantech_set_absolute_mode(psmouse)) {
psmouse_err(psmouse,
"failed to put touchpad into absolute mode.\n");
......
......@@ -9,13 +9,14 @@
* the Free Software Foundation.
*/
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/rmi.h>
#include <linux/firmware.h>
#include <asm/unaligned.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <asm/unaligned.h>
#include "rmi_driver.h"
#include "rmi_f34.h"
......@@ -464,7 +465,7 @@ static int rmi_f34v7_read_queries_bl_version(struct f34_data *f34)
static int rmi_f34v7_read_queries(struct f34_data *f34)
{
int ret;
int i, j;
int i;
u8 base;
int offset;
u8 *ptable;
......@@ -518,10 +519,7 @@ static int rmi_f34v7_read_queries(struct f34_data *f34)
query_1_7.partition_support[1] & HAS_GUEST_CODE;
if (query_0 & HAS_CONFIG_ID) {
char f34_ctrl[CONFIG_ID_SIZE];
int i = 0;
u8 *p = f34->configuration_id;
*p = '\0';
u8 f34_ctrl[CONFIG_ID_SIZE];
ret = rmi_read_block(f34->fn->rmi_dev,
f34->fn->fd.control_base_addr,
......@@ -531,13 +529,11 @@ static int rmi_f34v7_read_queries(struct f34_data *f34)
return ret;
/* Eat leading zeros */
while (i < sizeof(f34_ctrl) && !f34_ctrl[i])
i++;
for (i = 0; i < sizeof(f34_ctrl) - 1 && !f34_ctrl[i]; i++)
/* Empty */;
for (; i < sizeof(f34_ctrl); i++)
p += snprintf(p, f34->configuration_id
+ sizeof(f34->configuration_id) - p,
"%02X", f34_ctrl[i]);
snprintf(f34->configuration_id, sizeof(f34->configuration_id),
"%*phN", (int)sizeof(f34_ctrl) - i, f34_ctrl + i);
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "Configuration ID: %s\n",
f34->configuration_id);
......@@ -545,9 +541,7 @@ static int rmi_f34v7_read_queries(struct f34_data *f34)
f34->v7.partitions = 0;
for (i = 0; i < sizeof(query_1_7.partition_support); i++)
for (j = 0; j < 8; j++)
if (query_1_7.partition_support[i] & (1 << j))
f34->v7.partitions++;
f34->v7.partitions += hweight8(query_1_7.partition_support[i]);
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: Supported partitions: %*ph\n",
__func__, sizeof(query_1_7.partition_support),
......
......@@ -223,20 +223,6 @@ int sparse_keymap_setup(struct input_dev *dev,
}
EXPORT_SYMBOL(sparse_keymap_setup);
/**
* sparse_keymap_free - free memory allocated for sparse keymap
* @dev: Input device using sparse keymap
*
* This function used to free memory allocated by sparse keymap
* in an input device that was set up by sparse_keymap_setup().
* Since sparse_keymap_setup() now uses a managed allocation for the
* keymap copy, use of this function is deprecated.
*/
void sparse_keymap_free(struct input_dev *dev)
{
}
EXPORT_SYMBOL(sparse_keymap_free);
/**
* sparse_keymap_report_entry - report event corresponding to given key entry
* @dev: Input device for which event should be reported
......
......@@ -1114,6 +1114,17 @@ config TOUCHSCREEN_ST1232
To compile this driver as a module, choose M here: the
module will be called st1232_ts.
config TOUCHSCREEN_STMFTS
tristate "STMicroelectronics STMFTS touchscreen"
depends on I2C
depends on LEDS_CLASS
help
Say Y here if you want support for STMicroelectronics
STMFTS touchscreen.
To compile this driver as a module, choose M here: the
module will be called stmfts.
config TOUCHSCREEN_STMPE
tristate "STMicroelectronics STMPE touchscreens"
depends on MFD_STMPE
......
......@@ -67,6 +67,7 @@ obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
obj-$(CONFIG_TOUCHSCREEN_SILEAD) += silead.o
obj-$(CONFIG_TOUCHSCREEN_SIS_I2C) += sis_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ST1232) += st1232.o
obj-$(CONFIG_TOUCHSCREEN_STMFTS) += stmfts.o
obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o
obj-$(CONFIG_TOUCHSCREEN_SUN4I) += sun4i-ts.o
obj-$(CONFIG_TOUCHSCREEN_SUR40) += sur40.o
......
......@@ -15,10 +15,10 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c/mcs.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/platform_data/mcs.h>
#include <linux/slab.h>
/* Registers */
......
......@@ -11,9 +11,9 @@
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/i2c.h>
#include <linux/i2c/mms114.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/platform_data/mms114.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
......
......@@ -264,7 +264,11 @@ static int s3c2410ts_probe(struct platform_device *pdev)
return -ENOENT;
}
clk_prepare_enable(ts.clock);
ret = clk_prepare_enable(ts.clock);
if (ret) {
dev_err(dev, "Failed! to enabled clocks\n");
goto err_clk_get;
}
dev_dbg(dev, "got and enabled clocks\n");
ts.irq_tc = ret = platform_get_irq(pdev, 0);
......@@ -353,7 +357,9 @@ static int s3c2410ts_probe(struct platform_device *pdev)
err_iomap:
iounmap(ts.io);
err_clk:
clk_disable_unprepare(ts.clock);
del_timer_sync(&touch_timer);
err_clk_get:
clk_put(ts.clock);
return ret;
}
......
This diff is collapsed.
......@@ -25,9 +25,9 @@
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/platform_data/tsc2007.h>
#include "tsc2007.h"
int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
......
......@@ -32,13 +32,13 @@
#include <linux/i2c.h>
#include <linux/i2c-ocores.h>
#include <linux/i2c-xiic.h>
#include <linux/i2c/tsc2007.h>
#include <linux/spi/spi.h>
#include <linux/spi/xilinx_spi.h>
#include <linux/spi/max7301.h>
#include <linux/spi/mc33880.h>
#include <linux/platform_data/tsc2007.h>
#include <linux/platform_data/media/timb_radio.h>
#include <linux/platform_data/media/timb_video.h>
......
......@@ -51,7 +51,6 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
int sparse_keymap_setup(struct input_dev *dev,
const struct key_entry *keymap,
int (*setup)(struct input_dev *, struct key_entry *));
void sparse_keymap_free(struct input_dev *dev);
void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
unsigned int value, bool autorelease);
......
#ifndef __LINUX_I2C_TSC2007_H
#define __LINUX_I2C_TSC2007_H
/* linux/i2c/tsc2007.h */
/* linux/platform_data/tsc2007.h */
struct tsc2007_platform_data {
u16 model; /* 2007. */
......
......@@ -600,6 +600,7 @@
#define KEY_APPSELECT 0x244 /* AL Select Task/Application */
#define KEY_SCREENSAVER 0x245 /* AL Screen Saver */
#define KEY_VOICECOMMAND 0x246 /* Listening Voice Command */
#define KEY_ASSISTANT 0x247 /* AL Context-aware desktop assistant */
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
......
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