static int pn547_remove(struct i2c_client *client)
{
    struct pn547_dev *pn547_dev;

    pn547_dev = i2c_get_clientdata(client);
    free_irq(pn547_gpio_to_irq(pn547_dev), pn547_dev);
    misc_deregister(&pn547_dev->pn547_device);
    mutex_destroy(&pn547_dev->read_mutex);
#ifdef CONFIG_LGE_NFC_USE_PMIC
    pn547_change_clk(pn547_dev, CLK_DISABLE);
#endif
    gpio_free(pn547_dev->firm_gpio);
    gpio_free(pn547_dev->ven_gpio);
    gpio_free(pn547_dev->irq_gpio);
    kfree(pn547_dev);

    return 0;
}
static long pn547_dev_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    struct pn547_dev *pn547_dev = filp->private_data;
    unsigned long flags;

    switch (cmd) {
    case pn547_SET_PWR:
        if (arg == 2) {
            /*
            power on with firmware download (requires hw reset)
            */
            dprintk(PN547_DRV_NAME ":%s power on with firmware\n", __func__);

            gpio_set_value(pn547_dev->ven_gpio, 1);
            gpio_set_value(pn547_dev->firm_gpio, 1);
            msleep(10);
            gpio_set_value(pn547_dev->ven_gpio, 0);
            msleep(10);
            gpio_set_value(pn547_dev->ven_gpio, 1);
            msleep(10);
        } else if (arg == 1) {
            /* power on */
            pr_info(PN547_DRV_NAME ":%s power on\n", __func__);
            if (sPowerState == NFC_POWER_OFF) {
#ifdef CONFIG_LGE_NFC_USE_PMIC
                if(clk_source == CLKS_PMIC)
                    pn547_change_clk(pn547_dev, CLK_PIN);
#endif
                gpio_set_value(pn547_dev->firm_gpio, 0);
                gpio_set_value(pn547_dev->ven_gpio, 1);
                msleep(10);

                spin_lock_irqsave(&pn547_dev->irq_enabled_lock, flags);
#ifdef CONFIG_LGE_NFC_SET_IRQ_WAKEUP
                if (sIrqState == false) {
                    irq_set_irq_wake(pn547_dev->client->irq,1);
                    sIrqState = true;
                    pr_info(PN547_DRV_NAME ":%s enable IRQ\n", __func__);
                }
                else {
                    pr_err("%s IRQ is already enabled!\n", __func__);
                }
#endif
                //pr_err("%s NFC_POWER_ON\n", __func__); // for debug
                sPowerState = NFC_POWER_ON;
                spin_unlock_irqrestore(&pn547_dev->irq_enabled_lock, flags);
            }
            else {
                pr_err("%s NFC is alread On!\n", __func__);
            }
        } else  if (arg == 0) {
            /* power off */
            pr_info(PN547_DRV_NAME ":%s power off\n", __func__);
            if (sPowerState == NFC_POWER_ON) {
#ifdef CONFIG_LGE_NFC_USE_PMIC
                if(clk_source == CLKS_PMIC)
                    pn547_change_clk(pn547_dev, CLK_DISABLE);
#endif
                gpio_set_value(pn547_dev->firm_gpio, 0);
                gpio_set_value(pn547_dev->ven_gpio, 0);
                msleep(10);

                spin_lock_irqsave(&pn547_dev->irq_enabled_lock, flags);
#ifdef CONFIG_LGE_NFC_SET_IRQ_WAKEUP
                if (sIrqState == true) {
                    irq_set_irq_wake(pn547_dev->client->irq,0);
                    sIrqState = false;
                    dprintk(PN547_DRV_NAME ":%s disable IRQ\n", __func__);
                }
                else {
                    pr_err("%s IRQ is already disabled!\n", __func__);
                }
#endif
                if (sIsWakeLocked == true) {
                    pr_err("%s: Release Wake_Lock\n", __func__);
                    wake_unlock(&nfc_wake_lock);
                    sIsWakeLocked = false;
                }
                //pr_err("%s NFC_POWER_OFF\n", __func__); // for debug
                sPowerState = NFC_POWER_OFF;
                spin_unlock_irqrestore(&pn547_dev->irq_enabled_lock, flags);
            }
            else {
                pr_err("%s NFC is alread Off!\n", __func__);
            }
        } else {
                pr_err("%s bad arg %ld\n", __func__, arg);
            return -EINVAL;
        }
        break;
    case pn547_HW_REVISION:
        {
            return pn547_get_hw_revision();
        }
#ifdef CONFIG_LGE_NFC_USE_PMIC
    case pn547_CLKS_SET:
        {
            if(arg == 0){
                clk_source = CLKS_XO;
                dprintk(PN547_DRV_NAME "%s: clock source X-tal set!\n", __func__);
            }else if(arg == 1){
                clk_source = CLKS_PMIC;
                dprintk(PN547_DRV_NAME "%s: clock source PMIC set!\n", __func__);
            }else{
                pr_err("%s: wrong clock source set clk source : %ld\n", __func__, arg);
                return -1;
            }
        }
        break;
#endif
    default:
        pr_err("%s bad ioctl %d\n", __func__, cmd);
        return -EINVAL;
    }

    return 0;
}
Exemple #3
0
static int pn547_probe(struct i2c_client *client,
        const struct i2c_device_id *id)
{
    int ret;
    struct pn547_dev *pn547_dev = NULL;
    pn547_client = client;

    pr_info(PN547_DRV_NAME ": pn547_probe() start\n");

    pn547_dev = kzalloc(sizeof(*pn547_dev), GFP_KERNEL);
    if (pn547_dev == NULL) {
        dev_err(&client->dev,
                "failed to allocate memory for module data\n");
        ret = -ENOMEM;
        goto err_exit;
    }

    pn547_parse_dt(&client->dev, pn547_dev);

    pn547_dev->client   = client;
    dprintk(PN547_DRV_NAME ":IRQ : %d\nVEN : %d\nFIRM : %d\n",
            pn547_dev->irq_gpio, pn547_dev->ven_gpio, pn547_dev->firm_gpio);

    ret = gpio_request(pn547_dev->irq_gpio, "nfc_int");
    if (ret) {
        dprintk(PN547_DRV_NAME ":pn547_probe() : nfc_int request failed!\n");
        goto err_int;
    }
    ret = gpio_request(pn547_dev->ven_gpio, "nfc_ven");
    if (ret) {
        dprintk(PN547_DRV_NAME ":pn547_probe() : nfc_ven request failed!\n");
        goto err_ven;
    }
    ret = gpio_request(pn547_dev->firm_gpio, "nfc_firm");
    if (ret) {
        dprintk(PN547_DRV_NAME ":pn547_probe() : nfc_firm request failed!\n");
        goto err_firm;
    }

    pn547_gpio_enable(pn547_dev);
#if defined(CONFIG_MACH_MSM8226_W7_GLOBAL_COM) || defined(CONFIG_MACH_MSM8226_W7_GLOBAL_SCA)
    ret = gpio_direction_output(pn547_dev->ven_gpio,1);
#else
	ret = gpio_direction_output(pn547_dev->ven_gpio,0);
#endif
    ret = gpio_direction_output(pn547_dev->firm_gpio,0);
    ret = gpio_direction_input(pn547_dev->irq_gpio);

#ifdef CONFIG_LGE_NFC_USE_PMIC
    pn547_get_clk_source(pn547_dev);
    pn547_change_clk(pn547_dev, CLK_PIN);
#endif
    /* init mutex and queues */
    init_waitqueue_head(&pn547_dev->read_wq);
    mutex_init(&pn547_dev->read_mutex);
    spin_lock_init(&pn547_dev->irq_enabled_lock);

    pn547_dev->pn547_device.minor = MISC_DYNAMIC_MINOR;
    pn547_dev->pn547_device.name = PN547_DRV_NAME;
    pn547_dev->pn547_device.fops = &pn547_dev_fops;

    ret = misc_register(&pn547_dev->pn547_device);
    if (ret) {
        pr_err("%s : misc_register failed\n", __FILE__);
        goto err_misc_register;
    }

    wake_lock_init(&nfc_wake_lock, WAKE_LOCK_SUSPEND, "NFCWAKE");

    /* request irq.  the irq is set whenever the chip has data available
     * for reading.  it is cleared when all data has been read.
     */
    pr_info("%s : requesting IRQ %d\n", __func__, client->irq);
    ret = request_irq(pn547_gpio_to_irq(pn547_dev), pn547_dev_irq_handler,
              IRQF_TRIGGER_RISING|IRQF_NO_SUSPEND, client->name, pn547_dev);
    if (ret) {
        dev_err(&client->dev, "request_irq failed\n");
        goto err_request_irq_failed;
    }
    // Below code does not pack with pn547_enable_irq
    // request irq make irq enable.
    // so if irq enable in pn547_enable_irq called,
    // unbalanced enable log will be appeared.
    pn547_dev->irq_enabled = true;
    enable_irq_wake(pn547_get_irq_pin(pn547_dev));
    //
    pn547_disable_irq(pn547_dev);
    i2c_set_clientdata(client, pn547_dev);
    pr_info(PN547_DRV_NAME ": pn547_probe() end\n");

    return 0;

err_request_irq_failed:
    misc_deregister(&pn547_dev->pn547_device);

err_misc_register:
    mutex_destroy(&pn547_dev->read_mutex);
    gpio_free(pn547_dev->firm_gpio);

err_firm:
    gpio_free(pn547_dev->ven_gpio);

err_ven:
    gpio_free(pn547_dev->irq_gpio);

err_int:
    kfree(pn547_dev);

err_exit:
    pr_err(PN547_DRV_NAME ": pn547_dev is null\n");
    pr_err(PN547_DRV_NAME ": pn547_probe() end with error!\n");

    return ret;
}