OSDN Git Service

goodix_ta: clean up everything
authorDemon Singur <demonsingur@gmail.com>
Thu, 22 Mar 2018 20:22:47 +0000 (20:22 +0000)
committerArian <arian.kulmer@web.de>
Tue, 19 Nov 2019 15:24:31 +0000 (16:24 +0100)
 * get rid of spi bus support, we only need platform bus
 * move fingerprint detection wakelock time to a define
 * do not dynamically allocate minors, there's only one
   minor needed, 0
 * move wakelock declaration to gf_dev
 * merge enable/disable irq methods
 * remove spi clk control
 * remove nav event support
 * remove unused input events
 * remove unused ioctls
 * remove ioctl type checking, copy_from/to_user already
   handles this
 * remove fasync support
 * move netlink message sending out of notifier, inside
   dedicated worker
 * register platform_driver directly
 * move event handling to a high priority worker
 * do not use conflicting names for struct and instance of it

Change-Id: Iac4951f65d533befe1362a718ce4ce8773d7973c

drivers/input/fingerprint/goodix_ta/Makefile
drivers/input/fingerprint/goodix_ta/gf_spi.c
drivers/input/fingerprint/goodix_ta/gf_spi.h
drivers/input/fingerprint/goodix_ta/netlink.c
drivers/input/fingerprint/goodix_ta/platform.c [deleted file]

index 43929c1..c12f579 100644 (file)
@@ -1 +1 @@
-obj-$(CONFIG_FINGERPRINT_GOODIX_TA) += gf_spi.o platform.o netlink.o
+obj-$(CONFIG_FINGERPRINT_GOODIX_TA) += gf_spi.o netlink.o
index a6938e0..21ef982 100644 (file)
@@ -13,7 +13,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#define pr_fmt(fmt)            KBUILD_MODNAME ": " fmt
 
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/device.h>
 #include <linux/input.h>
-#include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/list.h>
-#include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/compat.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
-#include <linux/ktime.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/regulator/consumer.h>
 #include <linux/of_gpio.h>
-#include <linux/timer.h>
-#include <linux/notifier.h>
 #include <linux/fb.h>
-#include <linux/pm_qos.h>
-#include <linux/cpufreq.h>
-#include <linux/wakelock.h>
 
 #include "gf_spi.h"
 
-#if defined(USE_SPI_BUS)
-#include <linux/spi/spi.h>
-#include <linux/spi/spidev.h>
-#elif defined(USE_PLATFORM_BUS)
 #include <linux/platform_device.h>
-#endif
-
-#define VER_MAJOR   1
-#define VER_MINOR   2
-#define PATCH_LEVEL 1
-
-#define GF_SPIDEV_NAME     "goodix,fingerprint"
-/*device name after register in charater*/
-#define GF_DEV_NAME            "goodix_fp"
-#define        GF_INPUT_NAME       "uinput-goodix"     /*"goodix_fp" */
-
-#define        CHRD_DRIVER_NAME        "goodix_fp_spi"
-#define        CLASS_NAME                  "goodix_fp"
-
-#define N_SPI_MINORS           32      /* ... up to 256 */
-static int SPIDEV_MAJOR;
-
-static DECLARE_BITMAP(minors, N_SPI_MINORS);
-static LIST_HEAD(device_list);
-static DEFINE_MUTEX(device_list_lock);
-static struct wake_lock fp_wakelock;
-static struct gf_dev gf;
-
-struct gf_key_map maps[] = {
-       { EV_KEY, GF_KEY_INPUT_HOME },
-       { EV_KEY, GF_KEY_INPUT_MENU },
-       { EV_KEY, GF_KEY_INPUT_BACK },
-       { EV_KEY, GF_KEY_INPUT_POWER },
-#if defined(SUPPORT_NAV_EVENT)
-       { EV_KEY, GF_NAV_INPUT_UP },
-       { EV_KEY, GF_NAV_INPUT_DOWN },
-       { EV_KEY, GF_NAV_INPUT_RIGHT },
-       { EV_KEY, GF_NAV_INPUT_LEFT },
-       { EV_KEY, GF_KEY_INPUT_CAMERA },
-       { EV_KEY, GF_NAV_INPUT_CLICK },
-       { EV_KEY, GF_NAV_INPUT_DOUBLE_CLICK },
-       { EV_KEY, GF_NAV_INPUT_LONG_PRESS },
-       { EV_KEY, GF_NAV_INPUT_HEAVY },
-       { EV_KEY, KEY_KPENTER },
-#endif
-};
 
-static void gf_enable_irq(struct gf_dev *gf_dev)
-{
-       if (gf_dev->irq_enabled) {
-               pr_warn("IRQ has been enabled.\n");
-       } else {
-               enable_irq(gf_dev->irq);
-               gf_dev->irq_enabled = 1;
-       }
-}
+#define GF_DEV_NAME            "goodix_fp"
+#define GF_IRQ_NAME            "goodix_fp-irq"
+#define GF_DRIVER_NAME         "goodix_fp_spi"
+#define GF_INPUT_NAME          "uinput-goodix"
+#define GF_SPIDEV_NAME         "goodix,fingerprint"
 
-static void gf_disable_irq(struct gf_dev *gf_dev)
-{
-       if (gf_dev->irq_enabled) {
-               gf_dev->irq_enabled = 0;
-               disable_irq(gf_dev->irq);
-       } else {
-               pr_warn("IRQ has been disabled.\n");
-       }
-}
+static struct gf_device gf;
 
-#ifdef AP_CONTROL_CLK
-static long spi_clk_max_rate(struct clk *clk, unsigned long rate)
+static void gf_hw_reset(struct gf_device *gf_dev, unsigned int delay_ms)
 {
-       long lowest_available, nearest_low, step_size, cur;
-       long step_direction = -1;
-       long guess = rate;
-       int max_steps = 10;
-
-       cur = clk_round_rate(clk, rate);
-       if (cur == rate)
-               return rate;
-
-       /* if we got here then: cur > rate */
-       lowest_available = clk_round_rate(clk, 0);
-       if (lowest_available > rate)
-               return -EINVAL;
-
-       step_size = (rate - lowest_available) >> 1;
-       nearest_low = lowest_available;
-
-       while (max_steps-- && step_size) {
-               guess += step_size * step_direction;
-               cur = clk_round_rate(clk, guess);
-
-               if ((cur < rate) && (cur > nearest_low))
-                       nearest_low = cur;
-               /*
-                * if we stepped too far, then start stepping in the other
-                * direction with half the step size
-                */
-               if (((cur > rate) && (step_direction > 0))
-                               || ((cur < rate) && (step_direction < 0))) {
-                       step_direction = -step_direction;
-                       step_size >>= 1;
-               }
-       }
-       return nearest_low;
+       gpio_set_value(gf_dev->reset_gpio, 0);
+       msleep(delay_ms);
+       gpio_set_value(gf_dev->reset_gpio, 1);
+       msleep(delay_ms);
 }
 
-static void spi_clock_set(struct gf_dev *gf_dev, int speed)
-{
-       long rate;
-       int rc;
-
-       rate = spi_clk_max_rate(gf_dev->core_clk, speed);
-       if (rate < 0) {
-               pr_debug("%s: no match found for requested clock frequency:%d",
-                               __func__, speed);
+static void gf_irq_config(struct gf_device *gf_dev, bool state) {
+       if (gf_dev->irq_enabled == state)
                return;
-       }
-
-       rc = clk_set_rate(gf_dev->core_clk, rate);
-}
-
-static int gfspi_ioctl_clk_init(struct gf_dev *data)
-{
-       pr_debug("%s: enter\n", __func__);
-
-       data->clk_enabled = 0;
-       data->core_clk = clk_get(&data->spi->dev, "core_clk");
-       if (IS_ERR_OR_NULL(data->core_clk)) {
-               pr_err("%s: fail to get core_clk\n", __func__);
-               return -EPERM;
-       }
-       data->iface_clk = clk_get(&data->spi->dev, "iface_clk");
-       if (IS_ERR_OR_NULL(data->iface_clk)) {
-               pr_err("%s: fail to get iface_clk\n", __func__);
-               clk_put(data->core_clk);
-               data->core_clk = NULL;
-               return -ENOENT;
-       }
-       return 0;
-}
-
-static int gfspi_ioctl_clk_enable(struct gf_dev *data)
-{
-       int err;
 
-       pr_debug("%s: enter\n", __func__);
-
-       if (data->clk_enabled)
-               return 0;
-
-       err = clk_prepare_enable(data->core_clk);
-       if (err) {
-               pr_err("%s: fail to enable core_clk\n", __func__);
-               return -EPERM;
-       }
-
-       err = clk_prepare_enable(data->iface_clk);
-       if (err) {
-               pr_err("%s: fail to enable iface_clk\n", __func__);
-               clk_disable_unprepare(data->core_clk);
-               return -ENOENT;
-       }
-
-       data->clk_enabled = 1;
-
-       return 0;
-}
-
-static int gfspi_ioctl_clk_disable(struct gf_dev *data)
-{
-       pr_debug("%s: enter\n", __func__);
-
-       if (!data->clk_enabled)
-               return 0;
-
-       clk_disable_unprepare(data->core_clk);
-       clk_disable_unprepare(data->iface_clk);
-       data->clk_enabled = 0;
-
-       return 0;
-}
-
-static int gfspi_ioctl_clk_uninit(struct gf_dev *data)
-{
-       pr_debug("%s: enter\n", __func__);
-
-       if (data->clk_enabled)
-               gfspi_ioctl_clk_disable(data);
-
-       if (!IS_ERR_OR_NULL(data->core_clk)) {
-               clk_put(data->core_clk);
-               data->core_clk = NULL;
-       }
-
-       if (!IS_ERR_OR_NULL(data->iface_clk)) {
-               clk_put(data->iface_clk);
-               data->iface_clk = NULL;
-       }
-
-       return 0;
-}
-#endif
-
-static void nav_event_input(struct gf_dev *gf_dev, gf_nav_event_t nav_event)
-{
-       uint32_t nav_input = 0;
-
-       switch (nav_event) {
-       case GF_NAV_FINGER_DOWN:
-               pr_debug("%s nav finger down\n", __func__);
-               break;
-
-       case GF_NAV_FINGER_UP:
-               pr_debug("%s nav finger up\n", __func__);
-               break;
-
-       case GF_NAV_DOWN:
-               nav_input = GF_NAV_INPUT_DOWN;
-               pr_debug("%s nav down\n", __func__);
-               break;
-
-       case GF_NAV_UP:
-               nav_input = GF_NAV_INPUT_UP;
-               pr_debug("%s nav up\n", __func__);
-               break;
-
-       case GF_NAV_LEFT:
-               nav_input = GF_NAV_INPUT_LEFT;
-               pr_debug("%s nav left\n", __func__);
-               break;
-
-       case GF_NAV_RIGHT:
-               nav_input = GF_NAV_INPUT_RIGHT;
-               pr_debug("%s nav right\n", __func__);
-               break;
-
-       case GF_NAV_CLICK:
-               nav_input = GF_NAV_INPUT_CLICK;
-               pr_debug("%s nav click\n", __func__);
-               break;
-
-       case GF_NAV_HEAVY:
-               nav_input = GF_NAV_INPUT_HEAVY;
-               pr_debug("%s nav heavy\n", __func__);
-               break;
-
-       case GF_NAV_LONG_PRESS:
-               nav_input = GF_NAV_INPUT_LONG_PRESS;
-               pr_debug("%s nav long press\n", __func__);
-               break;
-
-       case GF_NAV_DOUBLE_CLICK:
-               nav_input = GF_NAV_INPUT_DOUBLE_CLICK;
-               pr_debug("%s nav double click\n", __func__);
-               break;
-
-       default:
-               pr_warn("%s unknown nav event: %d\n", __func__, nav_event);
-               break;
-       }
+       if (state)
+               enable_irq(gf_dev->irq);
+       else
+               disable_irq(gf_dev->irq);
 
-       if ((nav_event != GF_NAV_FINGER_DOWN) && (nav_event != GF_NAV_FINGER_UP)) {
-               input_report_key(gf_dev->input, nav_input, 1);
-               input_sync(gf_dev->input);
-               input_report_key(gf_dev->input, nav_input, 0);
-               input_sync(gf_dev->input);
-       }
+       gf_dev->irq_enabled = state;
 }
 
-
-static void gf_kernel_key_input(struct gf_dev *gf_dev, struct gf_key *gf_key)
+static void gf_kernel_key_input(struct gf_device *gf_dev, struct gf_key *gf_key)
 {
-       uint32_t key_input = 0;
-
-       if (GF_KEY_HOME == gf_key->key) {
-               key_input = GF_KEY_INPUT_HOME;
-       } else if (GF_KEY_POWER == gf_key->key) {
-               key_input = KEY_KPENTER;
-       } else if (GF_KEY_CAMERA == gf_key->key) {
-               key_input = GF_KEY_INPUT_CAMERA;
-       } else {
-               /* add special key define */
-               key_input = gf_key->key;
-       }
-       pr_debug("%s: received key event[%d], key=%d, value=%d\n",
-                       __func__, key_input, gf_key->key, gf_key->value);
-
-       if ((GF_KEY_POWER == gf_key->key || GF_KEY_CAMERA == gf_key->key)
-                       && (gf_key->value == 1)) {
-               input_report_key(gf_dev->input, key_input, 1);
-               input_sync(gf_dev->input);
-               input_report_key(gf_dev->input, key_input, 0);
-               input_sync(gf_dev->input);
-       }
+       pr_debug("%s: received key, key=%d, value=%d\n",
+                       __func__, gf_key->key, gf_key->value);
 
-       if (GF_KEY_HOME == gf_key->key) {
-               input_report_key(gf_dev->input, key_input, gf_key->value);
+       switch (gf_key->key) {
+       case GF_KEY_HOME:
+               input_report_key(gf_dev->input, GF_KEY_INPUT_HOME, gf_key->value);
                input_sync(gf_dev->input);
+               break;
        }
 }
 
 static long gf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
-       struct gf_dev *gf_dev = &gf;
+       struct gf_device *gf_dev = &gf;
        struct gf_key gf_key;
-#if defined(SUPPORT_NAV_EVENT)
-       gf_nav_event_t nav_event = GF_NAV_NONE;
-#endif
-       int retval = 0;
+       int rc = 0;
        u8 netlink_route = NETLINK_TEST;
-       struct gf_ioc_chip_info info;
-
-       if (_IOC_TYPE(cmd) != GF_IOC_MAGIC)
-               return -ENODEV;
-
-       if (_IOC_DIR(cmd) & _IOC_READ)
-               retval = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
-       else if (_IOC_DIR(cmd) & _IOC_WRITE)
-               retval = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
-       if (retval)
-               return -EFAULT;
-
-       if (gf_dev->device_available == 0) {
-               if ((cmd == GF_IOC_ENABLE_POWER) || (cmd == GF_IOC_DISABLE_POWER)) {
-                       pr_debug("power cmd\n");
-               } else {
-                       pr_debug("Sensor is power off currently.\n");
-                       return -ENODEV;
-               }
-       }
 
        switch (cmd) {
        case GF_IOC_INIT:
-               pr_debug("%s GF_IOC_INIT\n", __func__);
+               pr_debug("%s: GF_IOC_INIT\n", __func__);
                if (copy_to_user((void __user *)arg, (void *)&netlink_route, sizeof(u8))) {
-                       retval = -EFAULT;
+                       rc = -EFAULT;
                        break;
                }
                break;
-       case GF_IOC_EXIT:
-               pr_debug("%s GF_IOC_EXIT\n", __func__);
-               break;
-       case GF_IOC_DISABLE_IRQ:
-               pr_debug("%s GF_IOC_DISABEL_IRQ\n", __func__);
-               gf_disable_irq(gf_dev);
-               break;
-       case GF_IOC_ENABLE_IRQ:
-               pr_debug("%s GF_IOC_ENABLE_IRQ\n", __func__);
-               gf_enable_irq(gf_dev);
-               break;
        case GF_IOC_RESET:
-               pr_debug("%s GF_IOC_RESET.\n", __func__);
+               pr_debug("%s: GF_IOC_RESET.\n", __func__);
                gf_hw_reset(gf_dev, 3);
                break;
        case GF_IOC_INPUT_KEY_EVENT:
                if (copy_from_user(&gf_key, (struct gf_key *)arg, sizeof(struct gf_key))) {
-                       pr_debug("Failed to copy input key event from user to kernel\n");
-                       retval = -EFAULT;
+                       pr_err("%s: failed to copy input key event\n", __func__);
+                       rc = -EFAULT;
                        break;
                }
 
                gf_kernel_key_input(gf_dev, &gf_key);
                break;
-#if defined(SUPPORT_NAV_EVENT)
-       case GF_IOC_NAV_EVENT:
-               pr_debug("%s GF_IOC_NAV_EVENT\n", __func__);
-               if (copy_from_user(&nav_event, (gf_nav_event_t *)arg, sizeof(gf_nav_event_t))) {
-                       pr_debug("Failed to copy nav event from user to kernel\n");
-                       retval = -EFAULT;
-                       break;
-               }
-
-               nav_event_input(gf_dev, nav_event);
-               break;
-#endif
-
-       case GF_IOC_ENABLE_SPI_CLK:
-               pr_debug("%s GF_IOC_ENABLE_SPI_CLK\n", __func__);
-#ifdef AP_CONTROL_CLK
-               gfspi_ioctl_clk_enable(gf_dev);
-#else
-               pr_debug("Doesn't support control clock.\n");
-#endif
-               break;
-       case GF_IOC_DISABLE_SPI_CLK:
-               pr_debug("%s GF_IOC_DISABLE_SPI_CLK\n", __func__);
-#ifdef AP_CONTROL_CLK
-               gfspi_ioctl_clk_disable(gf_dev);
-#else
-               pr_debug("Doesn't support control clock\n");
-#endif
-               break;
-       case GF_IOC_ENABLE_POWER:
-               pr_debug("%s GF_IOC_ENABLE_POWER\n", __func__);
-               if (gf_dev->device_available == 1)
-                       pr_debug("Sensor has already powered-on.\n");
-               else
-                       gf_power_on(gf_dev);
-               gf_dev->device_available = 1;
-               break;
-       case GF_IOC_DISABLE_POWER:
-               pr_debug("%s GF_IOC_DISABLE_POWER\n", __func__);
-               if (gf_dev->device_available == 0)
-                       pr_debug("Sensor has already powered-off.\n");
-               else
-                       gf_power_off(gf_dev);
-               gf_dev->device_available = 0;
-               break;
-       case GF_IOC_ENTER_SLEEP_MODE:
-               pr_debug("%s GF_IOC_ENTER_SLEEP_MODE\n", __func__);
-               break;
-       case GF_IOC_GET_FW_INFO:
-               pr_debug("%s GF_IOC_GET_FW_INFO\n", __func__);
-               break;
-       case GF_IOC_REMOVE:
-               pr_debug("%s GF_IOC_REMOVE\n", __func__);
-               break;
-       case GF_IOC_CHIP_INFO:
-               pr_debug("%s GF_IOC_CHIP_INFO\n", __func__);
-               if (copy_from_user(&info, (struct gf_ioc_chip_info *)arg, sizeof(struct gf_ioc_chip_info))) {
-                       retval = -EFAULT;
-                       break;
-               }
-               pr_debug("vendor_id : 0x%x\n", info.vendor_id);
-               pr_debug("mode : 0x%x\n", info.mode);
-               pr_debug("operation: 0x%x\n", info.operation);
-               break;
        default:
-               pr_warn("unsupport cmd:0x%x\n", cmd);
-               break;
+               pr_debug("%s: unsupport cmd:0x%x\n", __func__, cmd);
        }
 
-       return retval;
+       return rc;
 }
 
 #ifdef CONFIG_COMPAT
@@ -489,119 +122,83 @@ static long gf_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long a
 
 static irqreturn_t gf_irq(int irq, void *handle)
 {
-#if defined(GF_NETLINK_ENABLE)
-       char temp[4] = { 0x0 };
-       temp[0] = GF_NET_EVENT_IRQ;
-       wake_lock_timeout(&fp_wakelock, msecs_to_jiffies(2*1000));
-       sendnlmsg(temp);
-#elif defined (GF_FASYNC)
-       struct gf_dev *gf_dev = &gf;
+       struct gf_device *gf_dev = handle;
 
-       if (gf_dev->async)
-               kill_fasync(&gf_dev->async, SIGIO, POLL_IN);
-#endif
+       gf_dev->event = GF_NET_EVENT_IRQ;
+       queue_work(gf_dev->event_workqueue, &gf_dev->event_work);
 
        return IRQ_HANDLED;
 }
 
 static int gf_open(struct inode *inode, struct file *filp)
 {
-       struct gf_dev *gf_dev;
-       int status = -ENXIO;
-       int rc = 0;
+       struct gf_device *gf_dev = &gf;
+       int rc;
 
-       mutex_lock(&device_list_lock);
+       /*
+        * If this is not the first user, skip hardware configuration.
+        */
+       if (++gf_dev->users != 1)
+               goto no_config;
 
-       list_for_each_entry(gf_dev, &device_list, device_entry) {
-               if (gf_dev->devt == inode->i_rdev) {
-                       pr_debug("Found\n");
-                       status = 0;
-                       break;
-               }
+       rc = gpio_request(gf_dev->reset_gpio, "goodix_reset");
+       if (rc) {
+               pr_err("%s: failed to request reset_gpio, rc = %d\n", __func__, rc);
+               goto error_reset_gpio;
        }
+       gpio_direction_output(gf_dev->reset_gpio, 1);
 
-       if (status == 0) {
-               if (status == 0) {
-                       rc = gpio_request(gf_dev->reset_gpio, "goodix_reset");
-                       if (rc) {
-                               dev_err(&gf_dev->spi->dev, "Failed to request RESET GPIO. rc = %d\n", rc);
-                               mutex_unlock(&device_list_lock);
-                               return -EPERM;
-                       }
-
-                       gpio_direction_output(gf_dev->reset_gpio, 1);
-
-                       rc = gpio_request(gf_dev->irq_gpio, "goodix_irq");
-                       if (rc) {
-                               dev_err(&gf_dev->spi->dev, "Failed to request IRQ GPIO. rc = %d\n", rc);
-                               mutex_unlock(&device_list_lock);
-                               return -EPERM;
-                       }
-                       gpio_direction_input(gf_dev->irq_gpio);
-
-                       rc = request_threaded_irq(gf_dev->irq, NULL, gf_irq,
-                                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-                                       "gf", gf_dev);
-
-                       if (!rc) {
-                               enable_irq_wake(gf_dev->irq);
-                               gf_dev->irq_enabled = 1;
-                               gf_disable_irq(gf_dev);
-                       }
-
-                       gf_dev->users++;
-                       filp->private_data = gf_dev;
-                       nonseekable_open(inode, filp);
-                       pr_debug("Succeed to open device. irq = %d\n",
-                                       gf_dev->irq);
-                       if (gf_dev->users == 1)
-                               gf_enable_irq(gf_dev);
-                       gf_hw_reset(gf_dev, 3);
-                       gf_dev->device_available = 1;
-               }
-       } else {
-               pr_debug("No device for minor %d\n", iminor(inode));
+       rc = gpio_request(gf_dev->irq_gpio, "goodix_irq");
+       if (rc) {
+               pr_err("%s: failed to request irq_gpio, rc = %d\n", __func__, rc);
+               goto error_irq_gpio;
        }
-       mutex_unlock(&device_list_lock);
-       return status;
-}
+       gpio_direction_input(gf_dev->irq_gpio);
 
-#ifdef GF_FASYNC
-static int gf_fasync(int fd, struct file *filp, int mode)
-{
-       struct gf_dev *gf_dev = filp->private_data;
-       int ret;
+       /*
+        * Requesting an irq also enables it.
+        */
+       gf_dev->irq_enabled = true;
+       rc = request_threaded_irq(gf_dev->irq, NULL, gf_irq,
+                       IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+                       GF_IRQ_NAME, gf_dev);
+       if (rc) {
+               pr_err("%s: failed to request threaded irq, rc = %d\n", __func__, rc);
+               goto error_irq_req;
+       }
+
+       gf_hw_reset(gf_dev, 3);
+
+no_config:
+       filp->private_data = gf_dev;
+       nonseekable_open(inode, filp);
+
+       return 0;
 
-       ret = fasync_helper(fd, filp, mode, &gf_dev->async);
-       pr_debug("ret = %d\n", ret);
-       return ret;
+error_irq_req:
+       gpio_free(gf_dev->irq_gpio);
+error_irq_gpio:
+       gpio_free(gf_dev->reset_gpio);
+error_reset_gpio:
+       return rc;
 }
-#endif
 
 static int gf_release(struct inode *inode, struct file *filp)
 {
-       struct gf_dev *gf_dev;
-       int status = 0;
+       struct gf_device *gf_dev = filp->private_data;
 
-       mutex_lock(&device_list_lock);
-       gf_dev = filp->private_data;
+       if (--gf_dev->users != 0)
+               goto no_config;
+
+       gf_irq_config(gf_dev, false);
+       free_irq(gf_dev->irq, gf_dev);
+       gpio_free(gf_dev->irq_gpio);
+       gpio_free(gf_dev->reset_gpio);
+
+no_config:
        filp->private_data = NULL;
 
-       /*last close?? */
-       gf_dev->users--;
-       if (!gf_dev->users) {
-
-               pr_debug("disble_irq. irq = %d\n", gf_dev->irq);
-               gf_disable_irq(gf_dev);
-               /*power off the sensor*/
-               gf_dev->device_available = 0;
-               free_irq(gf_dev->irq, gf_dev);
-               gpio_free(gf_dev->irq_gpio);
-               gpio_free(gf_dev->reset_gpio);
-               gf_power_off(gf_dev);
-       }
-       mutex_unlock(&device_list_lock);
-       return status;
+       return 0;
 }
 
 static const struct file_operations gf_fops = {
@@ -616,291 +213,208 @@ static const struct file_operations gf_fops = {
 #endif /*CONFIG_COMPAT*/
        .open = gf_open,
        .release = gf_release,
-#ifdef GF_FASYNC
-       .fasync = gf_fasync,
-#endif
 };
 
-static int goodix_fb_state_chg_callback(struct notifier_block *nb,
-               unsigned long val, void *data)
+#define FINGERPRINT_PROCESSING_MS              2000
+static void gf_event_worker(struct work_struct *work)
+{
+       struct gf_device *gf_dev = container_of(work, typeof(*gf_dev), event_work);
+       char temp[4] = {0x0};
+
+       switch (gf_dev->event) {
+       case GF_NET_EVENT_FB_BLACK:
+               gf_dev->display_on = false;
+               break;
+       case GF_NET_EVENT_FB_UNBLACK:
+               gf_dev->display_on = true;
+               break;
+       /*
+        * IRQs are followed by fingerprint procesing, hold a wakelock to make
+        * sure the fingerprint is processed when screen is off.
+        */
+       case GF_NET_EVENT_IRQ:
+               if (gf_dev->display_on)
+                       break;
+
+               wake_lock_timeout(&gf_dev->fp_wakelock,
+                               msecs_to_jiffies(FINGERPRINT_PROCESSING_MS));
+               break;
+       }
+
+       temp[0] = gf_dev->event;
+
+       sendnlmsg(temp);
+}
+
+static int gf_fb_state_callback(struct notifier_block *nb,
+               unsigned long type, void *data)
 {
-       struct gf_dev *gf_dev;
        struct fb_event *evdata = data;
+       struct gf_device *gf_dev;
        unsigned int blank;
-       char temp[4] = { 0x0 };
-
-       if (val != FB_EVENT_BLANK)
-               return 0;
-       pr_debug("[info] %s go to the goodix_fb_state_chg_callback value = %d\n",
-                       __func__, (int)val);
-       gf_dev = container_of(nb, struct gf_dev, notifier);
-       if (evdata && evdata->data && val == FB_EVENT_BLANK && gf_dev) {
-               blank = *(int *)(evdata->data);
-               switch (blank) {
-               case FB_BLANK_POWERDOWN:
-                       if (gf_dev->device_available == 1) {
-                               gf_dev->fb_black = 1;
-#if defined(GF_NETLINK_ENABLE)
-                               temp[0] = GF_NET_EVENT_FB_BLACK;
-                               sendnlmsg(temp);
-#elif defined (GF_FASYNC)
-                               if (gf_dev->async) {
-                                       kill_fasync(&gf_dev->async, SIGIO, POLL_IN);
-                               }
-#endif
-                       }
-                       break;
-               case FB_BLANK_UNBLANK:
-                       if (gf_dev->device_available == 1) {
-                               gf_dev->fb_black = 0;
-#if defined(GF_NETLINK_ENABLE)
-                               temp[0] = GF_NET_EVENT_FB_UNBLACK;
-                               sendnlmsg(temp);
-#elif defined (GF_FASYNC)
-                               if (gf_dev->async) {
-                                       kill_fasync(&gf_dev->async, SIGIO, POLL_IN);
-                               }
-#endif
-                       }
-                       break;
-               default:
-                       pr_debug("%s defalut\n", __func__);
-                       break;
-               }
+
+       if (type != FB_EVENT_BLANK)
+               goto end;
+
+       if (!evdata || !evdata->data)
+               goto end;
+
+       pr_debug("%s: type=%d\n", __func__, (int)type);
+
+       gf_dev = container_of(nb, struct gf_device, notifier);
+
+       blank = *(int *)(evdata->data);
+       switch (blank) {
+       case FB_BLANK_POWERDOWN:
+               gf_dev->event = GF_NET_EVENT_FB_BLACK;
+               break;
+       case FB_BLANK_UNBLANK:
+               gf_dev->event = GF_NET_EVENT_FB_UNBLACK;
+               break;
+       default:
+               goto end;
        }
+
+       queue_work(gf_dev->event_workqueue, &gf_dev->event_work);
+
+end:
        return NOTIFY_OK;
 }
 
-static struct notifier_block goodix_noti_block = {
-       .notifier_call = goodix_fb_state_chg_callback,
+static struct notifier_block gf_fb_notifier = {
+       .notifier_call = gf_fb_state_callback,
 };
 
-static struct class *gf_class;
-#if defined(USE_SPI_BUS)
-static int gf_probe(struct spi_device *spi)
-#elif defined(USE_PLATFORM_BUS)
 static int gf_probe(struct platform_device *pdev)
-#endif
 {
-       struct gf_dev *gf_dev = &gf;
-       int status = -EINVAL;
-       unsigned long minor;
-       int i;
-
-       /* Initialize the driver data */
-       INIT_LIST_HEAD(&gf_dev->device_entry);
-#if defined(USE_SPI_BUS)
-       gf_dev->spi = spi;
-#elif defined(USE_PLATFORM_BUS)
-       gf_dev->spi = pdev;
-#endif
-       gf_dev->irq_gpio = -EINVAL;
-       gf_dev->reset_gpio = -EINVAL;
-       gf_dev->pwr_gpio = -EINVAL;
-       gf_dev->device_available = 0;
-       gf_dev->fb_black = 0;
-
-       if (gf_parse_dts(gf_dev))
-               goto error_hw;
-
-       /* If we can allocate a minor number, hook up this device.
-        * Reusing minors is fine so long as udev or mdev is working.
-        */
-       mutex_lock(&device_list_lock);
-       minor = find_first_zero_bit(minors, N_SPI_MINORS);
-       if (minor < N_SPI_MINORS) {
-               struct device *dev;
+       struct gf_device *gf_dev = &gf;
+       struct device *dev;
+       int major;
+       int rc = 0;
 
-               gf_dev->devt = MKDEV(SPIDEV_MAJOR, minor);
-               dev = device_create(gf_class, &gf_dev->spi->dev, gf_dev->devt,
-                               gf_dev, GF_DEV_NAME);
-               status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
-       } else {
-               dev_dbg(&gf_dev->spi->dev, "no minor number available!\n");
-               status = -ENODEV;
-               mutex_unlock(&device_list_lock);
-               goto error_hw;
-       }
+       gf_dev->display_on = true;
+       gf_dev->irq_enabled = false;
 
-       if (status == 0) {
-               set_bit(minor, minors);
-               list_add(&gf_dev->device_entry, &device_list);
-       } else {
-               gf_dev->devt = 0;
+       gf_dev->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
+                       "fp-gpio-reset", 0);
+       if (!gpio_is_valid(gf_dev->reset_gpio)) {
+               pr_err("%s: failed to get reset_gpio, rc = %d\n", __func__, rc);
+               rc = -EINVAL;
+               goto error_dt;
        }
-       mutex_unlock(&device_list_lock);
-
-       if (status == 0) {
-               /*input device subsystem */
-               gf_dev->input = input_allocate_device();
-               if (gf_dev->input == NULL) {
-                       pr_err("%s, failed to allocate input device\n", __func__);
-                       status = -ENOMEM;
-                       goto error_dev;
-               }
-               for (i = 0; i < ARRAY_SIZE(maps); i++)
-                       input_set_capability(gf_dev->input, maps[i].type, maps[i].code);
-
-               gf_dev->input->name = GF_INPUT_NAME;
-               status = input_register_device(gf_dev->input);
-               if (status) {
-                       pr_err("failed to register input device\n");
-                       goto error_input;
-               }
+
+       gf_dev->irq_gpio = of_get_named_gpio(pdev->dev.of_node,
+                       "fp-gpio-irq", 0);
+       if (!gpio_is_valid(gf_dev->irq_gpio)) {
+               pr_err("%s: failed to get irq_gpio, rc = %d\n", __func__, rc);
+               rc = -EINVAL;
+               goto error_dt;
        }
-#ifdef AP_CONTROL_CLK
-       pr_debug("Get the clk resource.\n");
-       /* Enable spi clock */
-       if (gfspi_ioctl_clk_init(gf_dev))
-               goto gfspi_probe_clk_init_failed;
 
-       if (gfspi_ioctl_clk_enable(gf_dev))
-               goto gfspi_probe_clk_enable_failed;
+       gf_dev->irq = gpio_to_irq(gf_dev->irq_gpio);
+       enable_irq_wake(gf_dev->irq);
 
-       spi_clock_set(gf_dev, 1000000);
-#endif
+       major = register_chrdev(0, GF_DRIVER_NAME, &gf_fops);
+       if (major < 0) {
+               pr_err("%s: failed to register char device\n", __func__);
+               rc = major;
+               goto error_chardev;
+       }
 
-       gf_dev->notifier = goodix_noti_block;
-       fb_register_client(&gf_dev->notifier);
+       gf_dev->cls = class_create(THIS_MODULE, GF_DEV_NAME);
+       if (IS_ERR(gf_dev->cls)) {
+               pr_err("%s: failed to create device class\n", __func__);
+               rc = PTR_ERR(gf_dev->cls);
+               goto error_class;
+       }
 
-       gf_dev->irq = gf_irq_num(gf_dev);
+       gf_dev->devt = MKDEV(major, 0);
+       dev = device_create(gf_dev->cls, &pdev->dev, gf_dev->devt,
+                               gf_dev, GF_DEV_NAME);
+       if (IS_ERR(dev)) {
+               pr_err("%s: failed to create device\n", __func__);
+               rc = PTR_ERR(dev);
+               goto error_device;
+       }
 
-       wake_lock_init(&fp_wakelock, WAKE_LOCK_SUSPEND, "fp_wakelock");
-       pr_debug("version V%d.%d.%02d\n", VER_MAJOR, VER_MINOR, PATCH_LEVEL);
+       gf_dev->input = input_allocate_device();
+       if (!gf_dev->input) {
+               pr_err("%s: failed to allocate input device\n", __func__);
+               rc = -ENOMEM;
+               goto error_input_alloc;
+       }
 
-       return status;
+       input_set_capability(gf_dev->input, EV_KEY, GF_KEY_INPUT_HOME);
 
-#ifdef AP_CONTROL_CLK
-gfspi_probe_clk_enable_failed:
-       gfspi_ioctl_clk_uninit(gf_dev);
-gfspi_probe_clk_init_failed:
-#endif
-       input_unregister_device(gf_dev->input);
-error_input:
-       if (gf_dev->input != NULL)
-               input_free_device(gf_dev->input);
-error_dev:
-       if (gf_dev->devt != 0) {
-               pr_debug("Err: status = %d\n", status);
-               mutex_lock(&device_list_lock);
-               list_del(&gf_dev->device_entry);
-               device_destroy(gf_class, gf_dev->devt);
-               clear_bit(MINOR(gf_dev->devt), minors);
-               mutex_unlock(&device_list_lock);
+       gf_dev->input->name = GF_INPUT_NAME;
+       rc = input_register_device(gf_dev->input);
+       if (rc) {
+               pr_err("%s: failed to register input device\n", __func__);
+               goto error_input_register;
        }
-error_hw:
-       gf_cleanup(gf_dev);
-       gf_dev->device_available = 0;
 
-       return status;
+       gf_dev->notifier = gf_fb_notifier;
+       fb_register_client(&gf_dev->notifier);
+       gf_dev->event_workqueue = alloc_workqueue("gf-event-wq",
+                       WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
+       INIT_WORK(&gf_dev->event_work, gf_event_worker);
+
+       wake_lock_init(&gf_dev->fp_wakelock, WAKE_LOCK_SUSPEND, "fp_wakelock");
+
+       netlink_init();
+
+       return 0;
+
+error_input_register:
+       input_free_device(gf_dev->input);
+error_input_alloc:
+       device_destroy(gf_dev->cls, gf_dev->devt);
+error_device:
+       class_destroy(gf_dev->cls);
+error_class:
+       unregister_chrdev(MAJOR(gf_dev->devt), GF_DEV_NAME);
+error_chardev:
+error_dt:
+       return rc;
 }
 
-#if defined(USE_SPI_BUS)
-static int gf_remove(struct spi_device *spi)
-#elif defined(USE_PLATFORM_BUS)
 static int gf_remove(struct platform_device *pdev)
-#endif
 {
-       struct gf_dev *gf_dev = &gf;
+       struct gf_device *gf_dev = &gf;
 
-       wake_lock_destroy(&fp_wakelock);
-       /* make sure ops on existing fds can abort cleanly */
-       if (gf_dev->irq)
-               free_irq(gf_dev->irq, gf_dev);
-
-       if (gf_dev->input != NULL)
-               input_unregister_device(gf_dev->input);
-       input_free_device(gf_dev->input);
+       netlink_exit();
 
-       /* prevent new opens */
-       mutex_lock(&device_list_lock);
-       list_del(&gf_dev->device_entry);
-       device_destroy(gf_class, gf_dev->devt);
-       clear_bit(MINOR(gf_dev->devt), minors);
-       if (gf_dev->users == 0)
-               gf_cleanup(gf_dev);
+       wake_lock_destroy(&gf_dev->fp_wakelock);
 
+       destroy_workqueue(gf_dev->event_workqueue);
 
        fb_unregister_client(&gf_dev->notifier);
-       mutex_unlock(&device_list_lock);
+
+       input_unregister_device(gf_dev->input);
+
+       device_destroy(gf_dev->cls, gf_dev->devt);
+       class_destroy(gf_dev->cls);
+       unregister_chrdev(MAJOR(gf_dev->devt), GF_DEV_NAME);
 
        return 0;
 }
 
-static struct of_device_id gx_match_table[] = {
+static struct of_device_id gf_match_table[] = {
        { .compatible = GF_SPIDEV_NAME },
        {},
 };
 
-#if defined(USE_SPI_BUS)
-static struct spi_driver gf_driver = {
-#elif defined(USE_PLATFORM_BUS)
 static struct platform_driver gf_driver = {
-#endif
        .driver = {
                .name = GF_DEV_NAME,
                .owner = THIS_MODULE,
-               .of_match_table = gx_match_table,
+               .of_match_table = gf_match_table,
        },
        .probe = gf_probe,
        .remove = gf_remove,
 };
 
-static int __init gf_init(void)
-{
-       int status;
-
-       /* Claim our 256 reserved device numbers.  Then register a class
-        * that will key udev/mdev to add/remove /dev nodes.  Last, register
-        * the driver which manages those device numbers.
-        */
-
-       BUILD_BUG_ON(N_SPI_MINORS > 256);
-       status = register_chrdev(SPIDEV_MAJOR, CHRD_DRIVER_NAME, &gf_fops);
-       if (status < 0) {
-               pr_warn("Failed to register char device!\n");
-               return status;
-       }
-       SPIDEV_MAJOR = status;
-       gf_class = class_create(THIS_MODULE, CLASS_NAME);
-       if (IS_ERR(gf_class)) {
-               unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name);
-               pr_warn("Failed to create class.\n");
-               return PTR_ERR(gf_class);
-       }
-#if defined(USE_PLATFORM_BUS)
-       status = platform_driver_register(&gf_driver);
-#elif defined(USE_SPI_BUS)
-       status = spi_register_driver(&gf_driver);
-#endif
-       if (status < 0) {
-               class_destroy(gf_class);
-               unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name);
-               pr_warn("Failed to register SPI driver.\n");
-       }
-
-#ifdef GF_NETLINK_ENABLE
-       netlink_init();
-#endif
-       pr_debug("status = 0x%x\n", status);
-       return 0;
-}
-module_init(gf_init);
-
-static void __exit gf_exit(void)
-{
-#ifdef GF_NETLINK_ENABLE
-       netlink_exit();
-#endif
-#if defined(USE_PLATFORM_BUS)
-       platform_driver_unregister(&gf_driver);
-#elif defined(USE_SPI_BUS)
-       spi_unregister_driver(&gf_driver);
-#endif
-       class_destroy(gf_class);
-       unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name);
-}
-module_exit(gf_exit);
+module_platform_driver(gf_driver);
 
 MODULE_AUTHOR("Jiangtao Yi, <yijiangtao@goodix.com>");
 MODULE_AUTHOR("Jandy Gou, <gouqingsong@goodix.com>");
index 207e385..bdaa812 100644 (file)
 
 #include <linux/types.h>
 #include <linux/notifier.h>
-/**********************************************************/
-enum FP_MODE{
-       GF_IMAGE_MODE = 0,
-       GF_KEY_MODE,
-       GF_SLEEP_MODE,
-       GF_FF_MODE,
-       GF_DEBUG_MODE = 0x56
-};
-
-#define SUPPORT_NAV_EVENT
-
-#if defined(SUPPORT_NAV_EVENT)
-#define GF_NAV_INPUT_UP                        KEY_UP
-#define GF_NAV_INPUT_DOWN              KEY_DOWN
-#define GF_NAV_INPUT_LEFT              KEY_LEFT
-#define GF_NAV_INPUT_RIGHT             KEY_RIGHT
-#define GF_NAV_INPUT_CLICK             KEY_VOLUMEDOWN
-#define GF_NAV_INPUT_DOUBLE_CLICK      KEY_VOLUMEUP
-#define GF_NAV_INPUT_LONG_PRESS                KEY_SEARCH
-#define GF_NAV_INPUT_HEAVY             KEY_CHAT
-#endif
+#include <linux/wakelock.h>
 
 #define GF_KEY_INPUT_HOME              KEY_HOME
-#define GF_KEY_INPUT_MENU              KEY_MENU
-#define GF_KEY_INPUT_BACK              KEY_BACK
-#define GF_KEY_INPUT_POWER             KEY_POWER
-#define GF_KEY_INPUT_CAMERA            KEY_CAMERA
-
-#if defined(SUPPORT_NAV_EVENT)
-typedef enum gf_nav_event {
-       GF_NAV_NONE = 0,
-       GF_NAV_FINGER_UP,
-       GF_NAV_FINGER_DOWN,
-       GF_NAV_UP,
-       GF_NAV_DOWN,
-       GF_NAV_LEFT,
-       GF_NAV_RIGHT,
-       GF_NAV_CLICK,
-       GF_NAV_HEAVY,
-       GF_NAV_LONG_PRESS,
-       GF_NAV_DOUBLE_CLICK,
-} gf_nav_event_t;
-#endif
 
 typedef enum gf_key_event {
-       GF_KEY_NONE = 0,
-       GF_KEY_HOME,
-       GF_KEY_POWER,
-       GF_KEY_MENU,
-       GF_KEY_BACK,
-       GF_KEY_CAMERA,
+       GF_KEY_HOME = 1
 } gf_key_event_t;
 
 struct gf_key {
        enum gf_key_event key;
-       uint32_t value;   /* key down = 1, key up = 0 */
-};
-
-struct gf_key_map {
-       unsigned int type;
-       unsigned int code;
+       uint32_t value;
 };
 
-struct gf_ioc_chip_info {
-       unsigned char vendor_id;
-       unsigned char mode;
-       unsigned char operation;
-       unsigned char reserved[5];
+#define GF_IOC_MAGIC                   'g'
+#define GF_IOC_INIT                    _IOR(GF_IOC_MAGIC, 0, uint8_t)
+#define GF_IOC_RESET                   _IO(GF_IOC_MAGIC, 2)
+#define GF_IOC_ENABLE_IRQ              _IO(GF_IOC_MAGIC, 3)
+#define GF_IOC_DISABLE_IRQ             _IO(GF_IOC_MAGIC, 4)
+#define GF_IOC_INPUT_KEY_EVENT         _IOW(GF_IOC_MAGIC, 9, struct gf_key)
+
+enum {
+       GF_NET_EVENT_IRQ = 1,
+       GF_NET_EVENT_FB_BLACK,
+       GF_NET_EVENT_FB_UNBLACK
 };
 
-#define GF_IOC_MAGIC    'g'     /*define magic number*/
-#define GF_IOC_INIT             _IOR(GF_IOC_MAGIC, 0, uint8_t)
-#define GF_IOC_EXIT             _IO(GF_IOC_MAGIC, 1)
-#define GF_IOC_RESET            _IO(GF_IOC_MAGIC, 2)
-#define GF_IOC_ENABLE_IRQ       _IO(GF_IOC_MAGIC, 3)
-#define GF_IOC_DISABLE_IRQ      _IO(GF_IOC_MAGIC, 4)
-#define GF_IOC_ENABLE_SPI_CLK   _IOW(GF_IOC_MAGIC, 5, uint32_t)
-#define GF_IOC_DISABLE_SPI_CLK  _IO(GF_IOC_MAGIC, 6)
-#define GF_IOC_ENABLE_POWER     _IO(GF_IOC_MAGIC, 7)
-#define GF_IOC_DISABLE_POWER    _IO(GF_IOC_MAGIC, 8)
-#define GF_IOC_INPUT_KEY_EVENT  _IOW(GF_IOC_MAGIC, 9, struct gf_key)
-#define GF_IOC_ENTER_SLEEP_MODE _IO(GF_IOC_MAGIC, 10)
-#define GF_IOC_GET_FW_INFO      _IOR(GF_IOC_MAGIC, 11, uint8_t)
-#define GF_IOC_REMOVE           _IO(GF_IOC_MAGIC, 12)
-#define GF_IOC_CHIP_INFO        _IOW(GF_IOC_MAGIC, 13, struct gf_ioc_chip_info)
-
-#if defined(SUPPORT_NAV_EVENT)
-#define GF_IOC_NAV_EVENT       _IOW(GF_IOC_MAGIC, 14, gf_nav_event_t)
-#define  GF_IOC_MAXNR    15  /* THIS MACRO IS NOT USED NOW... */
-#else
-#define  GF_IOC_MAXNR    14  /* THIS MACRO IS NOT USED NOW... */
-#endif
-
-/*#define AP_CONTROL_CLK       1*/
-#define  USE_PLATFORM_BUS     1
-/*#define  USE_SPI_BUS 1*/
-/*#define GF_FASYNC   1*//*If support fasync mechanism.*/
-#define GF_NETLINK_ENABLE 1
-#define GF_NET_EVENT_IRQ 1
-#define GF_NET_EVENT_FB_BLACK 2
-#define GF_NET_EVENT_FB_UNBLACK 3
 #define NETLINK_TEST 25
 
-struct gf_dev {
+struct gf_device {
+       struct class *cls;
        dev_t devt;
-       struct list_head device_entry;
-#if defined(USE_SPI_BUS)
-       struct spi_device *spi;
-#elif defined(USE_PLATFORM_BUS)
-       struct platform_device *spi;
-#endif
-       struct clk *core_clk;
-       struct clk *iface_clk;
 
        struct input_dev *input;
-       /* buffer is NULL unless this device is open (users > 0) */
-       unsigned users;
+
+       struct notifier_block notifier;
+       struct workqueue_struct *event_workqueue;
+       struct work_struct event_work;
+       struct wake_lock fp_wakelock;
+       bool display_on;
+       int event;
+
+       bool irq_enabled;
        signed irq_gpio;
        signed reset_gpio;
-       signed pwr_gpio;
+
+       unsigned users;
        int irq;
-       int irq_enabled;
-       int clk_enabled;
-#ifdef GF_FASYNC
-       struct fasync_struct *async;
-#endif
-       struct notifier_block notifier;
-       char device_available;
-       char fb_black;
 };
 
-int gf_parse_dts(struct gf_dev *gf_dev);
-void gf_cleanup(struct gf_dev *gf_dev);
-
-int gf_power_on(struct gf_dev *gf_dev);
-int gf_power_off(struct gf_dev *gf_dev);
-
-int gf_hw_reset(struct gf_dev *gf_dev, unsigned int delay_ms);
-int gf_irq_num(struct gf_dev *gf_dev);
-
 void sendnlmsg(char *message);
-int netlink_init(void);
+void netlink_init(void);
 void netlink_exit(void);
+
 #endif /*__GF_SPI_H*/
index 9e96fa8..1ed639e 100644 (file)
 #include <net/sock.h>
 #include <net/netlink.h>
 
-#define NETLINK_TEST 25
-#define MAX_MSGSIZE 32
-int stringlength(char *s);
-void sendnlmsg(char *message);
+#include "gf_spi.h"
+
+#define MAX_MSG_SIZE 32
+
 static int pid = -1;
 struct sock *nl_sk = NULL;
 
@@ -23,32 +23,31 @@ void sendnlmsg(char *message)
 {
        struct sk_buff *skb_1;
        struct nlmsghdr *nlh;
-       int len = NLMSG_SPACE(MAX_MSGSIZE);
-       int slen = 0;
+       int len = NLMSG_SPACE(MAX_MSG_SIZE);
        int ret = 0;
-       if (!message || !nl_sk || !pid) {
+       int slen;
+
+       if (!message || !nl_sk || !pid)
                return;
-       }
+
        skb_1 = alloc_skb(len, GFP_KERNEL);
        if (!skb_1) {
-               pr_err("alloc_skb error\n");
+               pr_err("%s: failed to allocate network buffer\n", __func__);
                return;
        }
-       slen = strlen(message);
-       nlh = nlmsg_put(skb_1, 0, 0, 0, MAX_MSGSIZE, 0);
+
+       nlh = nlmsg_put(skb_1, 0, 0, 0, MAX_MSG_SIZE, 0);
 
        NETLINK_CB(skb_1).portid = 0;
        NETLINK_CB(skb_1).dst_group = 0;
 
+       slen = strlen(message);
        message[slen] = '\0';
-       memcpy(NLMSG_DATA(nlh), message, slen+1);
+       memcpy(NLMSG_DATA(nlh), message, slen + 1);
 
        ret = netlink_unicast(nl_sk, skb_1, pid, MSG_DONTWAIT);
-       if (!ret) {
-               /*kfree_skb(skb_1);*/
-               pr_err("send msg from kernel to usespace failed ret 0x%x\n", ret);
-       }
-
+       if (!ret)
+               pr_err("%s: failed to send netlink message\n", __func__);
 }
 
 
@@ -57,21 +56,25 @@ void nl_data_ready(struct sk_buff *__skb)
        struct sk_buff *skb;
        struct nlmsghdr *nlh;
        char str[100];
+
        skb = skb_get (__skb);
-       if (skb->len >= NLMSG_SPACE(0)) {
-               nlh = nlmsg_hdr(skb);
-               memcpy(str, NLMSG_DATA(nlh), sizeof(str));
-               pid = nlh->nlmsg_pid;
-               kfree_skb(skb);
-       }
+
+       if (skb->len < NLMSG_SPACE(0))
+               return;
+
+       nlh = nlmsg_hdr(skb);
+       memcpy(str, NLMSG_DATA(nlh), sizeof(str));
+       pid = nlh->nlmsg_pid;
+
+       kfree_skb(skb);
 }
 
 
-int netlink_init(void)
+void netlink_init(void)
 {
        struct netlink_kernel_cfg netlink_cfg;
-       memset(&netlink_cfg, 0, sizeof(struct netlink_kernel_cfg));
 
+       memset(&netlink_cfg, 0, sizeof(struct netlink_kernel_cfg));
        netlink_cfg.groups = 0;
        netlink_cfg.flags = 0;
        netlink_cfg.input = nl_data_ready;
@@ -79,20 +82,16 @@ int netlink_init(void)
 
        nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST,
                        &netlink_cfg);
-
-       if (!nl_sk) {
-               pr_err("create netlink socket error\n");
-               return 1;
-       }
-       return 0;
+       if (!nl_sk)
+               pr_err("%s: failed to create netlink socket\n", __func__);
 }
 
 void netlink_exit(void)
 {
-       if (nl_sk != NULL) {
-               netlink_kernel_release(nl_sk);
-               nl_sk = NULL;
-       }
-       pr_info("self module exited\n");
+       if (!nl_sk)
+               return;
+
+       netlink_kernel_release(nl_sk);
+       nl_sk = NULL;
 }
 
diff --git a/drivers/input/fingerprint/goodix_ta/platform.c b/drivers/input/fingerprint/goodix_ta/platform.c
deleted file mode 100644 (file)
index 3ac2965..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * platform indepent driver interface
- *
- * Coypritht (c) 2017 Goodix
- * Copyright (C) 2017 XiaoMi, Inc.
- */
-#include <linux/delay.h>
-#include <linux/workqueue.h>
-#include <linux/of_gpio.h>
-#include <linux/gpio.h>
-#include <linux/regulator/consumer.h>
-#include <linux/timer.h>
-#include <linux/err.h>
-
-#include "gf_spi.h"
-
-#if defined(USE_SPI_BUS)
-#include <linux/spi/spi.h>
-#include <linux/spi/spidev.h>
-#elif defined(USE_PLATFORM_BUS)
-#include <linux/platform_device.h>
-#endif
-
-int gf_parse_dts(struct gf_dev *gf_dev)
-{
-       /*get reset resource*/
-       gf_dev->reset_gpio = of_get_named_gpio(gf_dev->spi->dev.of_node, "fp-gpio-reset", 0);
-       if (!gpio_is_valid(gf_dev->reset_gpio)) {
-               pr_info("RESET GPIO is invalid.\n");
-               return -EPERM;
-       }
-
-       /*get irq resourece*/
-       gf_dev->irq_gpio = of_get_named_gpio(gf_dev->spi->dev.of_node, "fp-gpio-irq", 0);
-       pr_info("gf::irq_gpio:%d\n", gf_dev->irq_gpio);
-       if (!gpio_is_valid(gf_dev->irq_gpio)) {
-               pr_info("IRQ GPIO is invalid.\n");
-               return -EPERM;
-       }
-
-       return 0;
-}
-
-void gf_cleanup(struct gf_dev *gf_dev)
-{
-       pr_info("[info] %s\n", __func__);
-       if (gpio_is_valid(gf_dev->irq_gpio)) {
-               gpio_free(gf_dev->irq_gpio);
-               pr_info("remove irq_gpio success\n");
-       }
-       if (gpio_is_valid(gf_dev->reset_gpio)) {
-               gpio_free(gf_dev->reset_gpio);
-               pr_info("remove reset_gpio success\n");
-       }
-}
-
-int gf_power_on(struct gf_dev *gf_dev)
-{
-       int rc = 0;
-
-       msleep(10);
-       pr_info("---- power on ok ----\n");
-
-       return rc;
-}
-
-int gf_power_off(struct gf_dev *gf_dev)
-{
-       int rc = 0;
-
-       pr_info("---- power off ----\n");
-       return rc;
-}
-
-int gf_hw_reset(struct gf_dev *gf_dev, unsigned int delay_ms)
-{
-       if (gf_dev == NULL) {
-               pr_info("Input buff is NULL.\n");
-               return -EPERM;
-       }
-       gpio_direction_output(gf_dev->reset_gpio, 0);
-       gpio_set_value(gf_dev->reset_gpio, 0);
-       mdelay(3);
-       gpio_set_value(gf_dev->reset_gpio, 1);
-       mdelay(delay_ms);
-       return 0;
-}
-
-int gf_irq_num(struct gf_dev *gf_dev)
-{
-       if (gf_dev == NULL) {
-               pr_info("Input buff is NULL.\n");
-               return -EPERM;
-       } else {
-               return gpio_to_irq(gf_dev->irq_gpio);
-       }
-}
-