static ssize_t spi_prepare_set(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	int rc;
	struct  fpc1145_data *fpc1145 = dev_get_drvdata(dev);

	if (!strncmp(buf, "enable", strlen("enable")))
		rc = device_prepare(fpc1145, true);
	else if (!strncmp(buf, "disable", strlen("disable")))
		rc = device_prepare(fpc1145, false);
	else
		return -EINVAL;
	return rc ? rc : count;
}
static int fpc1145_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	int rc = 0;
	size_t i;
	int irqf;
	struct device_node *np = dev->of_node;
	u32 val;
	const char *idev_name;
	struct fpc1145_data *fpc1145 = devm_kzalloc(dev, sizeof(*fpc1145),
			GFP_KERNEL);
	if (!fpc1145) {
		dev_err(dev,
			"failed to allocate memory for struct fpc1145_data\n");
		rc = -ENOMEM;
		goto exit;
	}

	fpc1145->dev = dev;
	dev_set_drvdata(dev, fpc1145);
	fpc1145->spi = spi;

	if (!np) {
		dev_err(dev, "no of node found\n");
		rc = -EINVAL;
		goto exit;
	}

	rc = fpc1145_request_named_gpio(fpc1145, "fpc,gpio_irq",
			&fpc1145->irq_gpio);
	if (rc)
		goto exit;
	rc = fpc1145_request_named_gpio(fpc1145, "fpc,gpio_cs0",
			&fpc1145->cs0_gpio);
	if (rc)
		goto exit;
	rc = fpc1145_request_named_gpio(fpc1145, "fpc,gpio_cs1",
			&fpc1145->cs1_gpio);
	if (rc)
		goto exit;
	rc = fpc1145_request_named_gpio(fpc1145, "fpc,gpio_rst",
			&fpc1145->rst_gpio);
	if (rc)
		goto exit;

	fpc1145->iface_clk = clk_get(dev, "iface_clk");
	if (IS_ERR(fpc1145->iface_clk)) {
		dev_err(dev, "%s: Failed to get iface_clk\n", __func__);
		rc = -EINVAL;
		goto exit;
	}

	fpc1145->core_clk = clk_get(dev, "core_clk");
	if (IS_ERR(fpc1145->core_clk)) {
		dev_err(dev, "%s: Failed to get core_clk\n", __func__);
		rc = -EINVAL;
		goto exit;
	}

	rc = of_property_read_u32(np, "spi-qup-id", &val);
	if (rc < 0) {
		dev_err(dev, "spi-qup-id not found\n");
		goto exit;
	}
	fpc1145->qup_id = val;
	dev_dbg(dev, "spi-qup-id %d\n", fpc1145->qup_id);

	fpc1145->fingerprint_pinctrl = devm_pinctrl_get(dev);
	if (IS_ERR(fpc1145->fingerprint_pinctrl)) {
		if (PTR_ERR(fpc1145->fingerprint_pinctrl) == -EPROBE_DEFER) {
			dev_info(dev, "pinctrl not ready\n");
			rc = -EPROBE_DEFER;
			goto exit;
		}
		dev_err(dev, "Target does not use pinctrl\n");
		fpc1145->fingerprint_pinctrl = NULL;
		rc = -EINVAL;
		goto exit;
	}

	for (i = 0; i < ARRAY_SIZE(fpc1145->pinctrl_state); i++) {
		const char *n = pctl_names[i];
		struct pinctrl_state *state =
			pinctrl_lookup_state(fpc1145->fingerprint_pinctrl, n);
		if (IS_ERR(state)) {
			dev_err(dev, "cannot find '%s'\n", n);
			rc = -EINVAL;
			goto exit;
		}
		dev_info(dev, "found pin control %s\n", n);
		fpc1145->pinctrl_state[i] = state;
	}

	rc = select_pin_ctl(fpc1145, "fpc1145_reset_reset");
	if (rc)
		goto exit;
	rc = select_pin_ctl(fpc1145, "fpc1145_cs_low");
	if (rc)
		goto exit;
	rc = select_pin_ctl(fpc1145, "fpc1145_irq_active");
	if (rc)
		goto exit;
	rc = select_pin_ctl(fpc1145, "fpc1145_spi_active");
	if (rc)
		goto exit;

	rc = of_property_read_u32(np, "fpc,event-type", &val);
	fpc1145->event_type = rc < 0 ? EV_MSC : val;

	rc = of_property_read_u32(np, "fpc,event-code", &val);
	fpc1145->event_code = rc < 0 ? MSC_SCAN : val;

	fpc1145->idev = devm_input_allocate_device(dev);
	if (!fpc1145->idev) {
		dev_err(dev, "failed to allocate input device\n");
		rc = -ENOMEM;
		goto exit;
	}
	input_set_capability(fpc1145->idev, fpc1145->event_type,
			fpc1145->event_code);

	if (!of_property_read_string(np, "input-device-name", &idev_name)) {
		fpc1145->idev->name = idev_name;
	} else {
		snprintf(fpc1145->idev_name, sizeof(fpc1145->idev_name),
			"fpc1145@%s", dev_name(dev));
		fpc1145->idev->name = fpc1145->idev_name;
	}
	rc = input_register_device(fpc1145->idev);
	if (rc) {
		dev_err(dev, "failed to register input device\n");
		goto exit;
	}

	irqf = IRQF_TRIGGER_RISING | IRQF_ONESHOT;
	if (of_property_read_bool(dev->of_node, "fpc,enable-wakeup")) {
		irqf |= IRQF_NO_SUSPEND;
		device_init_wakeup(dev, 1);
	}
	mutex_init(&fpc1145->lock);
	rc = devm_request_threaded_irq(dev, gpio_to_irq(fpc1145->irq_gpio),
			NULL, fpc1145_irq_handler, irqf,
			dev_name(dev), fpc1145);
	if (rc) {
		dev_err(dev, "could not request irq %d\n",
				gpio_to_irq(fpc1145->irq_gpio));
		goto exit;
	}
	dev_dbg(dev, "requested irq %d\n", gpio_to_irq(fpc1145->irq_gpio));

	rc = sysfs_create_group(&dev->kobj, &attribute_group);
	if (rc) {
		dev_err(dev, "could not create sysfs\n");
		goto exit;
	}

	if (of_property_read_bool(dev->of_node, "fpc,enable-on-boot")) {
		dev_info(dev, "Enabling hardware\n");
		(void)device_prepare(fpc1145, true);
	}

	dev_info(dev, "%s: ok\n", __func__);
exit:
	if (rc)
		mutex_destroy(&fpc1145->lock);
	return rc;
}
static int fpc1020_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct device_node *np = dev->of_node;
	struct fpc1020_data *fpc1020;
	size_t i;
	int irqf = 0;
	int rc = 0;
	u32 val;
	fpc1020 = devm_kzalloc(dev, sizeof(*fpc1020), GFP_KERNEL);
	if (!fpc1020) {
		dev_err(dev, "failed to allocate memory\n");
		rc = -ENOMEM;
		goto exit;
	}

	fpc1020->dev = dev;
	dev_set_drvdata(dev, fpc1020);
	fpc1020->spi = spi;

	if (!np) {
		dev_err(dev, "of node found\n");
		rc = -EINVAL;
		goto exit;
	}

	rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_irq",
			&fpc1020->irq_gpio);
	if (rc)
		goto exit;

	rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_cs0",
			&fpc1020->cs0_gpio);
	if (rc)
		goto exit;

	rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_rst",
			&fpc1020->rst_gpio);
	if (rc)
		goto exit;

	fpc1020->iface_clk = clk_get(dev, "iface_clk");
	if (IS_ERR(fpc1020->iface_clk)) {
		dev_err(dev, "%s: failed to get iface_clk\n", __func__);
		rc = -EINVAL;
		goto exit;
	}

	fpc1020->core_clk = clk_get(dev, "core_clk");
	if (IS_ERR(fpc1020->core_clk)) {
		dev_err(dev, "%s: failed to get core_clk\n", __func__);
		rc = -EINVAL;
		goto exit;
	}

	rc = of_property_read_u32(np, "qcom,spi-qup-id", &val);
	if (rc < 0) {
		dev_err(dev, "qcom,spi-qup-id not found\n");
		goto exit;
	}

	fpc1020->qup_id = val;
	dev_dbg(dev, "qcom,spi-qup-id %d\n", fpc1020->qup_id);

	fpc1020->fingerprint_pinctrl = devm_pinctrl_get(dev);
	if (IS_ERR(fpc1020->fingerprint_pinctrl)) {
		if (PTR_ERR(fpc1020->fingerprint_pinctrl) == -EPROBE_DEFER) {
			dev_info(dev, "pinctrl not ready\n");
			rc = -EPROBE_DEFER;
			goto exit;
		}
		dev_err(dev, "Target does not use pinctrl\n");
		fpc1020->fingerprint_pinctrl = NULL;
		rc = -EINVAL;
		goto exit;
	}

	for (i = 0; i < ARRAY_SIZE(fpc1020->pinctrl_state); i++) {
		const char *n = pctl_names[i];
		struct pinctrl_state *state =
			pinctrl_lookup_state(fpc1020->fingerprint_pinctrl, n);
		if (IS_ERR(state)) {
			dev_err(dev, "cannot find '%s'\n", n);
			rc = -EINVAL;
			goto exit;
		}
		dev_info(dev, "found pin control %s\n", n);
		fpc1020->pinctrl_state[i] = state;
	}

	select_pin_ctl(fpc1020, "fpc1020_reset_active");
	udelay(100);
	select_pin_ctl(fpc1020, "fpc1020_reset_reset");
	udelay(1000);
	select_pin_ctl(fpc1020, "fpc1020_reset_active");
	udelay(1250);
	rc = select_pin_ctl(fpc1020, "fpc1020_irq_active");
	if (rc)
		goto exit;

	rc = select_pin_ctl(fpc1020, "fpc1020_spi_active");
	if (rc)
		goto exit;

	fpc1020->wakeup_enabled = false;
	fpc1020->clocks_enabled = false;
	fpc1020->clocks_suspended = false;
	irqf = IRQF_TRIGGER_RISING | IRQF_ONESHOT;
	if (of_property_read_bool(dev->of_node, "fpc,enable-wakeup")) {
		irqf |= IRQF_NO_SUSPEND;
		device_init_wakeup(dev, 1);
	}

	mutex_init(&fpc1020->lock);
	rc = devm_request_threaded_irq(dev, gpio_to_irq(fpc1020->irq_gpio),
			NULL, fpc1020_irq_handler, irqf,
			dev_name(dev), fpc1020);
	if (rc) {
		dev_err(dev, "could not request irq %d\n",
				gpio_to_irq(fpc1020->irq_gpio));
		goto exit;
	}

	dev_dbg(dev, "requested irq %d\n", gpio_to_irq(fpc1020->irq_gpio));

	/* Request that the interrupt should be wakeable */
	enable_irq_wake( gpio_to_irq( fpc1020->irq_gpio ) );

	wake_lock_init(&fpc1020->ttw_wl, WAKE_LOCK_SUSPEND, "fpc_ttw_wl");

	rc = sysfs_create_group(&dev->kobj, &attribute_group);
	if (rc) {
		dev_err(dev, "could not create sysfs\n");
		goto exit;
	}

	if (of_property_read_bool(dev->of_node, "fpc,enable-on-boot")) {
		dev_info(dev, "enabling hardware\n");
		(void)device_prepare(fpc1020, true);
		(void)set_clks(fpc1020, false);
	}

	dev_info(dev, "%s: end\n", __func__);
exit:
	return rc;
}