summaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/ads7846.c35
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c16
-rw-r--r--drivers/input/touchscreen/cyttsp4_core.c2
-rw-r--r--drivers/input/touchscreen/cyttsp_i2c_common.c1
-rw-r--r--drivers/input/touchscreen/da9052_tsi.c2
-rw-r--r--drivers/input/touchscreen/dynapro.c2
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c1
-rw-r--r--drivers/input/touchscreen/egalax_ts_serial.c2
-rw-r--r--drivers/input/touchscreen/ektf2127.c36
-rw-r--r--drivers/input/touchscreen/elo.c2
-rw-r--r--drivers/input/touchscreen/exc3000.c7
-rw-r--r--drivers/input/touchscreen/fsl-imx25-tcq.c2
-rw-r--r--drivers/input/touchscreen/fujitsu_ts.c2
-rw-r--r--drivers/input/touchscreen/goodix_berlin_spi.c24
-rw-r--r--drivers/input/touchscreen/gunze.c2
-rw-r--r--drivers/input/touchscreen/hampshire.c2
-rw-r--r--drivers/input/touchscreen/himax_hx83112b.c135
-rw-r--r--drivers/input/touchscreen/ili210x.c127
-rw-r--r--drivers/input/touchscreen/imagis.c33
-rw-r--r--drivers/input/touchscreen/inexio.c2
-rw-r--r--drivers/input/touchscreen/mtouch.c2
-rw-r--r--drivers/input/touchscreen/penmount.c2
-rw-r--r--drivers/input/touchscreen/rohm_bu21023.c95
-rw-r--r--drivers/input/touchscreen/sur40.c2
-rw-r--r--drivers/input/touchscreen/touchit213.c2
-rw-r--r--drivers/input/touchscreen/touchright.c2
-rw-r--r--drivers/input/touchscreen/touchwin.c2
-rw-r--r--drivers/input/touchscreen/tsc40.c2
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c15
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c37
30 files changed, 359 insertions, 237 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 4d13db13b9e5..4247283c7271 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -138,6 +138,7 @@ struct ads7846 {
void *filter_data;
int (*get_pendown_state)(void);
struct gpio_desc *gpio_pendown;
+ struct gpio_desc *gpio_hsync;
void (*wait_for_sync)(void);
};
@@ -634,10 +635,6 @@ ATTRIBUTE_GROUPS(ads784x);
/*--------------------------------------------------------------------------*/
-static void null_wait_for_sync(void)
-{
-}
-
static int ads7846_debounce_filter(void *ads, int data_idx, int *val)
{
struct ads7846 *ts = ads;
@@ -790,6 +787,28 @@ static int ads7846_filter(struct ads7846 *ts)
return 0;
}
+static void ads7846_wait_for_hsync(struct ads7846 *ts)
+{
+ if (ts->wait_for_sync) {
+ ts->wait_for_sync();
+ return;
+ }
+
+ if (!ts->gpio_hsync)
+ return;
+
+ /*
+ * Wait for HSYNC to assert the line should be flagged
+ * as active low so here we are waiting for it to assert
+ */
+ while (!gpiod_get_value(ts->gpio_hsync))
+ cpu_relax();
+
+ /* Then we wait for it do de-assert */
+ while (gpiod_get_value(ts->gpio_hsync))
+ cpu_relax();
+}
+
static void ads7846_read_state(struct ads7846 *ts)
{
struct ads7846_packet *packet = ts->packet;
@@ -800,7 +819,7 @@ static void ads7846_read_state(struct ads7846 *ts)
packet->last_cmd_idx = 0;
while (true) {
- ts->wait_for_sync();
+ ads7846_wait_for_hsync(ts);
m = &ts->msg[msg_idx];
error = spi_sync(ts->spi, m);
@@ -1268,7 +1287,11 @@ static int ads7846_probe(struct spi_device *spi)
ts->penirq_recheck_delay_usecs =
pdata->penirq_recheck_delay_usecs;
- ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync;
+ ts->wait_for_sync = pdata->wait_for_sync;
+
+ ts->gpio_hsync = devm_gpiod_get_optional(dev, "ti,hsync", GPIOD_IN);
+ if (IS_ERR(ts->gpio_hsync))
+ return PTR_ERR(ts->gpio_hsync);
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));
snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 8a606bd441ae..cfc92157701f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3069,9 +3069,7 @@ static struct attribute *mxt_attrs[] = {
NULL
};
-static const struct attribute_group mxt_attr_group = {
- .attrs = mxt_attrs,
-};
+ATTRIBUTE_GROUPS(mxt);
static void mxt_start(struct mxt_data *data)
{
@@ -3348,18 +3346,8 @@ static int mxt_probe(struct i2c_client *client)
if (error)
goto err_disable_regulators;
- error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
- if (error) {
- dev_err(&client->dev, "Failure %d creating sysfs group\n",
- error);
- goto err_free_object;
- }
-
return 0;
-err_free_object:
- mxt_free_input_device(data);
- mxt_free_object_table(data);
err_disable_regulators:
regulator_bulk_disable(ARRAY_SIZE(data->regulators),
data->regulators);
@@ -3371,7 +3359,6 @@ static void mxt_remove(struct i2c_client *client)
struct mxt_data *data = i2c_get_clientdata(client);
disable_irq(data->irq);
- sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
mxt_free_input_device(data);
mxt_free_object_table(data);
regulator_bulk_disable(ARRAY_SIZE(data->regulators),
@@ -3455,6 +3442,7 @@ MODULE_DEVICE_TABLE(i2c, mxt_id);
static struct i2c_driver mxt_driver = {
.driver = {
.name = "atmel_mxt_ts",
+ .dev_groups = mxt_groups,
.of_match_table = mxt_of_match,
.acpi_match_table = ACPI_PTR(mxt_acpi_id),
.pm = pm_sleep_ptr(&mxt_pm_ops),
diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c
index 7cb26929dc73..9dc25eb2be44 100644
--- a/drivers/input/touchscreen/cyttsp4_core.c
+++ b/drivers/input/touchscreen/cyttsp4_core.c
@@ -871,7 +871,7 @@ static void cyttsp4_get_mt_touches(struct cyttsp4_mt_data *md, int num_cur_tch)
struct cyttsp4_touch tch;
int sig;
int i, j, t = 0;
- int ids[max(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)];
+ int ids[MAX(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)];
memset(ids, 0, si->si_ofs.tch_abs[CY_TCH_T].max * sizeof(int));
for (i = 0; i < num_cur_tch; i++) {
diff --git a/drivers/input/touchscreen/cyttsp_i2c_common.c b/drivers/input/touchscreen/cyttsp_i2c_common.c
index 1f0b6d6f48e2..7e752fb9fad7 100644
--- a/drivers/input/touchscreen/cyttsp_i2c_common.c
+++ b/drivers/input/touchscreen/cyttsp_i2c_common.c
@@ -81,5 +81,6 @@ int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf,
EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data);
+MODULE_DESCRIPTION("Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Cypress");
diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c
index d71690ce6463..52e0e834e76f 100644
--- a/drivers/input/touchscreen/da9052_tsi.c
+++ b/drivers/input/touchscreen/da9052_tsi.c
@@ -232,7 +232,7 @@ static int da9052_ts_probe(struct platform_device *pdev)
if (!da9052)
return -EINVAL;
- tsi = kzalloc(sizeof(struct da9052_tsi), GFP_KERNEL);
+ tsi = kzalloc(sizeof(*tsi), GFP_KERNEL);
input_dev = input_allocate_device();
if (!tsi || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c
index dc07fca7c5ed..fe626a226b85 100644
--- a/drivers/input/touchscreen/dynapro.c
+++ b/drivers/input/touchscreen/dynapro.c
@@ -110,7 +110,7 @@ static int dynapro_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- pdynapro = kzalloc(sizeof(struct dynapro), GFP_KERNEL);
+ pdynapro = kzalloc(sizeof(*pdynapro), GFP_KERNEL);
input_dev = input_allocate_device();
if (!pdynapro || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 06ec0f2e18ae..42f99e57fbb7 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -1496,6 +1496,7 @@ static const struct of_device_id edt_ft5x06_of_match[] = {
{ .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data },
{ .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data },
{ .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data },
+ { .compatible = "focaltech,ft5426", .data = &edt_ft5506_data },
{ .compatible = "focaltech,ft5452", .data = &edt_ft5452_data },
/* Note focaltech vendor prefix for compatibility with ft6236.c */
{ .compatible = "focaltech,ft6236", .data = &edt_ft6236_data },
diff --git a/drivers/input/touchscreen/egalax_ts_serial.c b/drivers/input/touchscreen/egalax_ts_serial.c
index 375922d3a6d1..07a4aa1c19bb 100644
--- a/drivers/input/touchscreen/egalax_ts_serial.c
+++ b/drivers/input/touchscreen/egalax_ts_serial.c
@@ -99,7 +99,7 @@ static int egalax_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int error;
- egalax = kzalloc(sizeof(struct egalax), GFP_KERNEL);
+ egalax = kzalloc(sizeof(*egalax), GFP_KERNEL);
input_dev = input_allocate_device();
if (!egalax || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
index ab8159e1c99d..46a0611fac82 100644
--- a/drivers/input/touchscreen/ektf2127.c
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -13,6 +13,7 @@
* Hans de Goede <hdegoede@redhat.com>
*/
+#include <linux/bits.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
@@ -46,6 +47,11 @@ struct ektf2127_ts {
struct input_dev *input;
struct gpio_desc *power_gpios;
struct touchscreen_properties prop;
+ int status_shift;
+};
+
+struct ektf2127_i2c_chip_data {
+ int status_shift;
};
static void ektf2127_parse_coordinates(const u8 *buf, unsigned int touch_count,
@@ -112,8 +118,8 @@ static void ektf2127_report2_contact(struct ektf2127_ts *ts, int slot,
static void ektf2127_report2_event(struct ektf2127_ts *ts, const u8 *buf)
{
- ektf2127_report2_contact(ts, 0, &buf[1], !!(buf[7] & 2));
- ektf2127_report2_contact(ts, 1, &buf[4], !!(buf[7] & 4));
+ ektf2127_report2_contact(ts, 0, &buf[1], !!(buf[7] & BIT(ts->status_shift)));
+ ektf2127_report2_contact(ts, 1, &buf[4], !!(buf[7] & BIT(ts->status_shift + 1)));
input_mt_sync_frame(ts->input);
input_sync(ts->input);
@@ -247,6 +253,7 @@ static int ektf2127_query_dimension(struct i2c_client *client, bool width)
static int ektf2127_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
+ const struct ektf2127_i2c_chip_data *chip_data;
struct ektf2127_ts *ts;
struct input_dev *input;
u8 buf[4];
@@ -303,6 +310,13 @@ static int ektf2127_probe(struct i2c_client *client)
return error;
ts->input = input;
+
+ chip_data = i2c_get_match_data(client);
+ if (!chip_data)
+ return dev_err_probe(&client->dev, -EINVAL, "missing chip data\n");
+
+ ts->status_shift = chip_data->status_shift;
+
input_set_drvdata(input, ts);
error = devm_request_threaded_irq(dev, client->irq,
@@ -325,18 +339,28 @@ static int ektf2127_probe(struct i2c_client *client)
return 0;
}
+static const struct ektf2127_i2c_chip_data ektf2127_data = {
+ .status_shift = 1,
+};
+
+static const struct ektf2127_i2c_chip_data ektf2232_data = {
+ .status_shift = 0,
+};
+
#ifdef CONFIG_OF
static const struct of_device_id ektf2127_of_match[] = {
- { .compatible = "elan,ektf2127" },
- { .compatible = "elan,ektf2132" },
+ { .compatible = "elan,ektf2127", .data = &ektf2127_data},
+ { .compatible = "elan,ektf2132", .data = &ektf2127_data},
+ { .compatible = "elan,ektf2232", .data = &ektf2232_data},
{}
};
MODULE_DEVICE_TABLE(of, ektf2127_of_match);
#endif
static const struct i2c_device_id ektf2127_i2c_id[] = {
- { "ektf2127" },
- { "ektf2132" },
+ { .name = "ektf2127", .driver_data = (long)&ektf2127_data },
+ { .name = "ektf2132", .driver_data = (long)&ektf2127_data },
+ { .name = "ektf2232", .driver_data = (long)&ektf2232_data },
{}
};
MODULE_DEVICE_TABLE(i2c, ektf2127_i2c_id);
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index 96173232e53f..eb883db55420 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -307,7 +307,7 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- elo = kzalloc(sizeof(struct elo), GFP_KERNEL);
+ elo = kzalloc(sizeof(*elo), GFP_KERNEL);
input_dev = input_allocate_device();
if (!elo || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/exc3000.c b/drivers/input/touchscreen/exc3000.c
index a4030cc9ff60..2e77cfb63f32 100644
--- a/drivers/input/touchscreen/exc3000.c
+++ b/drivers/input/touchscreen/exc3000.c
@@ -53,6 +53,7 @@ enum eeti_dev_id {
EETI_EXC3000,
EETI_EXC80H60,
EETI_EXC80H84,
+ EETI_EXC81W32,
};
static struct eeti_dev_info exc3000_info[] = {
@@ -68,6 +69,10 @@ static struct eeti_dev_info exc3000_info[] = {
.name = "EETI EXC80H84 Touch Screen",
.max_xy = SZ_16K - 1,
},
+ [EETI_EXC81W32] = {
+ .name = "EETI EXC81W32 Touch Screen",
+ .max_xy = SZ_16K - 1,
+ },
};
struct exc3000_data {
@@ -441,6 +446,7 @@ static const struct i2c_device_id exc3000_id[] = {
{ "exc3000", EETI_EXC3000 },
{ "exc80h60", EETI_EXC80H60 },
{ "exc80h84", EETI_EXC80H84 },
+ { "exc81w32", EETI_EXC81W32 },
{ }
};
MODULE_DEVICE_TABLE(i2c, exc3000_id);
@@ -450,6 +456,7 @@ static const struct of_device_id exc3000_of_match[] = {
{ .compatible = "eeti,exc3000", .data = &exc3000_info[EETI_EXC3000] },
{ .compatible = "eeti,exc80h60", .data = &exc3000_info[EETI_EXC80H60] },
{ .compatible = "eeti,exc80h84", .data = &exc3000_info[EETI_EXC80H84] },
+ { .compatible = "eeti,exc81w32", .data = &exc3000_info[EETI_EXC81W32] },
{ }
};
MODULE_DEVICE_TABLE(of, exc3000_of_match);
diff --git a/drivers/input/touchscreen/fsl-imx25-tcq.c b/drivers/input/touchscreen/fsl-imx25-tcq.c
index 60a7246c5157..a32708652d10 100644
--- a/drivers/input/touchscreen/fsl-imx25-tcq.c
+++ b/drivers/input/touchscreen/fsl-imx25-tcq.c
@@ -38,7 +38,7 @@ struct mx25_tcq_priv {
struct device *dev;
};
-static struct regmap_config mx25_tcq_regconfig = {
+static const struct regmap_config mx25_tcq_regconfig = {
.fast_io = true,
.max_register = 0x5c,
.reg_bits = 32,
diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c
index 3b0b8fccc3f0..1a3e14ea2e08 100644
--- a/drivers/input/touchscreen/fujitsu_ts.c
+++ b/drivers/input/touchscreen/fujitsu_ts.c
@@ -99,7 +99,7 @@ static int fujitsu_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- fujitsu = kzalloc(sizeof(struct fujitsu), GFP_KERNEL);
+ fujitsu = kzalloc(sizeof(*fujitsu), GFP_KERNEL);
input_dev = input_allocate_device();
if (!fujitsu || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/goodix_berlin_spi.c b/drivers/input/touchscreen/goodix_berlin_spi.c
index 4cc557da048a..82774a412956 100644
--- a/drivers/input/touchscreen/goodix_berlin_spi.c
+++ b/drivers/input/touchscreen/goodix_berlin_spi.c
@@ -36,13 +36,14 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf,
struct spi_transfer xfers;
struct spi_message spi_msg;
const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */
- u8 *buf;
int error;
if (reg_size != GOODIX_BERLIN_REGISTER_WIDTH)
return -EINVAL;
- buf = kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size, GFP_KERNEL);
+ u8 *buf __free(kfree) =
+ kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size,
+ GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -62,12 +63,12 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf,
spi_message_add_tail(&xfers, &spi_msg);
error = spi_sync(spi, &spi_msg);
- if (error < 0)
+ if (error < 0) {
dev_err(&spi->dev, "spi transfer error, %d", error);
- else
- memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size);
+ return error;
+ }
- kfree(buf);
+ memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size);
return error;
}
@@ -79,10 +80,10 @@ static int goodix_berlin_spi_write(void *context, const void *data,
struct spi_transfer xfers;
struct spi_message spi_msg;
const u32 *reg = data; /* reg is stored as native u32 at start of buffer */
- u8 *buf;
int error;
- buf = kzalloc(GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL);
+ u8 *buf __free(kfree) =
+ kzalloc(GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -100,11 +101,12 @@ static int goodix_berlin_spi_write(void *context, const void *data,
spi_message_add_tail(&xfers, &spi_msg);
error = spi_sync(spi, &spi_msg);
- if (error < 0)
+ if (error < 0) {
dev_err(&spi->dev, "spi transfer error, %d", error);
+ return error;
+ }
- kfree(buf);
- return error;
+ return 0;
}
static const struct regmap_config goodix_berlin_spi_regmap_conf = {
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
index 5a5f9da73fa1..dbf92fb02f80 100644
--- a/drivers/input/touchscreen/gunze.c
+++ b/drivers/input/touchscreen/gunze.c
@@ -97,7 +97,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- gunze = kzalloc(sizeof(struct gunze), GFP_KERNEL);
+ gunze = kzalloc(sizeof(*gunze), GFP_KERNEL);
input_dev = input_allocate_device();
if (!gunze || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/hampshire.c b/drivers/input/touchscreen/hampshire.c
index 5c4d877564ee..dc0a2482ddd6 100644
--- a/drivers/input/touchscreen/hampshire.c
+++ b/drivers/input/touchscreen/hampshire.c
@@ -109,7 +109,7 @@ static int hampshire_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- phampshire = kzalloc(sizeof(struct hampshire), GFP_KERNEL);
+ phampshire = kzalloc(sizeof(*phampshire), GFP_KERNEL);
input_dev = input_allocate_device();
if (!phampshire || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c
index bafabd06dabc..9ed3bccde4ac 100644
--- a/drivers/input/touchscreen/himax_hx83112b.c
+++ b/drivers/input/touchscreen/himax_hx83112b.c
@@ -4,6 +4,9 @@
*
* Copyright (C) 2022 Job Noorman <job@noorman.info>
*
+ * HX83100A support
+ * Copyright (C) 2024 Felix Kaechele <felix@kaechele.ca>
+ *
* This code is based on "Himax Android Driver Sample Code for QCT platform":
*
* Copyright (C) 2017 Himax Corporation.
@@ -20,16 +23,22 @@
#include <linux/kernel.h>
#include <linux/regmap.h>
-#define HIMAX_ID_83112B 0x83112b
-
#define HIMAX_MAX_POINTS 10
-#define HIMAX_REG_CFG_SET_ADDR 0x00
-#define HIMAX_REG_CFG_INIT_READ 0x0c
-#define HIMAX_REG_CFG_READ_VALUE 0x08
-#define HIMAX_REG_READ_EVENT 0x30
+#define HIMAX_AHB_ADDR_BYTE_0 0x00
+#define HIMAX_AHB_ADDR_RDATA_BYTE_0 0x08
+#define HIMAX_AHB_ADDR_ACCESS_DIRECTION 0x0c
+#define HIMAX_AHB_ADDR_INCR4 0x0d
+#define HIMAX_AHB_ADDR_CONTI 0x13
+#define HIMAX_AHB_ADDR_EVENT_STACK 0x30
+
+#define HIMAX_AHB_CMD_ACCESS_DIRECTION_READ 0x00
+#define HIMAX_AHB_CMD_INCR4 0x10
+#define HIMAX_AHB_CMD_CONTI 0x31
-#define HIMAX_CFG_PRODUCT_ID 0x900000d0
+#define HIMAX_REG_ADDR_ICID 0x900000d0
+
+#define HX83100A_REG_FW_EVENT_STACK 0x90060000
#define HIMAX_INVALID_COORD 0xffff
@@ -49,7 +58,16 @@ struct himax_event {
static_assert(sizeof(struct himax_event) == 56);
+struct himax_ts_data;
+struct himax_chip {
+ u32 id;
+ int (*check_id)(struct himax_ts_data *ts);
+ int (*read_events)(struct himax_ts_data *ts, struct himax_event *event,
+ size_t length);
+};
+
struct himax_ts_data {
+ const struct himax_chip *chip;
struct gpio_desc *gpiod_rst;
struct input_dev *input_dev;
struct i2c_client *client;
@@ -63,19 +81,60 @@ static const struct regmap_config himax_regmap_config = {
.val_format_endian = REGMAP_ENDIAN_LITTLE,
};
-static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst)
+static int himax_bus_enable_burst(struct himax_ts_data *ts)
{
int error;
- error = regmap_write(ts->regmap, HIMAX_REG_CFG_SET_ADDR, address);
+ error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_CONTI,
+ HIMAX_AHB_CMD_CONTI);
if (error)
return error;
- error = regmap_write(ts->regmap, HIMAX_REG_CFG_INIT_READ, 0x0);
+ error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_INCR4,
+ HIMAX_AHB_CMD_INCR4);
if (error)
return error;
- error = regmap_read(ts->regmap, HIMAX_REG_CFG_READ_VALUE, dst);
+ return 0;
+}
+
+static int himax_bus_read(struct himax_ts_data *ts, u32 address, void *dst,
+ size_t length)
+{
+ int error;
+
+ if (length > 4) {
+ error = himax_bus_enable_burst(ts);
+ if (error)
+ return error;
+ }
+
+ error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_BYTE_0, address);
+ if (error)
+ return error;
+
+ error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_ACCESS_DIRECTION,
+ HIMAX_AHB_CMD_ACCESS_DIRECTION_READ);
+ if (error)
+ return error;
+
+ if (length > 4)
+ error = regmap_noinc_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0,
+ dst, length);
+ else
+ error = regmap_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0,
+ dst);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static int himax_read_mcu(struct himax_ts_data *ts, u32 address, u32 *dst)
+{
+ int error;
+
+ error = himax_bus_read(ts, address, dst, sizeof(dst));
if (error)
return error;
@@ -101,7 +160,7 @@ static int himax_read_product_id(struct himax_ts_data *ts, u32 *product_id)
{
int error;
- error = himax_read_config(ts, HIMAX_CFG_PRODUCT_ID, product_id);
+ error = himax_read_mcu(ts, HIMAX_REG_ADDR_ICID, product_id);
if (error)
return error;
@@ -120,15 +179,12 @@ static int himax_check_product_id(struct himax_ts_data *ts)
dev_dbg(&ts->client->dev, "Product id: %x\n", product_id);
- switch (product_id) {
- case HIMAX_ID_83112B:
+ if (product_id == ts->chip->id)
return 0;
- default:
- dev_err(&ts->client->dev,
- "Unknown product id: %x\n", product_id);
- return -EINVAL;
- }
+ dev_err(&ts->client->dev, "Unknown product id: %x\n",
+ product_id);
+ return -EINVAL;
}
static int himax_input_register(struct himax_ts_data *ts)
@@ -230,13 +286,25 @@ static bool himax_verify_checksum(struct himax_ts_data *ts,
return true;
}
+static int himax_read_events(struct himax_ts_data *ts,
+ struct himax_event *event, size_t length)
+{
+ return regmap_raw_read(ts->regmap, HIMAX_AHB_ADDR_EVENT_STACK, event,
+ length);
+}
+
+static int hx83100a_read_events(struct himax_ts_data *ts,
+ struct himax_event *event, size_t length)
+{
+ return himax_bus_read(ts, HX83100A_REG_FW_EVENT_STACK, event, length);
+};
+
static int himax_handle_input(struct himax_ts_data *ts)
{
int error;
struct himax_event event;
- error = regmap_raw_read(ts->regmap, HIMAX_REG_READ_EVENT, &event,
- sizeof(event));
+ error = ts->chip->read_events(ts, &event, sizeof(event));
if (error) {
dev_err(&ts->client->dev, "Failed to read input event: %d\n",
error);
@@ -282,6 +350,7 @@ static int himax_probe(struct i2c_client *client)
i2c_set_clientdata(client, ts);
ts->client = client;
+ ts->chip = i2c_get_match_data(client);
ts->regmap = devm_regmap_init_i2c(client, &himax_regmap_config);
error = PTR_ERR_OR_ZERO(ts->regmap);
@@ -299,9 +368,11 @@ static int himax_probe(struct i2c_client *client)
himax_reset(ts);
- error = himax_check_product_id(ts);
- if (error)
- return error;
+ if (ts->chip->check_id) {
+ error = himax_check_product_id(ts);
+ if (error)
+ return error;
+ }
error = himax_input_register(ts);
if (error)
@@ -334,15 +405,27 @@ static int himax_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(himax_pm_ops, himax_suspend, himax_resume);
+static const struct himax_chip hx83100a_chip = {
+ .read_events = hx83100a_read_events,
+};
+
+static const struct himax_chip hx83112b_chip = {
+ .id = 0x83112b,
+ .check_id = himax_check_product_id,
+ .read_events = himax_read_events,
+};
+
static const struct i2c_device_id himax_ts_id[] = {
- { "hx83112b" },
+ { "hx83100a", (kernel_ulong_t)&hx83100a_chip },
+ { "hx83112b", (kernel_ulong_t)&hx83112b_chip },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, himax_ts_id);
#ifdef CONFIG_OF
static const struct of_device_id himax_of_match[] = {
- { .compatible = "himax,hx83112b" },
+ { .compatible = "himax,hx83100a", .data = &hx83100a_chip },
+ { .compatible = "himax,hx83112b", .data = &hx83112b_chip },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, himax_of_match);
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index 79bdb2b10949..4573844c3395 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -582,14 +582,12 @@ static ssize_t ili210x_calibrate(struct device *dev,
}
static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ili210x_calibrate);
-static int ili251x_firmware_to_buffer(const struct firmware *fw,
- u8 **buf, u16 *ac_end, u16 *df_end)
+static const u8 *ili251x_firmware_to_buffer(const struct firmware *fw,
+ u16 *ac_end, u16 *df_end)
{
const struct ihex_binrec *rec;
u32 fw_addr, fw_last_addr = 0;
u16 fw_len;
- u8 *fw_buf;
- int error;
/*
* The firmware ihex blob can never be bigger than 64 kiB, so make this
@@ -597,9 +595,9 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,
* once, copy them all into this buffer at the right locations, and then
* do all operations on this linear buffer.
*/
- fw_buf = kzalloc(SZ_64K, GFP_KERNEL);
+ u8* fw_buf __free(kvfree) = kvmalloc(SZ_64K, GFP_KERNEL);
if (!fw_buf)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
rec = (const struct ihex_binrec *)fw->data;
while (rec) {
@@ -607,10 +605,8 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,
fw_len = be16_to_cpu(rec->len);
/* The last 32 Byte firmware block can be 0xffe0 */
- if (fw_addr + fw_len > SZ_64K || fw_addr > SZ_64K - 32) {
- error = -EFBIG;
- goto err_big;
- }
+ if (fw_addr + fw_len > SZ_64K || fw_addr > SZ_64K - 32)
+ return ERR_PTR(-EFBIG);
/* Find the last address before DF start address, that is AC end */
if (fw_addr == 0xf000)
@@ -623,12 +619,8 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,
/* DF end address is the last address in the firmware blob */
*df_end = fw_addr + fw_len;
- *buf = fw_buf;
- return 0;
-err_big:
- kfree(fw_buf);
- return error;
+ return_ptr(fw_buf);
}
/* Switch mode between Application and BootLoader */
@@ -691,7 +683,7 @@ static int ili251x_firmware_busy(struct i2c_client *client)
return 0;
}
-static int ili251x_firmware_write_to_ic(struct device *dev, u8 *fwbuf,
+static int ili251x_firmware_write_to_ic(struct device *dev, const u8 *fwbuf,
u16 start, u16 end, u8 dataflash)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -776,47 +768,17 @@ static void ili210x_hardware_reset(struct gpio_desc *reset_gpio)
msleep(300);
}
-static ssize_t ili210x_firmware_update_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static int ili210x_do_firmware_update(struct ili210x *priv,
+ const u8 *fwbuf, u16 ac_end, u16 df_end)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct ili210x *priv = i2c_get_clientdata(client);
- const char *fwname = ILI251X_FW_FILENAME;
- const struct firmware *fw;
- u16 ac_end, df_end;
- u8 *fwbuf;
+ struct i2c_client *client = priv->client;
+ struct device *dev = &client->dev;
int error;
int i;
- error = request_ihex_firmware(&fw, fwname, dev);
- if (error) {
- dev_err(dev, "Failed to request firmware %s, error=%d\n",
- fwname, error);
- return error;
- }
-
- error = ili251x_firmware_to_buffer(fw, &fwbuf, &ac_end, &df_end);
- release_firmware(fw);
- if (error)
- return error;
-
- /*
- * Disable touchscreen IRQ, so that we would not get spurious touch
- * interrupt during firmware update, and so that the IRQ handler won't
- * trigger and interfere with the firmware update. There is no bit in
- * the touch controller to disable the IRQs during update, so we have
- * to do it this way here.
- */
- disable_irq(client->irq);
-
- dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);
-
- ili210x_hardware_reset(priv->reset_gpio);
-
error = ili251x_firmware_reset(client);
if (error)
- goto exit;
+ return error;
/* This may not succeed on first try, so re-try a few times. */
for (i = 0; i < 5; i++) {
@@ -826,7 +788,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
}
if (error)
- goto exit;
+ return error;
dev_dbg(dev, "IC is now in BootLoader mode\n");
@@ -835,7 +797,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
error = ili251x_firmware_write_to_ic(dev, fwbuf, 0xf000, df_end, 1);
if (error) {
dev_err(dev, "DF firmware update failed, error=%d\n", error);
- goto exit;
+ return error;
}
dev_dbg(dev, "DataFlash firmware written\n");
@@ -843,7 +805,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
error = ili251x_firmware_write_to_ic(dev, fwbuf, 0x2000, ac_end, 0);
if (error) {
dev_err(dev, "AC firmware update failed, error=%d\n", error);
- goto exit;
+ return error;
}
dev_dbg(dev, "Application firmware written\n");
@@ -856,22 +818,61 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
}
if (error)
- goto exit;
+ return error;
dev_dbg(dev, "IC is now in Application mode\n");
error = ili251x_firmware_update_cached_state(dev);
if (error)
- goto exit;
+ return error;
- error = count;
+ return 0;
+}
-exit:
- ili210x_hardware_reset(priv->reset_gpio);
- dev_dbg(dev, "Firmware update ended, error=%i\n", error);
- enable_irq(client->irq);
- kfree(fwbuf);
- return error;
+static ssize_t ili210x_firmware_update_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ili210x *priv = i2c_get_clientdata(client);
+ const char *fwname = ILI251X_FW_FILENAME;
+ u16 ac_end, df_end;
+ int error;
+
+ const struct firmware *fw __free(firmware) = NULL;
+ error = request_ihex_firmware(&fw, fwname, dev);
+ if (error) {
+ dev_err(dev, "Failed to request firmware %s, error=%d\n",
+ fwname, error);
+ return error;
+ }
+
+ const u8* fwbuf __free(kvfree) =
+ ili251x_firmware_to_buffer(fw, &ac_end, &df_end);
+ error = PTR_ERR_OR_ZERO(fwbuf);
+ if (error)
+ return error;
+
+ /*
+ * Disable touchscreen IRQ, so that we would not get spurious touch
+ * interrupt during firmware update, and so that the IRQ handler won't
+ * trigger and interfere with the firmware update. There is no bit in
+ * the touch controller to disable the IRQs during update, so we have
+ * to do it this way here.
+ */
+ scoped_guard(disable_irq, &client->irq) {
+ dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);
+
+ ili210x_hardware_reset(priv->reset_gpio);
+
+ error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end);
+
+ ili210x_hardware_reset(priv->reset_gpio);
+
+ dev_dbg(dev, "Firmware update ended, error=%i\n", error);
+ }
+
+ return error ?: count;
}
static DEVICE_ATTR(firmware_update, 0200, NULL, ili210x_firmware_update_store);
diff --git a/drivers/input/touchscreen/imagis.c b/drivers/input/touchscreen/imagis.c
index 074dd6c342ec..aeabf8d057de 100644
--- a/drivers/input/touchscreen/imagis.c
+++ b/drivers/input/touchscreen/imagis.c
@@ -12,9 +12,17 @@
#include <linux/property.h>
#include <linux/regulator/consumer.h>
+#define IST30XX_REG_STATUS 0x20
+#define IST30XX_REG_CHIPID (0x40000000 | IST3038C_DIRECT_ACCESS)
+
+#define IST30XX_WHOAMI 0x30003000
+#define IST30XXA_WHOAMI 0x300a300a
+#define IST30XXB_WHOAMI 0x300b300b
+#define IST3038_WHOAMI 0x30383038
+
#define IST3032C_WHOAMI 0x32c
+#define IST3038C_WHOAMI 0x38c
-#define IST3038B_REG_STATUS 0x20
#define IST3038B_REG_CHIPID 0x30
#define IST3038B_WHOAMI 0x30380b
@@ -25,7 +33,6 @@
#define IST3038C_REG_TOUCH_STATUS (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS)
#define IST3038C_REG_TOUCH_COORD (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x8)
#define IST3038C_REG_INTR_MESSAGE (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x4)
-#define IST3038C_WHOAMI 0x38c
#define IST3038C_CHIP_ON_DELAY_MS 60
#define IST3038C_I2C_RETRY_COUNT 3
#define IST3038C_MAX_FINGER_NUM 10
@@ -121,11 +128,11 @@ static irqreturn_t imagis_interrupt(int irq, void *dev_id)
for (i = 0; i < finger_count; i++) {
if (ts->tdata->protocol_b)
error = imagis_i2c_read_reg(ts,
- ts->tdata->touch_coord_cmd, &finger_status);
- else
- error = imagis_i2c_read_reg(ts,
ts->tdata->touch_coord_cmd + (i * 4),
&finger_status);
+ else
+ error = imagis_i2c_read_reg(ts,
+ ts->tdata->touch_coord_cmd, &finger_status);
if (error) {
dev_err(&ts->client->dev,
"failed to read coordinates for finger %d: %d\n",
@@ -394,14 +401,22 @@ static const struct imagis_properties imagis_3032c_data = {
.whoami_cmd = IST3038C_REG_CHIPID,
.whoami_val = IST3032C_WHOAMI,
.touch_keys_supported = true,
+ .protocol_b = true,
+};
+
+static const struct imagis_properties imagis_3038_data = {
+ .interrupt_msg_cmd = IST30XX_REG_STATUS,
+ .touch_coord_cmd = IST30XX_REG_STATUS,
+ .whoami_cmd = IST30XX_REG_CHIPID,
+ .whoami_val = IST3038_WHOAMI,
+ .touch_keys_supported = true,
};
static const struct imagis_properties imagis_3038b_data = {
- .interrupt_msg_cmd = IST3038B_REG_STATUS,
- .touch_coord_cmd = IST3038B_REG_STATUS,
+ .interrupt_msg_cmd = IST30XX_REG_STATUS,
+ .touch_coord_cmd = IST30XX_REG_STATUS,
.whoami_cmd = IST3038B_REG_CHIPID,
.whoami_val = IST3038B_WHOAMI,
- .protocol_b = true,
};
static const struct imagis_properties imagis_3038c_data = {
@@ -409,11 +424,13 @@ static const struct imagis_properties imagis_3038c_data = {
.touch_coord_cmd = IST3038C_REG_TOUCH_COORD,
.whoami_cmd = IST3038C_REG_CHIPID,
.whoami_val = IST3038C_WHOAMI,
+ .protocol_b = true,
};
#ifdef CONFIG_OF
static const struct of_device_id imagis_of_match[] = {
{ .compatible = "imagis,ist3032c", .data = &imagis_3032c_data },
+ { .compatible = "imagis,ist3038", .data = &imagis_3038_data },
{ .compatible = "imagis,ist3038b", .data = &imagis_3038b_data },
{ .compatible = "imagis,ist3038c", .data = &imagis_3038c_data },
{ },
diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c
index 1d7e4c3966ce..82f7ac62a4f2 100644
--- a/drivers/input/touchscreen/inexio.c
+++ b/drivers/input/touchscreen/inexio.c
@@ -114,7 +114,7 @@ static int inexio_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- pinexio = kzalloc(sizeof(struct inexio), GFP_KERNEL);
+ pinexio = kzalloc(sizeof(*pinexio), GFP_KERNEL);
input_dev = input_allocate_device();
if (!pinexio || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c
index 28e449eea318..eefae96a2d40 100644
--- a/drivers/input/touchscreen/mtouch.c
+++ b/drivers/input/touchscreen/mtouch.c
@@ -128,7 +128,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- mtouch = kzalloc(sizeof(struct mtouch), GFP_KERNEL);
+ mtouch = kzalloc(sizeof(*mtouch), GFP_KERNEL);
input_dev = input_allocate_device();
if (!mtouch || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 12abb3b36128..95adede26703 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -199,7 +199,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
int max_x, max_y;
int err;
- pm = kzalloc(sizeof(struct pm), GFP_KERNEL);
+ pm = kzalloc(sizeof(*pm), GFP_KERNEL);
input_dev = input_allocate_device();
if (!pm || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c
index 06fa3a19d266..0e5cc9fbad17 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -643,12 +643,12 @@ static int rohm_ts_load_firmware(struct i2c_client *client,
const char *firmware_name)
{
struct device *dev = &client->dev;
- const struct firmware *fw;
s32 status;
unsigned int offset, len, xfer_len;
unsigned int retry = 0;
int error, error2;
+ const struct firmware *fw __free(firmware) = NULL;
error = request_firmware(&fw, firmware_name, dev);
if (error) {
dev_err(dev, "unable to retrieve firmware %s: %d\n",
@@ -722,18 +722,39 @@ static int rohm_ts_load_firmware(struct i2c_client *client,
out:
error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL);
- release_firmware(fw);
-
return error ? error : error2;
}
+static int rohm_ts_update_setting(struct rohm_ts_data *ts,
+ unsigned int setting_bit, bool on)
+{
+ int error;
+
+ scoped_cond_guard(mutex_intr, return -EINTR, &ts->input->mutex) {
+ if (on)
+ ts->setup2 |= setting_bit;
+ else
+ ts->setup2 &= ~setting_bit;
+
+ if (ts->initialized) {
+ error = i2c_smbus_write_byte_data(ts->client,
+ COMMON_SETUP2,
+ ts->setup2);
+ if (error)
+ return error;
+ }
+ }
+
+ return 0;
+}
+
static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct rohm_ts_data *ts = i2c_get_clientdata(client);
- return sprintf(buf, "%d\n", !!(ts->setup2 & SWAP_XY));
+ return sysfs_emit(buf, "%d\n", !!(ts->setup2 & SWAP_XY));
}
static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr,
@@ -748,22 +769,8 @@ static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr,
if (error)
return error;
- error = mutex_lock_interruptible(&ts->input->mutex);
- if (error)
- return error;
-
- if (val)
- ts->setup2 |= SWAP_XY;
- else
- ts->setup2 &= ~SWAP_XY;
-
- if (ts->initialized)
- error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
- ts->setup2);
-
- mutex_unlock(&ts->input->mutex);
-
- return error ? error : count;
+ error = rohm_ts_update_setting(ts, SWAP_XY, val);
+ return error ?: count;
}
static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr,
@@ -772,7 +779,7 @@ static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr,
struct i2c_client *client = to_i2c_client(dev);
struct rohm_ts_data *ts = i2c_get_clientdata(client);
- return sprintf(buf, "%d\n", !!(ts->setup2 & INV_X));
+ return sysfs_emit(buf, "%d\n", !!(ts->setup2 & INV_X));
}
static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr,
@@ -787,22 +794,8 @@ static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr,
if (error)
return error;
- error = mutex_lock_interruptible(&ts->input->mutex);
- if (error)
- return error;
-
- if (val)
- ts->setup2 |= INV_X;
- else
- ts->setup2 &= ~INV_X;
-
- if (ts->initialized)
- error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
- ts->setup2);
-
- mutex_unlock(&ts->input->mutex);
-
- return error ? error : count;
+ error = rohm_ts_update_setting(ts, INV_X, val);
+ return error ?: count;
}
static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr,
@@ -811,7 +804,7 @@ static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr,
struct i2c_client *client = to_i2c_client(dev);
struct rohm_ts_data *ts = i2c_get_clientdata(client);
- return sprintf(buf, "%d\n", !!(ts->setup2 & INV_Y));
+ return sysfs_emit(buf, "%d\n", !!(ts->setup2 & INV_Y));
}
static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr,
@@ -826,22 +819,8 @@ static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr,
if (error)
return error;
- error = mutex_lock_interruptible(&ts->input->mutex);
- if (error)
- return error;
-
- if (val)
- ts->setup2 |= INV_Y;
- else
- ts->setup2 &= ~INV_Y;
-
- if (ts->initialized)
- error = i2c_smbus_write_byte_data(client, COMMON_SETUP2,
- ts->setup2);
-
- mutex_unlock(&ts->input->mutex);
-
- return error ? error : count;
+ error = rohm_ts_update_setting(ts, INV_Y, val);
+ return error ?: count;
}
static DEVICE_ATTR_RW(swap_xy);
@@ -861,7 +840,7 @@ static int rohm_ts_device_init(struct i2c_client *client, u8 setup2)
struct device *dev = &client->dev;
int error;
- disable_irq(client->irq);
+ guard(disable_irq)(&client->irq);
/*
* Wait 200usec for reset
@@ -1036,10 +1015,10 @@ static int rohm_ts_device_init(struct i2c_client *client, u8 setup2)
/* controller CPU power on */
error = i2c_smbus_write_byte_data(client, SYSTEM,
ANALOG_POWER_ON | CPU_POWER_ON);
+ if (error)
+ return error;
- enable_irq(client->irq);
-
- return error;
+ return 0;
}
static int rohm_ts_power_off(struct i2c_client *client)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 5f2cf8881e72..8365a2ac6fce 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -672,7 +672,7 @@ static int sur40_probe(struct usb_interface *interface,
return -ENODEV;
/* Allocate memory for our device state and initialize it. */
- sur40 = kzalloc(sizeof(struct sur40_state), GFP_KERNEL);
+ sur40 = kzalloc(sizeof(*sur40), GFP_KERNEL);
if (!sur40)
return -ENOMEM;
diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c
index fb49687da405..c2718350815c 100644
--- a/drivers/input/touchscreen/touchit213.c
+++ b/drivers/input/touchscreen/touchit213.c
@@ -139,7 +139,7 @@ static int touchit213_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- touchit213 = kzalloc(sizeof(struct touchit213), GFP_KERNEL);
+ touchit213 = kzalloc(sizeof(*touchit213), GFP_KERNEL);
input_dev = input_allocate_device();
if (!touchit213 || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c
index 3cd58a13e44f..30ba97bd00a1 100644
--- a/drivers/input/touchscreen/touchright.c
+++ b/drivers/input/touchscreen/touchright.c
@@ -102,7 +102,7 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- tr = kzalloc(sizeof(struct tr), GFP_KERNEL);
+ tr = kzalloc(sizeof(*tr), GFP_KERNEL);
input_dev = input_allocate_device();
if (!tr || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c
index bde3c6ee3c60..fbd72789ea80 100644
--- a/drivers/input/touchscreen/touchwin.c
+++ b/drivers/input/touchscreen/touchwin.c
@@ -109,7 +109,7 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- tw = kzalloc(sizeof(struct tw), GFP_KERNEL);
+ tw = kzalloc(sizeof(*tw), GFP_KERNEL);
input_dev = input_allocate_device();
if (!tw || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c
index 139577021413..9f485cf57a72 100644
--- a/drivers/input/touchscreen/tsc40.c
+++ b/drivers/input/touchscreen/tsc40.c
@@ -83,7 +83,7 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int error;
- ptsc = kzalloc(sizeof(struct tsc_ser), GFP_KERNEL);
+ ptsc = kzalloc(sizeof(*ptsc), GFP_KERNEL);
input_dev = input_allocate_device();
if (!ptsc || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 60354ebc7242..dd6b12c6dc58 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -505,12 +505,14 @@ free:
static int mtouch_alloc(struct usbtouch_usb *usbtouch)
{
+ struct mtouch_priv *priv;
int ret;
- usbtouch->priv = kmalloc(sizeof(struct mtouch_priv), GFP_KERNEL);
- if (!usbtouch->priv)
+ priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
return -ENOMEM;
+ usbtouch->priv = priv;
ret = sysfs_create_group(&usbtouch->interface->dev.kobj,
&mtouch_attr_group);
if (ret) {
@@ -924,12 +926,11 @@ static int nexio_alloc(struct usbtouch_usb *usbtouch)
struct nexio_priv *priv;
int ret = -ENOMEM;
- usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL);
- if (!usbtouch->priv)
+ priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
goto out_buf;
- priv = usbtouch->priv;
-
+ usbtouch->priv = priv;
priv->ack_buf = kmemdup(nexio_ack_pkt, sizeof(nexio_ack_pkt),
GFP_KERNEL);
if (!priv->ack_buf)
@@ -1661,7 +1662,7 @@ static int usbtouch_probe(struct usb_interface *intf,
if (!endpoint)
return -ENXIO;
- usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL);
+ usbtouch = kzalloc(sizeof(*usbtouch), GFP_KERNEL);
input_dev = input_allocate_device();
if (!usbtouch || !input_dev)
goto out_free;
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 928c5ee3ac36..ed2ca8a689d5 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -380,30 +380,28 @@ static int w8001_open(struct input_dev *dev)
struct w8001 *w8001 = input_get_drvdata(dev);
int err;
- err = mutex_lock_interruptible(&w8001->mutex);
- if (err)
- return err;
+ scoped_guard(mutex_intr, &w8001->mutex) {
+ if (w8001->open_count == 0) {
+ err = w8001_command(w8001, W8001_CMD_START, false);
+ if (err)
+ return err;
+ }
- if (w8001->open_count++ == 0) {
- err = w8001_command(w8001, W8001_CMD_START, false);
- if (err)
- w8001->open_count--;
+ w8001->open_count++;
+ return 0;
}
- mutex_unlock(&w8001->mutex);
- return err;
+ return -EINTR;
}
static void w8001_close(struct input_dev *dev)
{
struct w8001 *w8001 = input_get_drvdata(dev);
- mutex_lock(&w8001->mutex);
+ guard(mutex)(&w8001->mutex);
if (--w8001->open_count == 0)
w8001_command(w8001, W8001_CMD_STOP, false);
-
- mutex_unlock(&w8001->mutex);
}
static int w8001_detect(struct w8001 *w8001)
@@ -595,10 +593,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
struct w8001 *w8001;
struct input_dev *input_dev_pen;
struct input_dev *input_dev_touch;
- char basename[64];
+ char basename[64] = "Wacom Serial";
int err, err_pen, err_touch;
- w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL);
+ w8001 = kzalloc(sizeof(*w8001), GFP_KERNEL);
input_dev_pen = input_allocate_device();
input_dev_touch = input_allocate_device();
if (!w8001 || !input_dev_pen || !input_dev_touch) {
@@ -625,8 +623,6 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
/* For backwards-compatibility we compose the basename based on
* capabilities and then just append the tool type
*/
- strscpy(basename, "Wacom Serial", sizeof(basename));
-
err_pen = w8001_setup_pen(w8001, basename, sizeof(basename));
err_touch = w8001_setup_touch(w8001, basename, sizeof(basename));
if (err_pen && err_touch) {
@@ -635,8 +631,8 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
}
if (!err_pen) {
- strscpy(w8001->pen_name, basename, sizeof(w8001->pen_name));
- strlcat(w8001->pen_name, " Pen", sizeof(w8001->pen_name));
+ snprintf(w8001->pen_name, sizeof(w8001->pen_name),
+ "%s Pen", basename);
input_dev_pen->name = w8001->pen_name;
w8001_set_devdata(input_dev_pen, w8001, serio);
@@ -651,9 +647,8 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
}
if (!err_touch) {
- strscpy(w8001->touch_name, basename, sizeof(w8001->touch_name));
- strlcat(w8001->touch_name, " Finger",
- sizeof(w8001->touch_name));
+ snprintf(w8001->touch_name, sizeof(w8001->touch_name),
+ "%s Finger", basename);
input_dev_touch->name = w8001->touch_name;
w8001_set_devdata(input_dev_touch, w8001, serio);