Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bf3f2e7 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "NFC: Keep VEN gpio always high from boot"

parents f5be9bae 04faeba9
Loading
Loading
Loading
Loading
+73 −52
Original line number Diff line number Diff line
@@ -54,15 +54,15 @@ MODULE_DEVICE_TABLE(of, msm_match_table);
#define WAKEUP_SRC_TIMEOUT		(2000)
#define MAX_RETRY_COUNT			3
#define NCI_RESET_CMD_LEN		4
#define NCI_INIT_CMD_LEN		3
#define NCI_RESET_RSP_LEN		6
#define NCI_INIT_RSP_LEN		28
#define NCI_RESET_RSP_LEN		4
#define NCI_RESET_NTF_LEN		13
#define NCI_GET_VERSION_CMD_LEN		8
#define NCI_GET_VERSION_RSP_LEN		12

struct nqx_dev {
	wait_queue_head_t	read_wq;
	struct	mutex		read_mutex;
	struct	mutex		dev_ref_mutex;
	struct	i2c_client	*client;
	dev_t			devno;
	struct class		*nqx_class;
@@ -83,6 +83,8 @@ struct nqx_dev {
	bool			irq_wake_up;
	spinlock_t		irq_enabled_lock;
	unsigned int		count_irq;
	/* NFC_IRQ Count */
	unsigned int		dev_ref_count;
	/* Initial CORE RESET notification */
	unsigned int		core_reset_ntf;
	/* CLK control */
@@ -489,16 +491,56 @@ static int nqx_ese_pwr(struct nqx_dev *nqx_dev, unsigned long int arg)

static int nfc_open(struct inode *inode, struct file *filp)
{
	int ret = 0;
	struct nqx_dev *nqx_dev = container_of(inode->i_cdev,
				struct nqx_dev, c_dev);

	filp->private_data = nqx_dev;
	nqx_init_stat(nqx_dev);

	mutex_lock(&nqx_dev->dev_ref_mutex);

	if (nqx_dev->dev_ref_count == 0) {
		nqx_enable_irq(nqx_dev);

		if (gpio_is_valid(nqx_dev->firm_gpio)) {
			gpio_set_value(nqx_dev->firm_gpio, 0);
			usleep_range(10000, 10100);
		}
	}

	nqx_dev->dev_ref_count = nqx_dev->dev_ref_count + 1;

	mutex_unlock(&nqx_dev->dev_ref_mutex);

	dev_dbg(&nqx_dev->client->dev,
			"%s: %d,%d\n", __func__, imajor(inode), iminor(inode));
	return ret;
	return 0;
}

static int nfc_close(struct inode *inode, struct file *filp)
{
	struct nqx_dev *nqx_dev = container_of(inode->i_cdev,
				struct nqx_dev, c_dev);

	mutex_lock(&nqx_dev->dev_ref_mutex);

	if (nqx_dev->dev_ref_count == 1) {
		nqx_disable_irq(nqx_dev);

		if (gpio_is_valid(nqx_dev->firm_gpio)) {
			gpio_set_value(nqx_dev->firm_gpio, 0);
			usleep_range(10000, 10100);
		}
	}

	if (nqx_dev->dev_ref_count > 0)
		nqx_dev->dev_ref_count = nqx_dev->dev_ref_count - 1;

	mutex_unlock(&nqx_dev->dev_ref_mutex);

	filp->private_data = NULL;

	return 0;
}

/*
@@ -744,6 +786,7 @@ static const struct file_operations nfc_dev_fops = {
	.read  = nfc_read,
	.write = nfc_write,
	.open = nfc_open,
	.release = nfc_close,
	.unlocked_ioctl = nfc_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = nfc_compat_ioctl
@@ -756,12 +799,11 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
	int ret = 0;

	int gpio_retry_count = 0;
	unsigned char init_rsp_len = 0;
	unsigned char reset_ntf_len = 0;
	unsigned int enable_gpio = nqx_dev->en_gpio;
	char *nci_reset_cmd = NULL;
	char *nci_init_cmd = NULL;
	char *nci_init_rsp = NULL;
	char *nci_reset_rsp = NULL;
	char *nci_reset_ntf = NULL;
	char *nci_get_version_cmd = NULL;
	char *nci_get_version_rsp = NULL;

@@ -777,14 +819,8 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
		goto done;
	}

	nci_init_cmd = kzalloc(NCI_INIT_CMD_LEN + 1,  GFP_DMA | GFP_KERNEL);
	if (!nci_init_cmd) {
		ret = -ENOMEM;
		goto done;
	}

	nci_init_rsp = kzalloc(NCI_INIT_RSP_LEN + 1,  GFP_DMA | GFP_KERNEL);
	if (!nci_init_rsp) {
	nci_reset_ntf = kzalloc(NCI_RESET_NTF_LEN + 1,  GFP_DMA | GFP_KERNEL);
	if (!nci_reset_ntf) {
		ret = -ENOMEM;
		goto done;
	}
@@ -883,34 +919,28 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
			goto reset_enable_gpio;
		goto err_nfcc_hw_check;
	}
	nci_init_cmd[0] = 0x20;
	nci_init_cmd[1] = 0x01;
	nci_init_cmd[2] = 0x00;
	ret = nqx_standby_write(nqx_dev, nci_init_cmd, NCI_INIT_CMD_LEN);
	if (ret < 0) {
		dev_err(&client->dev,
		"%s: - i2c_master_send failed for Core INIT\n", __func__);
		goto err_nfcc_core_init_fail;
	}

	/* hardware dependent delay */
	msleep(30);
	/* Read Response of INIT command */
	ret = i2c_master_recv(client, nci_init_rsp, NCI_INIT_RSP_LEN);

	/* Read Notification of RESET command */
	ret = i2c_master_recv(client, nci_reset_ntf, NCI_RESET_NTF_LEN);
	if (ret < 0) {
		dev_err(&client->dev,
		"%s: - i2c_master_recv Error\n", __func__);
		goto err_nfcc_core_init_fail;
		goto err_nfcc_hw_check;
	}
	init_rsp_len = 2 + nci_init_rsp[2]; /*payload + len*/
	if (init_rsp_len > PAYLOAD_HEADER_LENGTH) {

	reset_ntf_len = 2 + nci_reset_ntf[2]; /*payload + len*/
	if (reset_ntf_len > PAYLOAD_HEADER_LENGTH) {
		nqx_dev->nqx_info.info.chip_type =
				nci_init_rsp[init_rsp_len - 3];
				nci_reset_ntf[reset_ntf_len - 3];
		nqx_dev->nqx_info.info.rom_version =
				nci_init_rsp[init_rsp_len - 2];
				nci_reset_ntf[reset_ntf_len - 2];
		nqx_dev->nqx_info.info.fw_major =
				nci_init_rsp[init_rsp_len - 1];
				nci_reset_ntf[reset_ntf_len - 1];
		nqx_dev->nqx_info.info.fw_minor =
				nci_init_rsp[init_rsp_len];
				nci_reset_ntf[reset_ntf_len];
	}
	dev_dbg(&client->dev,
		"%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
@@ -926,14 +956,6 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
		nqx_dev->nqx_info.info.fw_minor);

	switch (nqx_dev->nqx_info.info.chip_type) {
	case NFCC_NQ_210:
		dev_dbg(&client->dev,
		"%s: ## NFCC == NQ210 ##\n", __func__);
		break;
	case NFCC_NQ_220:
		dev_dbg(&client->dev,
		"%s: ## NFCC == NQ220 ##\n", __func__);
		break;
	case NFCC_NQ_310:
		dev_dbg(&client->dev,
		"%s: ## NFCC == NQ310 ##\n", __func__);
@@ -946,23 +968,21 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
		dev_dbg(&client->dev,
		"%s: ## NFCC == PN66T ##\n", __func__);
		break;
	case NFCC_SN100_A:
	case NFCC_SN100_B:
		dev_dbg(&client->dev,
		"%s: ## NFCC == SN100x ##\n", __func__);
		break;
	default:
		dev_err(&client->dev,
		"%s: - NFCC HW not Supported\n", __func__);
		break;
	}

	/*Disable NFC by default to save power on boot*/
	gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
	ret = 0;
	nqx_dev->nfc_ven_enabled = true;
	goto done;

err_nfcc_core_init_fail:
	dev_err(&client->dev,
	"%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
	__func__, nci_reset_rsp[0],
	nci_reset_rsp[1], nci_reset_rsp[2]);

err_nfcc_hw_check:
	ret = -ENXIO;
	dev_err(&client->dev,
@@ -970,8 +990,7 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)

done:
	kfree(nci_reset_rsp);
	kfree(nci_init_rsp);
	kfree(nci_init_cmd);
	kfree(nci_reset_ntf);
	kfree(nci_reset_cmd);
	kfree(nci_get_version_cmd);
	kfree(nci_get_version_rsp);
@@ -1262,6 +1281,7 @@ static int nqx_probe(struct i2c_client *client,
	/* init mutex and queues */
	init_waitqueue_head(&nqx_dev->read_wq);
	mutex_init(&nqx_dev->read_mutex);
	mutex_init(&nqx_dev->dev_ref_mutex);
	spin_lock_init(&nqx_dev->irq_enabled_lock);

	r = alloc_chrdev_region(&nqx_dev->devno, 0, DEV_COUNT, DEVICE_NAME);
@@ -1410,6 +1430,7 @@ static int nqx_remove(struct i2c_client *client)
	class_destroy(nqx_dev->nqx_class);
	unregister_chrdev_region(nqx_dev->devno, DEV_COUNT);
	mutex_destroy(&nqx_dev->read_mutex);
	mutex_destroy(&nqx_dev->dev_ref_mutex);
	gpio_free(nqx_dev->clkreq_gpio);
	/* optional gpio, not sure was configured in probe */
	if (nqx_dev->ese_gpio > 0)