Input: eeti_ts - use gpio_get_value_cansleep
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / drivers / input / touchscreen / eeti_ts.c
index 16023867b9da7bf2e2b348805c4d6b77a8f14699..fc61dbea4736ba8556d8e7c0f3de9f11eaac857c 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/gpio.h>
 #include <linux/input/eeti_ts.h>
 #include <linux/slab.h>
+#include <asm/unaligned.h>
 
 static bool flip_x;
 module_param(flip_x, bool, 0644);
@@ -43,42 +44,42 @@ static bool flip_y;
 module_param(flip_y, bool, 0644);
 MODULE_PARM_DESC(flip_y, "flip y coordinate");
 
-struct eeti_ts_priv {
+struct eeti_ts {
        struct i2c_client *client;
        struct input_dev *input;
        struct work_struct work;
        struct mutex mutex;
-       int irq_gpio, irq, irq_active_high;
+       int irq_gpio, irq_active_high;
 };
 
 #define EETI_TS_BITDEPTH       (11)
 #define EETI_MAXVAL            ((1 << (EETI_TS_BITDEPTH + 1)) - 1)
 
-#define REPORT_BIT_PRESSED     (1 << 0)
-#define REPORT_BIT_AD0         (1 << 1)
-#define REPORT_BIT_AD1         (1 << 2)
-#define REPORT_BIT_HAS_PRESSURE        (1 << 6)
+#define REPORT_BIT_PRESSED     BIT(0)
+#define REPORT_BIT_AD0         BIT(1)
+#define REPORT_BIT_AD1         BIT(2)
+#define REPORT_BIT_HAS_PRESSURE        BIT(6)
 #define REPORT_RES_BITS(v)     (((v) >> 1) + EETI_TS_BITDEPTH)
 
-static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv)
+static inline int eeti_ts_irq_active(struct eeti_ts *eeti)
 {
-       return gpio_get_value(priv->irq_gpio) == priv->irq_active_high;
+       return gpio_get_value_cansleep(eeti->irq_gpio) == eeti->irq_active_high;
 }
 
 static void eeti_ts_read(struct work_struct *work)
 {
        char buf[6];
        unsigned int x, y, res, pressed, to = 100;
-       struct eeti_ts_priv *priv =
-               container_of(work, struct eeti_ts_priv, work);
+       struct eeti_ts *eeti =
+               container_of(work, struct eeti_ts, work);
 
-       mutex_lock(&priv->mutex);
+       mutex_lock(&eeti->mutex);
 
-       while (eeti_ts_irq_active(priv) && --to)
-               i2c_master_recv(priv->client, buf, sizeof(buf));
+       while (eeti_ts_irq_active(eeti) && --to)
+               i2c_master_recv(eeti->client, buf, sizeof(buf));
 
        if (!to) {
-               dev_err(&priv->client->dev,
+               dev_err(&eeti->client->dev,
                        "unable to clear IRQ - line stuck?\n");
                goto out;
        }
@@ -89,8 +90,9 @@ static void eeti_ts_read(struct work_struct *work)
 
        pressed = buf[0] & REPORT_BIT_PRESSED;
        res = REPORT_RES_BITS(buf[0] & (REPORT_BIT_AD0 | REPORT_BIT_AD1));
-       x = buf[2] | (buf[1] << 8);
-       y = buf[4] | (buf[3] << 8);
+
+       x = get_unaligned_be16(&buf[1]);
+       y = get_unaligned_be16(&buf[3]);
 
        /* fix the range to 11 bits */
        x >>= res - EETI_TS_BITDEPTH;
@@ -103,65 +105,66 @@ static void eeti_ts_read(struct work_struct *work)
                y = EETI_MAXVAL - y;
 
        if (buf[0] & REPORT_BIT_HAS_PRESSURE)
-               input_report_abs(priv->input, ABS_PRESSURE, buf[5]);
+               input_report_abs(eeti->input, ABS_PRESSURE, buf[5]);
 
-       input_report_abs(priv->input, ABS_X, x);
-       input_report_abs(priv->input, ABS_Y, y);
-       input_report_key(priv->input, BTN_TOUCH, !!pressed);
-       input_sync(priv->input);
+       input_report_abs(eeti->input, ABS_X, x);
+       input_report_abs(eeti->input, ABS_Y, y);
+       input_report_key(eeti->input, BTN_TOUCH, !!pressed);
+       input_sync(eeti->input);
 
 out:
-       mutex_unlock(&priv->mutex);
+       mutex_unlock(&eeti->mutex);
 }
 
 static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
 {
-       struct eeti_ts_priv *priv = dev_id;
+       struct eeti_ts *eeti = dev_id;
 
         /* postpone I2C transactions as we are atomic */
-       schedule_work(&priv->work);
+       schedule_work(&eeti->work);
 
        return IRQ_HANDLED;
 }
 
-static void eeti_ts_start(struct eeti_ts_priv *priv)
+static void eeti_ts_start(struct eeti_ts *eeti)
 {
-       enable_irq(priv->irq);
+       enable_irq(eeti->client->irq);
 
        /* Read the events once to arm the IRQ */
-       eeti_ts_read(&priv->work);
+       eeti_ts_read(&eeti->work);
 }
 
-static void eeti_ts_stop(struct eeti_ts_priv *priv)
+static void eeti_ts_stop(struct eeti_ts *eeti)
 {
-       disable_irq(priv->irq);
-       cancel_work_sync(&priv->work);
+       disable_irq(eeti->client->irq);
+       cancel_work_sync(&eeti->work);
 }
 
 static int eeti_ts_open(struct input_dev *dev)
 {
-       struct eeti_ts_priv *priv = input_get_drvdata(dev);
+       struct eeti_ts *eeti = input_get_drvdata(dev);
 
-       eeti_ts_start(priv);
+       eeti_ts_start(eeti);
 
        return 0;
 }
 
 static void eeti_ts_close(struct input_dev *dev)
 {
-       struct eeti_ts_priv *priv = input_get_drvdata(dev);
+       struct eeti_ts *eeti = input_get_drvdata(dev);
 
-       eeti_ts_stop(priv);
+       eeti_ts_stop(eeti);
 }
 
 static int eeti_ts_probe(struct i2c_client *client,
-                                  const struct i2c_device_id *idp)
+                        const struct i2c_device_id *idp)
 {
-       struct eeti_ts_platform_data *pdata = dev_get_platdata(&client->dev);
-       struct eeti_ts_priv *priv;
+       struct device *dev = &client->dev;
+       struct eeti_ts_platform_data *pdata = dev_get_platdata(dev);
+       struct eeti_ts *eeti;
        struct input_dev *input;
        unsigned int irq_flags;
-       int err = -ENOMEM;
+       int error;
 
        /*
         * In contrast to what's described in the datasheet, there seems
@@ -170,21 +173,21 @@ static int eeti_ts_probe(struct i2c_client *client,
         * for interrupts to occur.
         */
 
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv) {
-               dev_err(&client->dev, "failed to allocate driver data\n");
+       eeti = devm_kzalloc(dev, sizeof(*eeti), GFP_KERNEL);
+       if (!eeti) {
+               dev_err(dev, "failed to allocate driver data\n");
                return -ENOMEM;
        }
 
-       mutex_init(&priv->mutex);
-       input = input_allocate_device();
+       mutex_init(&eeti->mutex);
+
+       input = devm_input_allocate_device(dev);
        if (!input) {
-               dev_err(&client->dev, "Failed to allocate input device.\n");
-               goto err1;
+               dev_err(dev, "Failed to allocate input device.\n");
+               return -ENOMEM;
        }
 
-       input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-       input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+       input_set_capability(input, EV_KEY, BTN_TOUCH);
 
        input_set_abs_params(input, ABS_X, 0, EETI_MAXVAL, 0, 0);
        input_set_abs_params(input, ABS_Y, 0, EETI_MAXVAL, 0, 0);
@@ -192,71 +195,44 @@ static int eeti_ts_probe(struct i2c_client *client,
 
        input->name = client->name;
        input->id.bustype = BUS_I2C;
-       input->dev.parent = &client->dev;
        input->open = eeti_ts_open;
        input->close = eeti_ts_close;
 
-       priv->client = client;
-       priv->input = input;
-       priv->irq_gpio = pdata->irq_gpio;
-       priv->irq = gpio_to_irq(pdata->irq_gpio);
+       eeti->client = client;
+       eeti->input = input;
+       eeti->irq_gpio = pdata->irq_gpio;
 
-       err = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name);
-       if (err < 0)
-               goto err1;
+       error = devm_gpio_request_one(dev, pdata->irq_gpio, GPIOF_IN,
+                                     client->name);
+       if (error)
+               return error;
 
-       priv->irq_active_high = pdata->irq_active_high;
+       eeti->irq_active_high = pdata->irq_active_high;
 
-       irq_flags = priv->irq_active_high ?
+       irq_flags = eeti->irq_active_high ?
                IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
 
-       INIT_WORK(&priv->work, eeti_ts_read);
-       i2c_set_clientdata(client, priv);
-       input_set_drvdata(input, priv);
+       INIT_WORK(&eeti->work, eeti_ts_read);
+       i2c_set_clientdata(client, eeti);
+       input_set_drvdata(input, eeti);
 
-       err = input_register_device(input);
-       if (err)
-               goto err2;
+       error = input_register_device(input);
+       if (error)
+               return error;
 
-       err = request_irq(priv->irq, eeti_ts_isr, irq_flags,
-                         client->name, priv);
-       if (err) {
-               dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
-               goto err3;
+       error = devm_request_irq(dev, client->irq, eeti_ts_isr, irq_flags,
+                                client->name, eeti);
+       if (error) {
+               dev_err(dev, "Unable to request touchscreen IRQ: %d\n",
+                       error);
+               return error;
        }
 
        /*
         * Disable the device for now. It will be enabled once the
         * input device is opened.
         */
-       eeti_ts_stop(priv);
-
-       return 0;
-
-err3:
-       input_unregister_device(input);
-       input = NULL; /* so we dont try to free it below */
-err2:
-       gpio_free(pdata->irq_gpio);
-err1:
-       input_free_device(input);
-       kfree(priv);
-       return err;
-}
-
-static int eeti_ts_remove(struct i2c_client *client)
-{
-       struct eeti_ts_priv *priv = i2c_get_clientdata(client);
-
-       free_irq(priv->irq, priv);
-       /*
-        * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it
-        * so that device still works if we reload the driver.
-        */
-       enable_irq(priv->irq);
-
-       input_unregister_device(priv->input);
-       kfree(priv);
+       eeti_ts_stop(eeti);
 
        return 0;
 }
@@ -264,18 +240,18 @@ static int eeti_ts_remove(struct i2c_client *client)
 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);
-       struct input_dev *input_dev = priv->input;
+       struct eeti_ts *eeti = i2c_get_clientdata(client);
+       struct input_dev *input_dev = eeti->input;
 
        mutex_lock(&input_dev->mutex);
 
        if (input_dev->users)
-               eeti_ts_stop(priv);
+               eeti_ts_stop(eeti);
 
        mutex_unlock(&input_dev->mutex);
 
        if (device_may_wakeup(&client->dev))
-               enable_irq_wake(priv->irq);
+               enable_irq_wake(client->irq);
 
        return 0;
 }
@@ -283,16 +259,16 @@ static int __maybe_unused eeti_ts_suspend(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);
-       struct input_dev *input_dev = priv->input;
+       struct eeti_ts *eeti = i2c_get_clientdata(client);
+       struct input_dev *input_dev = eeti->input;
 
        if (device_may_wakeup(&client->dev))
-               disable_irq_wake(priv->irq);
+               disable_irq_wake(client->irq);
 
        mutex_lock(&input_dev->mutex);
 
        if (input_dev->users)
-               eeti_ts_start(priv);
+               eeti_ts_start(eeti);
 
        mutex_unlock(&input_dev->mutex);
 
@@ -313,7 +289,6 @@ static struct i2c_driver eeti_ts_driver = {
                .pm = &eeti_ts_pm,
        },
        .probe = eeti_ts_probe,
-       .remove = eeti_ts_remove,
        .id_table = eeti_ts_id,
 };