diff options
Diffstat (limited to 'drivers/input/touchscreen/tsc2007_core.c')
| -rw-r--r-- | drivers/input/touchscreen/tsc2007_core.c | 126 |
1 files changed, 51 insertions, 75 deletions
diff --git a/drivers/input/touchscreen/tsc2007_core.c b/drivers/input/touchscreen/tsc2007_core.c index 8342e0c48a53..948935de894b 100644 --- a/drivers/input/touchscreen/tsc2007_core.c +++ b/drivers/input/touchscreen/tsc2007_core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * drivers/input/touchscreen/tsc2007.c * @@ -14,19 +15,17 @@ * Copyright (C) 2002 MontaVista Software * Copyright (C) 2004 Texas Instruments * Copyright (C) 2005 Dirk Behme - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/module.h> #include <linux/slab.h> +#include <linux/gpio/consumer.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/i2c.h> -#include <linux/of_device.h> -#include <linux/of_gpio.h> +#include <linux/math64.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #include <linux/platform_data/tsc2007.h> #include "tsc2007.h" @@ -70,7 +69,7 @@ static void tsc2007_read_values(struct tsc2007 *tsc, struct ts_event *tc) u32 tsc2007_calculate_resistance(struct tsc2007 *tsc, struct ts_event *tc) { - u32 rt = 0; + u64 rt = 0; /* range filtering */ if (tc->x == MAX_12BIT) @@ -81,11 +80,13 @@ u32 tsc2007_calculate_resistance(struct tsc2007 *tsc, struct ts_event *tc) rt = tc->z2 - tc->z1; rt *= tc->x; rt *= tsc->x_plate_ohms; - rt /= tc->z1; + rt = div_u64(rt, tc->z1); rt = (rt + 2047) >> 12; } - return rt; + if (rt > U32_MAX) + return U32_MAX; + return (u32) rt; } bool tsc2007_is_pen_down(struct tsc2007 *ts) @@ -144,8 +145,7 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle) rt = ts->max_rt - rt; input_report_key(input, BTN_TOUCH, 1); - input_report_abs(input, ABS_X, tc.x); - input_report_abs(input, ABS_Y, tc.y); + touchscreen_report_pos(input, &ts->prop, tc.x, tc.y, false); input_report_abs(input, ABS_PRESSURE, rt); input_sync(input); @@ -174,26 +174,14 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle) return IRQ_HANDLED; } -static irqreturn_t tsc2007_hard_irq(int irq, void *handle) -{ - struct tsc2007 *ts = handle; - - if (tsc2007_is_pen_down(ts)) - return IRQ_WAKE_THREAD; - - if (ts->clear_penirq) - ts->clear_penirq(); - - return IRQ_HANDLED; -} - static void tsc2007_stop(struct tsc2007 *ts) { ts->stopped = true; mb(); wake_up(&ts->wait); - disable_irq(ts->irq); + if (ts->irq) + disable_irq(ts->irq); } static int tsc2007_open(struct input_dev *input_dev) @@ -204,7 +192,8 @@ static int tsc2007_open(struct input_dev *input_dev) ts->stopped = false; mb(); - enable_irq(ts->irq); + if (ts->irq) + enable_irq(ts->irq); /* Prepare for touch readings - power down ADC and enable PENIRQ */ err = tsc2007_xfer(ts, PWRDOWN); @@ -223,71 +212,58 @@ static void tsc2007_close(struct input_dev *input_dev) tsc2007_stop(ts); } -#ifdef CONFIG_OF static int tsc2007_get_pendown_state_gpio(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct tsc2007 *ts = i2c_get_clientdata(client); - return !gpio_get_value(ts->gpio); + return gpiod_get_value_cansleep(ts->gpiod); } -static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts) +static int tsc2007_probe_properties(struct device *dev, struct tsc2007 *ts) { - struct device_node *np = client->dev.of_node; u32 val32; u64 val64; - if (!np) { - dev_err(&client->dev, "missing device tree data\n"); - return -EINVAL; - } - - if (!of_property_read_u32(np, "ti,max-rt", &val32)) + if (!device_property_read_u32(dev, "ti,max-rt", &val32)) ts->max_rt = val32; else ts->max_rt = MAX_12BIT; - if (!of_property_read_u32(np, "ti,fuzzx", &val32)) + if (!device_property_read_u32(dev, "ti,fuzzx", &val32)) ts->fuzzx = val32; - if (!of_property_read_u32(np, "ti,fuzzy", &val32)) + if (!device_property_read_u32(dev, "ti,fuzzy", &val32)) ts->fuzzy = val32; - if (!of_property_read_u32(np, "ti,fuzzz", &val32)) + if (!device_property_read_u32(dev, "ti,fuzzz", &val32)) ts->fuzzz = val32; - if (!of_property_read_u64(np, "ti,poll-period", &val64)) + if (!device_property_read_u64(dev, "ti,poll-period", &val64)) ts->poll_period = msecs_to_jiffies(val64); else ts->poll_period = msecs_to_jiffies(1); - if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) { + if (!device_property_read_u32(dev, "ti,x-plate-ohms", &val32)) { ts->x_plate_ohms = val32; } else { - dev_err(&client->dev, "missing ti,x-plate-ohms devicetree property."); + dev_err(dev, "Missing ti,x-plate-ohms device property\n"); return -EINVAL; } - ts->gpio = of_get_gpio(np, 0); - if (gpio_is_valid(ts->gpio)) + ts->gpiod = devm_gpiod_get_optional(dev, NULL, GPIOD_IN); + if (IS_ERR(ts->gpiod)) + return PTR_ERR(ts->gpiod); + + if (ts->gpiod) ts->get_pendown_state = tsc2007_get_pendown_state_gpio; else - dev_warn(&client->dev, - "GPIO not specified in DT (of_get_gpio returned %d)\n", - ts->gpio); + dev_dbg(dev, "Pen down GPIO is not specified in properties\n"); return 0; } -#else -static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts) -{ - dev_err(&client->dev, "platform data is required!\n"); - return -EINVAL; -} -#endif -static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts, +static int tsc2007_probe_pdev(struct device *dev, struct tsc2007 *ts, const struct tsc2007_platform_data *pdata, const struct i2c_device_id *id) { @@ -302,7 +278,7 @@ static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts, ts->fuzzz = pdata->fuzzz; if (pdata->x_plate_ohms == 0) { - dev_err(&client->dev, "x_plate_ohms is not set up in platform data"); + dev_err(dev, "x_plate_ohms is not set up in platform data\n"); return -EINVAL; } @@ -317,9 +293,9 @@ static void tsc2007_call_exit_platform_hw(void *data) pdata->exit_platform_hw(); } -static int tsc2007_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tsc2007_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev); struct tsc2007 *ts; @@ -335,9 +311,9 @@ static int tsc2007_probe(struct i2c_client *client, return -ENOMEM; if (pdata) - err = tsc2007_probe_pdev(client, ts, pdata, id); + err = tsc2007_probe_pdev(&client->dev, ts, pdata, id); else - err = tsc2007_probe_dt(client, ts); + err = tsc2007_probe_properties(&client->dev, ts); if (err) return err; @@ -367,9 +343,9 @@ static int tsc2007_probe(struct i2c_client *client, input_set_drvdata(input_dev, ts); input_set_capability(input_dev, EV_KEY, BTN_TOUCH); - input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0); input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0); + touchscreen_parse_properties(input_dev, false, &ts->prop); input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, ts->fuzzz, 0); @@ -390,17 +366,19 @@ static int tsc2007_probe(struct i2c_client *client, pdata->init_platform_hw(); } - err = devm_request_threaded_irq(&client->dev, ts->irq, - tsc2007_hard_irq, tsc2007_soft_irq, - IRQF_ONESHOT, - client->dev.driver->name, ts); - if (err) { - dev_err(&client->dev, "Failed to request irq %d: %d\n", - ts->irq, err); - return err; - } + if (ts->irq) { + err = devm_request_threaded_irq(&client->dev, ts->irq, + NULL, tsc2007_soft_irq, + IRQF_ONESHOT, + client->dev.driver->name, ts); + if (err) { + dev_err(&client->dev, "Failed to request irq %d: %d\n", + ts->irq, err); + return err; + } - tsc2007_stop(ts); + tsc2007_stop(ts); + } /* power down the chip (TSC2007_SETUP does not ACK on I2C) */ err = tsc2007_xfer(ts, PWRDOWN); @@ -428,24 +406,22 @@ static int tsc2007_probe(struct i2c_client *client, } static const struct i2c_device_id tsc2007_idtable[] = { - { "tsc2007", 0 }, + { "tsc2007" }, { } }; MODULE_DEVICE_TABLE(i2c, tsc2007_idtable); -#ifdef CONFIG_OF static const struct of_device_id tsc2007_of_match[] = { { .compatible = "ti,tsc2007" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, tsc2007_of_match); -#endif static struct i2c_driver tsc2007_driver = { .driver = { .name = "tsc2007", - .of_match_table = of_match_ptr(tsc2007_of_match), + .of_match_table = tsc2007_of_match, }, .id_table = tsc2007_idtable, .probe = tsc2007_probe, |
