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

Commit 165add72 authored by Gaurav Singhal's avatar Gaurav Singhal Committed by Gerrit - the friendly Code Review server
Browse files

NFC: Fix for core init cmd send failure



Due to delay of ~3 sec between core reset response
and core init cmd, i2c send fails as NFC controller
goes to deep sleep state if its idle for ~1sec.

Delay caused due to logs in driver probe sequence.

Delay is added after every gpio state change to
ensure, modified value is taken into consideration
and unnecessary delays are removed.

Change-Id: I4c6e8f867f641d6648139206244d67bb556e0099
Signed-off-by: default avatarGaurav Singhal <gsinghal@codeaurora.org>
Signed-off-by: default avatarChintan Pandya <cpandya@codeaurora.org>
parent 788cb1cb
Loading
Loading
Loading
Loading
+33 −20
Original line number Diff line number Diff line
@@ -469,39 +469,43 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg)
		dev_dbg(&nqx_dev->client->dev,
			"gpio_set_value disable: %s: info: %p\n",
			__func__, nqx_dev);
		if (gpio_is_valid(nqx_dev->firm_gpio))
		if (gpio_is_valid(nqx_dev->firm_gpio)) {
			gpio_set_value(nqx_dev->firm_gpio, 0);
			usleep_range(10000, 10100);
		}

		if (gpio_is_valid(nqx_dev->ese_gpio)) {
			if (!gpio_get_value(nqx_dev->ese_gpio)) {
				dev_dbg(&nqx_dev->client->dev, "disabling en_gpio\n");
				gpio_set_value(nqx_dev->en_gpio, 0);
				usleep_range(10000, 10100);
			} else {
				dev_dbg(&nqx_dev->client->dev, "keeping en_gpio high\n");
			}
		} else {
			dev_dbg(&nqx_dev->client->dev, "ese_gpio invalid, set en_gpio to low\n");
			gpio_set_value(nqx_dev->en_gpio, 0);
			usleep_range(10000, 10100);
		}
		r = nqx_clock_deselect(nqx_dev);
		if (r < 0)
			dev_err(&nqx_dev->client->dev, "unable to disable clock\n");
		nqx_dev->nfc_ven_enabled = false;
		/* hardware dependent delay */
		msleep(100);
	} else if (arg == 1) {
		nqx_enable_irq(nqx_dev);
		dev_dbg(&nqx_dev->client->dev,
			"gpio_set_value enable: %s: info: %p\n",
			__func__, nqx_dev);
		if (gpio_is_valid(nqx_dev->firm_gpio))
		if (gpio_is_valid(nqx_dev->firm_gpio)) {
			gpio_set_value(nqx_dev->firm_gpio, 0);
			usleep_range(10000, 10100);
		}
		gpio_set_value(nqx_dev->en_gpio, 1);
		usleep_range(10000, 10100);
		r = nqx_clock_select(nqx_dev);
		if (r < 0)
			dev_err(&nqx_dev->client->dev, "unable to enable clock\n");
		nqx_dev->nfc_ven_enabled = true;
		msleep(20);
	} else if (arg == 2) {
		/*
		 * We are switching to Dowload Mode, toggle the enable pin
@@ -515,14 +519,15 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg)
			}
		}
		gpio_set_value(nqx_dev->en_gpio, 1);
		msleep(20);
		if (gpio_is_valid(nqx_dev->firm_gpio))
		usleep_range(10000, 10100);
		if (gpio_is_valid(nqx_dev->firm_gpio)) {
			gpio_set_value(nqx_dev->firm_gpio, 1);
		msleep(20);
			usleep_range(10000, 10100);
		}
		gpio_set_value(nqx_dev->en_gpio, 0);
		msleep(100);
		usleep_range(10000, 10100);
		gpio_set_value(nqx_dev->en_gpio, 1);
		msleep(20);
		usleep_range(10000, 10100);
	} else {
		r = -ENOIOCTLCMD;
	}
@@ -648,13 +653,14 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
	unsigned char nci_reset_rsp[6];
	unsigned char init_rsp_len = 0;
	unsigned int enable_gpio = nqx_dev->en_gpio;

	/* making sure that the NFCC starts in a clean state. */
	gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
	/* hardware dependent delay */
	msleep(20);
	usleep_range(10000, 10100);
	gpio_set_value(enable_gpio, 1);/* HPD : Enable*/
	/* hardware dependent delay */
	msleep(20);
	usleep_range(10000, 10100);

	/* send NCI CORE RESET CMD with Keep Config parameters */
	ret = i2c_master_send(client, raw_nci_reset_cmd,
@@ -670,21 +676,17 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
	/* Read Response of RESET command */
	ret = i2c_master_recv(client, nci_reset_rsp,
		sizeof(nci_reset_rsp));
	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]);
	if (ret < 0) {
		dev_err(&client->dev,
		"%s: - i2c_master_recv Error\n", __func__);
		goto err_nfcc_hw_check;
	}
	ret = i2c_master_send(client, raw_nci_init_cmd,
	ret = nqx_standby_write(nqx_dev, raw_nci_init_cmd,
				sizeof(raw_nci_init_cmd));
	if (ret < 0) {
		dev_err(&client->dev,
		"%s: - i2c_master_send Error\n", __func__);
		goto err_nfcc_hw_check;
		goto err_nfcc_core_init_fail;
	}
	/* hardware dependent delay */
	msleep(30);
@@ -694,7 +696,7 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
	if (ret < 0) {
		dev_err(&client->dev,
		"%s: - i2c_master_recv Error\n", __func__);
		goto err_nfcc_hw_check;
		goto err_nfcc_core_init_fail;
	}
	init_rsp_len = 2 + nci_init_rsp[2]; /*payload + len*/
	if (init_rsp_len > PAYLOAD_HEADER_LENGTH) {
@@ -707,6 +709,11 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
		nqx_dev->nqx_info.info.fw_minor =
				nci_init_rsp[init_rsp_len];
	}
	dev_dbg(&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]);

	dev_dbg(&nqx_dev->client->dev, "NQ NFCC chip_type = %x\n",
		nqx_dev->nqx_info.info.chip_type);
	dev_dbg(&nqx_dev->client->dev, "NQ fw version = %x.%x.%x\n",
@@ -746,6 +753,12 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
	ret = 0;
	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,