You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem updates from Dmitry Torokhov: "Two new drivers for Elan hardware (for I2C touchpad and touchscreen found in several Chromebooks and other devices), a driver for Goodix touch panel, and small fixes to Cypress I2C trackpad and other input drivers. Also we switched to use __maybe_unused instead of gating suspend/ resume code with #ifdef guards to get better compile coverage" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (27 commits) Input: gpio_keys - fix warning regarding uninitialized 'button' variable Input: add support for Elan eKTH I2C touchscreens Input: gpio_keys - fix warning regarding uninitialized 'irq' variable Input: cyapa - use 'error' for error codes Input: cyapa - fix resuming the device Input: gpio_keys - add device tree support for interrupt only keys Input: amikbd - allocate temporary keymap buffer on the stack Input: amikbd - fix build if !CONFIG_HW_CONSOLE Input: lm8323 - missing error check in lm8323_set_disable() Input: initialize device counter variables with -1 Input: initialize input_no to -1 to avoid subtraction Input: i8042 - do not try to load on Intel NUC D54250WYK Input: atkbd - correct MSC_SCAN events for force_release keys Input: cyapa - switch to using managed resources Input: lifebook - use "static inline" instead of "inline" in lifebook.h Input: touchscreen - use __maybe_unused instead of ifdef around suspend/resume Input: mouse - use __maybe_unused instead of ifdef around suspend/resume Input: misc - use __maybe_unused instead of ifdef around suspend/resume Input: cap11xx - support for irq-active-high option Input: cap11xx - add support for various cap11xx devices ...
This commit is contained in:
@@ -295,6 +295,19 @@ config TOUCHSCREEN_FUJITSU
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called fujitsu-ts.
|
||||
|
||||
config TOUCHSCREEN_GOODIX
|
||||
tristate "Goodix I2C touchscreen"
|
||||
depends on I2C && ACPI
|
||||
help
|
||||
Say Y here if you have the Goodix touchscreen (such as one
|
||||
installed in Onda v975w tablets) connected to your
|
||||
system.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called goodix.
|
||||
|
||||
config TOUCHSCREEN_ILI210X
|
||||
tristate "Ilitek ILI210X based touchscreen"
|
||||
depends on I2C
|
||||
@@ -334,6 +347,18 @@ config TOUCHSCREEN_GUNZE
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called gunze.
|
||||
|
||||
config TOUCHSCREEN_ELAN
|
||||
tristate "Elan eKTH I2C touchscreen"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here if you have an Elan eKTH I2C touchscreen
|
||||
connected to your system.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called elants_i2c.
|
||||
|
||||
config TOUCHSCREEN_ELO
|
||||
tristate "Elo serial touchscreens"
|
||||
select SERIO
|
||||
|
||||
@@ -31,9 +31,11 @@ obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ELAN) += elants_i2c.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
|
||||
|
||||
@@ -820,8 +820,7 @@ static int ad7877_remove(struct spi_device *spi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ad7877_suspend(struct device *dev)
|
||||
static int __maybe_unused ad7877_suspend(struct device *dev)
|
||||
{
|
||||
struct ad7877 *ts = dev_get_drvdata(dev);
|
||||
|
||||
@@ -830,7 +829,7 @@ static int ad7877_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad7877_resume(struct device *dev)
|
||||
static int __maybe_unused ad7877_resume(struct device *dev)
|
||||
{
|
||||
struct ad7877 *ts = dev_get_drvdata(dev);
|
||||
|
||||
@@ -838,7 +837,6 @@ static int ad7877_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ad7877_pm, ad7877_suspend, ad7877_resume);
|
||||
|
||||
|
||||
@@ -284,8 +284,7 @@ static void ad7879_close(struct input_dev* input)
|
||||
__ad7879_disable(ts);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ad7879_suspend(struct device *dev)
|
||||
static int __maybe_unused ad7879_suspend(struct device *dev)
|
||||
{
|
||||
struct ad7879 *ts = dev_get_drvdata(dev);
|
||||
|
||||
@@ -301,7 +300,7 @@ static int ad7879_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad7879_resume(struct device *dev)
|
||||
static int __maybe_unused ad7879_resume(struct device *dev)
|
||||
{
|
||||
struct ad7879 *ts = dev_get_drvdata(dev);
|
||||
|
||||
@@ -316,7 +315,6 @@ static int ad7879_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
SIMPLE_DEV_PM_OPS(ad7879_pm_ops, ad7879_suspend, ad7879_resume);
|
||||
EXPORT_SYMBOL(ad7879_pm_ops);
|
||||
|
||||
@@ -883,8 +883,7 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ads7846_suspend(struct device *dev)
|
||||
static int __maybe_unused ads7846_suspend(struct device *dev)
|
||||
{
|
||||
struct ads7846 *ts = dev_get_drvdata(dev);
|
||||
|
||||
@@ -906,7 +905,7 @@ static int ads7846_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ads7846_resume(struct device *dev)
|
||||
static int __maybe_unused ads7846_resume(struct device *dev)
|
||||
{
|
||||
struct ads7846 *ts = dev_get_drvdata(dev);
|
||||
|
||||
@@ -927,7 +926,6 @@ static int ads7846_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume);
|
||||
|
||||
|
||||
@@ -2244,8 +2244,7 @@ static int mxt_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int mxt_suspend(struct device *dev)
|
||||
static int __maybe_unused mxt_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct mxt_data *data = i2c_get_clientdata(client);
|
||||
@@ -2261,7 +2260,7 @@ static int mxt_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxt_resume(struct device *dev)
|
||||
static int __maybe_unused mxt_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct mxt_data *data = i2c_get_clientdata(client);
|
||||
@@ -2276,7 +2275,6 @@ static int mxt_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
|
||||
|
||||
|
||||
@@ -417,8 +417,7 @@ static void auo_pixcir_input_close(struct input_dev *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int auo_pixcir_suspend(struct device *dev)
|
||||
static int __maybe_unused auo_pixcir_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct auo_pixcir_ts *ts = i2c_get_clientdata(client);
|
||||
@@ -450,7 +449,7 @@ unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int auo_pixcir_resume(struct device *dev)
|
||||
static int __maybe_unused auo_pixcir_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct auo_pixcir_ts *ts = i2c_get_clientdata(client);
|
||||
@@ -479,7 +478,6 @@ unlock:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops,
|
||||
auo_pixcir_suspend, auo_pixcir_resume);
|
||||
|
||||
@@ -291,8 +291,7 @@ err_free_mem:
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int cy8ctmg110_suspend(struct device *dev)
|
||||
static int __maybe_unused cy8ctmg110_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cy8ctmg110 *ts = i2c_get_clientdata(client);
|
||||
@@ -306,7 +305,7 @@ static int cy8ctmg110_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cy8ctmg110_resume(struct device *dev)
|
||||
static int __maybe_unused cy8ctmg110_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct cy8ctmg110 *ts = i2c_get_clientdata(client);
|
||||
@@ -319,7 +318,6 @@ static int cy8ctmg110_resume(struct device *dev)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume);
|
||||
|
||||
|
||||
@@ -472,8 +472,7 @@ static int cyttsp_disable(struct cyttsp *ts)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int cyttsp_suspend(struct device *dev)
|
||||
static int __maybe_unused cyttsp_suspend(struct device *dev)
|
||||
{
|
||||
struct cyttsp *ts = dev_get_drvdata(dev);
|
||||
int retval = 0;
|
||||
@@ -491,7 +490,7 @@ static int cyttsp_suspend(struct device *dev)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int cyttsp_resume(struct device *dev)
|
||||
static int __maybe_unused cyttsp_resume(struct device *dev)
|
||||
{
|
||||
struct cyttsp *ts = dev_get_drvdata(dev);
|
||||
|
||||
@@ -507,8 +506,6 @@ static int cyttsp_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume);
|
||||
EXPORT_SYMBOL_GPL(cyttsp_pm_ops);
|
||||
|
||||
|
||||
@@ -1092,8 +1092,7 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int edt_ft5x06_ts_suspend(struct device *dev)
|
||||
static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
@@ -1103,7 +1102,7 @@ static int edt_ft5x06_ts_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int edt_ft5x06_ts_resume(struct device *dev)
|
||||
static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
@@ -1112,7 +1111,6 @@ static int edt_ft5x06_ts_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops,
|
||||
edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume);
|
||||
|
||||
@@ -264,8 +264,7 @@ static int eeti_ts_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int eeti_ts_suspend(struct device *dev)
|
||||
static int __maybe_unused eeti_ts_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct eeti_ts_priv *priv = i2c_get_clientdata(client);
|
||||
@@ -284,7 +283,7 @@ static int eeti_ts_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eeti_ts_resume(struct device *dev)
|
||||
static int __maybe_unused eeti_ts_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct eeti_ts_priv *priv = i2c_get_clientdata(client);
|
||||
@@ -302,7 +301,6 @@ static int eeti_ts_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume);
|
||||
|
||||
|
||||
@@ -239,8 +239,7 @@ static const struct i2c_device_id egalax_ts_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, egalax_ts_id);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int egalax_ts_suspend(struct device *dev)
|
||||
static int __maybe_unused egalax_ts_suspend(struct device *dev)
|
||||
{
|
||||
static const u8 suspend_cmd[MAX_I2C_DATA_LEN] = {
|
||||
0x3, 0x6, 0xa, 0x3, 0x36, 0x3f, 0x2, 0, 0, 0
|
||||
@@ -252,13 +251,12 @@ static int egalax_ts_suspend(struct device *dev)
|
||||
return ret > 0 ? 0 : ret;
|
||||
}
|
||||
|
||||
static int egalax_ts_resume(struct device *dev)
|
||||
static int __maybe_unused egalax_ts_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
return egalax_wake_up_device(client);
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* Driver for Goodix Touchscreens
|
||||
*
|
||||
* Copyright (c) 2014 Red Hat Inc.
|
||||
*
|
||||
* This code is based on gt9xx.c authored by andrew@goodix.com:
|
||||
*
|
||||
* 2010 - 2012 Goodix Technology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
struct goodix_ts_data {
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input_dev;
|
||||
int abs_x_max;
|
||||
int abs_y_max;
|
||||
unsigned int max_touch_num;
|
||||
unsigned int int_trigger_type;
|
||||
};
|
||||
|
||||
#define GOODIX_MAX_HEIGHT 4096
|
||||
#define GOODIX_MAX_WIDTH 4096
|
||||
#define GOODIX_INT_TRIGGER 1
|
||||
#define GOODIX_CONTACT_SIZE 8
|
||||
#define GOODIX_MAX_CONTACTS 10
|
||||
|
||||
#define GOODIX_CONFIG_MAX_LENGTH 240
|
||||
|
||||
/* Register defines */
|
||||
#define GOODIX_READ_COOR_ADDR 0x814E
|
||||
#define GOODIX_REG_CONFIG_DATA 0x8047
|
||||
#define GOODIX_REG_VERSION 0x8140
|
||||
|
||||
#define RESOLUTION_LOC 1
|
||||
#define TRIGGER_LOC 6
|
||||
|
||||
static const unsigned long goodix_irq_flags[] = {
|
||||
IRQ_TYPE_EDGE_RISING,
|
||||
IRQ_TYPE_EDGE_FALLING,
|
||||
IRQ_TYPE_LEVEL_LOW,
|
||||
IRQ_TYPE_LEVEL_HIGH,
|
||||
};
|
||||
|
||||
/**
|
||||
* goodix_i2c_read - read data from a register of the i2c slave device.
|
||||
*
|
||||
* @client: i2c device.
|
||||
* @reg: the register to read from.
|
||||
* @buf: raw write data buffer.
|
||||
* @len: length of the buffer to write
|
||||
*/
|
||||
static int goodix_i2c_read(struct i2c_client *client,
|
||||
u16 reg, u8 *buf, int len)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
u16 wbuf = cpu_to_be16(reg);
|
||||
int ret;
|
||||
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].len = 2;
|
||||
msgs[0].buf = (u8 *) &wbuf;
|
||||
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[1].addr = client->addr;
|
||||
msgs[1].len = len;
|
||||
msgs[1].buf = buf;
|
||||
|
||||
ret = i2c_transfer(client->adapter, msgs, 2);
|
||||
return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
|
||||
}
|
||||
|
||||
static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
|
||||
{
|
||||
int touch_num;
|
||||
int error;
|
||||
|
||||
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data,
|
||||
GOODIX_CONTACT_SIZE + 1);
|
||||
if (error) {
|
||||
dev_err(&ts->client->dev, "I2C transfer error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
touch_num = data[0] & 0x0f;
|
||||
if (touch_num > GOODIX_MAX_CONTACTS)
|
||||
return -EPROTO;
|
||||
|
||||
if (touch_num > 1) {
|
||||
data += 1 + GOODIX_CONTACT_SIZE;
|
||||
error = goodix_i2c_read(ts->client,
|
||||
GOODIX_READ_COOR_ADDR +
|
||||
1 + GOODIX_CONTACT_SIZE,
|
||||
data,
|
||||
GOODIX_CONTACT_SIZE * (touch_num - 1));
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
return touch_num;
|
||||
}
|
||||
|
||||
static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
|
||||
{
|
||||
int id = coor_data[0] & 0x0F;
|
||||
int input_x = get_unaligned_le16(&coor_data[1]);
|
||||
int input_y = get_unaligned_le16(&coor_data[3]);
|
||||
int input_w = get_unaligned_le16(&coor_data[5]);
|
||||
|
||||
input_mt_slot(ts->input_dev, id);
|
||||
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
|
||||
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x);
|
||||
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y);
|
||||
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
|
||||
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
|
||||
}
|
||||
|
||||
/**
|
||||
* goodix_process_events - Process incoming events
|
||||
*
|
||||
* @ts: our goodix_ts_data pointer
|
||||
*
|
||||
* Called when the IRQ is triggered. Read the current device state, and push
|
||||
* the input events to the user space.
|
||||
*/
|
||||
static void goodix_process_events(struct goodix_ts_data *ts)
|
||||
{
|
||||
u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
|
||||
int touch_num;
|
||||
int i;
|
||||
|
||||
touch_num = goodix_ts_read_input_report(ts, point_data);
|
||||
if (touch_num < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < touch_num; i++)
|
||||
goodix_ts_report_touch(ts,
|
||||
&point_data[1 + GOODIX_CONTACT_SIZE * i]);
|
||||
|
||||
input_mt_sync_frame(ts->input_dev);
|
||||
input_sync(ts->input_dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* goodix_ts_irq_handler - The IRQ handler
|
||||
*
|
||||
* @irq: interrupt number.
|
||||
* @dev_id: private data pointer.
|
||||
*/
|
||||
static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
static const u8 end_cmd[] = {
|
||||
GOODIX_READ_COOR_ADDR >> 8,
|
||||
GOODIX_READ_COOR_ADDR & 0xff,
|
||||
0
|
||||
};
|
||||
struct goodix_ts_data *ts = dev_id;
|
||||
|
||||
goodix_process_events(ts);
|
||||
|
||||
if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0)
|
||||
dev_err(&ts->client->dev, "I2C write end_cmd error\n");
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* goodix_read_config - Read the embedded configuration of the panel
|
||||
*
|
||||
* @ts: our goodix_ts_data pointer
|
||||
*
|
||||
* Must be called during probe
|
||||
*/
|
||||
static void goodix_read_config(struct goodix_ts_data *ts)
|
||||
{
|
||||
u8 config[GOODIX_CONFIG_MAX_LENGTH];
|
||||
int error;
|
||||
|
||||
error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
|
||||
config,
|
||||
GOODIX_CONFIG_MAX_LENGTH);
|
||||
if (error) {
|
||||
dev_warn(&ts->client->dev,
|
||||
"Error reading config (%d), using defaults\n",
|
||||
error);
|
||||
ts->abs_x_max = GOODIX_MAX_WIDTH;
|
||||
ts->abs_y_max = GOODIX_MAX_HEIGHT;
|
||||
ts->int_trigger_type = GOODIX_INT_TRIGGER;
|
||||
return;
|
||||
}
|
||||
|
||||
ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]);
|
||||
ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]);
|
||||
ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03;
|
||||
if (!ts->abs_x_max || !ts->abs_y_max) {
|
||||
dev_err(&ts->client->dev,
|
||||
"Invalid config, using defaults\n");
|
||||
ts->abs_x_max = GOODIX_MAX_WIDTH;
|
||||
ts->abs_y_max = GOODIX_MAX_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* goodix_read_version - Read goodix touchscreen version
|
||||
*
|
||||
* @client: the i2c client
|
||||
* @version: output buffer containing the version on success
|
||||
*/
|
||||
static int goodix_read_version(struct i2c_client *client, u16 *version)
|
||||
{
|
||||
int error;
|
||||
u8 buf[6];
|
||||
|
||||
error = goodix_i2c_read(client, GOODIX_REG_VERSION, buf, sizeof(buf));
|
||||
if (error) {
|
||||
dev_err(&client->dev, "read version failed: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (version)
|
||||
*version = get_unaligned_le16(&buf[4]);
|
||||
|
||||
dev_info(&client->dev, "IC VERSION: %6ph\n", buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* goodix_i2c_test - I2C test function to check if the device answers.
|
||||
*
|
||||
* @client: the i2c client
|
||||
*/
|
||||
static int goodix_i2c_test(struct i2c_client *client)
|
||||
{
|
||||
int retry = 0;
|
||||
int error;
|
||||
u8 test;
|
||||
|
||||
while (retry++ < 2) {
|
||||
error = goodix_i2c_read(client, GOODIX_REG_CONFIG_DATA,
|
||||
&test, 1);
|
||||
if (!error)
|
||||
return 0;
|
||||
|
||||
dev_err(&client->dev, "i2c test failed attempt %d: %d\n",
|
||||
retry, error);
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* goodix_request_input_dev - Allocate, populate and register the input device
|
||||
*
|
||||
* @ts: our goodix_ts_data pointer
|
||||
*
|
||||
* Must be called during probe
|
||||
*/
|
||||
static int goodix_request_input_dev(struct goodix_ts_data *ts)
|
||||
{
|
||||
int error;
|
||||
|
||||
ts->input_dev = devm_input_allocate_device(&ts->client->dev);
|
||||
if (!ts->input_dev) {
|
||||
dev_err(&ts->client->dev, "Failed to allocate input device.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) |
|
||||
BIT_MASK(EV_KEY) |
|
||||
BIT_MASK(EV_ABS);
|
||||
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0,
|
||||
ts->abs_x_max, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0,
|
||||
ts->abs_y_max, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
|
||||
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
|
||||
|
||||
input_mt_init_slots(ts->input_dev, GOODIX_MAX_CONTACTS,
|
||||
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
|
||||
|
||||
ts->input_dev->name = "Goodix Capacitive TouchScreen";
|
||||
ts->input_dev->phys = "input/ts";
|
||||
ts->input_dev->id.bustype = BUS_I2C;
|
||||
ts->input_dev->id.vendor = 0x0416;
|
||||
ts->input_dev->id.product = 0x1001;
|
||||
ts->input_dev->id.version = 10427;
|
||||
|
||||
error = input_register_device(ts->input_dev);
|
||||
if (error) {
|
||||
dev_err(&ts->client->dev,
|
||||
"Failed to register input device: %d", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct goodix_ts_data *ts;
|
||||
unsigned long irq_flags;
|
||||
int error;
|
||||
u16 version_info;
|
||||
|
||||
dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr);
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
dev_err(&client->dev, "I2C check functionality failed.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
|
||||
if (!ts)
|
||||
return -ENOMEM;
|
||||
|
||||
ts->client = client;
|
||||
i2c_set_clientdata(client, ts);
|
||||
|
||||
error = goodix_i2c_test(client);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "I2C communication failure: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = goodix_read_version(client, &version_info);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "Read version failed.\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
goodix_read_config(ts);
|
||||
|
||||
error = goodix_request_input_dev(ts);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
|
||||
error = devm_request_threaded_irq(&ts->client->dev, client->irq,
|
||||
NULL, goodix_ts_irq_handler,
|
||||
irq_flags, client->name, ts);
|
||||
if (error) {
|
||||
dev_err(&client->dev, "request IRQ failed: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id goodix_ts_id[] = {
|
||||
{ "GDIX1001:00", 0 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct acpi_device_id goodix_acpi_match[] = {
|
||||
{ "GDIX1001", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, goodix_acpi_match);
|
||||
|
||||
static struct i2c_driver goodix_ts_driver = {
|
||||
.probe = goodix_ts_probe,
|
||||
.id_table = goodix_ts_id,
|
||||
.driver = {
|
||||
.name = "Goodix-TS",
|
||||
.owner = THIS_MODULE,
|
||||
.acpi_match_table = goodix_acpi_match,
|
||||
},
|
||||
};
|
||||
module_i2c_driver(goodix_ts_driver);
|
||||
|
||||
MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
|
||||
MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
|
||||
MODULE_DESCRIPTION("Goodix touchscreen driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -311,8 +311,7 @@ static int ili210x_i2c_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ili210x_i2c_suspend(struct device *dev)
|
||||
static int __maybe_unused ili210x_i2c_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
@@ -322,7 +321,7 @@ static int ili210x_i2c_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ili210x_i2c_resume(struct device *dev)
|
||||
static int __maybe_unused ili210x_i2c_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
@@ -331,7 +330,6 @@ static int ili210x_i2c_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ili210x_i2c_pm,
|
||||
ili210x_i2c_suspend, ili210x_i2c_resume);
|
||||
|
||||
@@ -122,8 +122,7 @@ static int micro_ts_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int micro_ts_suspend(struct device *dev)
|
||||
static int __maybe_unused micro_ts_suspend(struct device *dev)
|
||||
{
|
||||
struct touchscreen_data *ts = dev_get_drvdata(dev);
|
||||
|
||||
@@ -132,7 +131,7 @@ static int micro_ts_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int micro_ts_resume(struct device *dev)
|
||||
static int __maybe_unused micro_ts_resume(struct device *dev)
|
||||
{
|
||||
struct touchscreen_data *ts = dev_get_drvdata(dev);
|
||||
struct input_dev *input = ts->input;
|
||||
@@ -146,7 +145,6 @@ static int micro_ts_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops micro_ts_dev_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(micro_ts_suspend, micro_ts_resume)
|
||||
|
||||
@@ -515,8 +515,7 @@ static int mms114_probe(struct i2c_client *client,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int mms114_suspend(struct device *dev)
|
||||
static int __maybe_unused mms114_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct mms114_data *data = i2c_get_clientdata(client);
|
||||
@@ -540,7 +539,7 @@ static int mms114_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mms114_resume(struct device *dev)
|
||||
static int __maybe_unused mms114_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct mms114_data *data = i2c_get_clientdata(client);
|
||||
@@ -559,7 +558,6 @@ static int mms114_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume);
|
||||
|
||||
|
||||
@@ -347,8 +347,7 @@ static void pixcir_input_close(struct input_dev *dev)
|
||||
pixcir_stop(ts);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int pixcir_i2c_ts_suspend(struct device *dev)
|
||||
static int __maybe_unused pixcir_i2c_ts_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
|
||||
@@ -377,7 +376,7 @@ unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pixcir_i2c_ts_resume(struct device *dev)
|
||||
static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
|
||||
@@ -405,7 +404,6 @@ unlock:
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
|
||||
pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
|
||||
|
||||
@@ -243,8 +243,7 @@ static int st1232_ts_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int st1232_ts_suspend(struct device *dev)
|
||||
static int __maybe_unused st1232_ts_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct st1232_ts_data *ts = i2c_get_clientdata(client);
|
||||
@@ -259,7 +258,7 @@ static int st1232_ts_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st1232_ts_resume(struct device *dev)
|
||||
static int __maybe_unused st1232_ts_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct st1232_ts_data *ts = i2c_get_clientdata(client);
|
||||
@@ -274,8 +273,6 @@ static int st1232_ts_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops,
|
||||
st1232_ts_suspend, st1232_ts_resume);
|
||||
|
||||
|
||||
@@ -773,8 +773,7 @@ static int tsc2005_remove(struct spi_device *spi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int tsc2005_suspend(struct device *dev)
|
||||
static int __maybe_unused tsc2005_suspend(struct device *dev)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
struct tsc2005 *ts = spi_get_drvdata(spi);
|
||||
@@ -791,7 +790,7 @@ static int tsc2005_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tsc2005_resume(struct device *dev)
|
||||
static int __maybe_unused tsc2005_resume(struct device *dev)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
struct tsc2005 *ts = spi_get_drvdata(spi);
|
||||
@@ -807,7 +806,6 @@ static int tsc2005_resume(struct device *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user