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; }