drivers: nfc: Import Xiaomi changes

* From dagu-s-oss

Change-Id: I47d46f534cd51f9a050c4af6875f58b1512e17a0
This commit is contained in:
Sebastiano Barezzi
2022-11-15 16:31:06 +01:00
committed by Sebastiano Barezzi
parent f6bf3bf5a3
commit c63fb6366f

View File

@@ -21,7 +21,9 @@
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#include <linux/compat.h> #include <linux/compat.h>
#endif #endif
#ifdef NQ_READ_INT
#include <linux/jiffies.h> #include <linux/jiffies.h>
#endif
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
struct nqx_platform_data { struct nqx_platform_data {
@@ -1069,6 +1071,7 @@ static const struct file_operations nfc_dev_fops = {
* Return: error codes in case of any failure, * Return: error codes in case of any failure,
* number of bytes read otherwise * number of bytes read otherwise
*/ */
#if 0
static int get_nfcc_hw_info(struct i2c_client *client, static int get_nfcc_hw_info(struct i2c_client *client,
struct nqx_dev *nqx_dev, char nci_reset_rsp_payload_len) struct nqx_dev *nqx_dev, char nci_reset_rsp_payload_len)
{ {
@@ -1178,6 +1181,7 @@ static int get_nfcc_hw_info(struct i2c_client *client,
return ret; return ret;
} }
#endif
/* Check for availability of NQ_ NFC controller hardware */ /* Check for availability of NQ_ NFC controller hardware */
static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
@@ -1185,9 +1189,13 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
int ret = 0; int ret = 0;
int gpio_retry_count = 0;
int send_retry_count = 0;
unsigned char reset_ntf_len = 0;
unsigned int enable_gpio = nqx_dev->en_gpio; unsigned int enable_gpio = nqx_dev->en_gpio;
char *nci_reset_cmd = NULL; char *nci_reset_cmd = NULL;
char *nci_reset_rsp = NULL; char *nci_reset_rsp = NULL;
char *nci_reset_ntf = NULL;
char *nci_get_version_cmd = NULL; char *nci_get_version_cmd = NULL;
char *nci_get_version_rsp = NULL; char *nci_get_version_rsp = NULL;
@@ -1203,6 +1211,13 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
ret = -ENOMEM; ret = -ENOMEM;
goto done; goto done;
} }
nci_reset_ntf = kzalloc(NCI_RESET_NTF_LEN + 1, GFP_DMA | GFP_KERNEL);
if (!nci_reset_ntf) {
ret = -ENOMEM;
goto done;
}
nci_get_version_cmd = kzalloc(NCI_GET_VERSION_CMD_LEN + 1, nci_get_version_cmd = kzalloc(NCI_GET_VERSION_CMD_LEN + 1,
GFP_DMA | GFP_KERNEL); GFP_DMA | GFP_KERNEL);
if (!nci_get_version_cmd) { if (!nci_get_version_cmd) {
@@ -1217,10 +1232,13 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
goto done; goto done;
} }
reset_enable_gpio:
/* making sure that the NFCC starts in a clean state. */ /* making sure that the NFCC starts in a clean state. */
#ifdef NQ_READ_INT
gpio_set_value(enable_gpio, 1);/* HPD : Enable*/ gpio_set_value(enable_gpio, 1);/* HPD : Enable*/
/* hardware dependent delay */ /* hardware dependent delay */
usleep_range(10000, 10100); usleep_range(10000, 10100);
#endif
gpio_set_value(enable_gpio, 0);/* ULPM: Disable */ gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
/* hardware dependent delay */ /* hardware dependent delay */
usleep_range(10000, 10100); usleep_range(10000, 10100);
@@ -1238,6 +1256,17 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
dev_err(&client->dev, dev_err(&client->dev,
"%s: - i2c_master_send core reset Error\n", __func__); "%s: - i2c_master_send core reset Error\n", __func__);
if (send_retry_count < MAX_RETRY_COUNT) {
send_retry_count += 1;
goto reset_enable_gpio;
} else {
nqx_dev->nqx_info.info.chip_type = NFCC_SN100_A;
nqx_dev->nqx_info.info.rom_version = 0;
nqx_dev->nqx_info.info.fw_minor = 0;
nqx_dev->nqx_info.info.fw_major = 0;
goto err_nfcc_reset_failed;
}
if (gpio_is_valid(nqx_dev->firm_gpio)) { if (gpio_is_valid(nqx_dev->firm_gpio)) {
gpio_set_value(nqx_dev->firm_gpio, 1); gpio_set_value(nqx_dev->firm_gpio, 1);
usleep_range(10000, 10100); usleep_range(10000, 10100);
@@ -1287,37 +1316,60 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
goto err_nfcc_reset_failed; goto err_nfcc_reset_failed;
} }
/* hardware dependent delay */
msleep(60);
#ifdef NQ_READ_INT
ret = is_data_available_for_read(nqx_dev); ret = is_data_available_for_read(nqx_dev);
if (ret <= 0) { if (ret <= 0) {
nqx_disable_irq(nqx_dev); nqx_disable_irq(nqx_dev);
goto err_nfcc_hw_check; goto err_nfcc_hw_check;
} }
#endif
/* Read Header of RESET command */ /* Read Response of RESET command */
ret = i2c_master_recv(client, nci_reset_rsp, NCI_HEADER_LEN); ret = i2c_master_recv(client, nci_reset_rsp, NCI_RESET_RSP_LEN);
if (ret != NCI_HEADER_LEN) { if (ret < 0) {
dev_dbg(&client->dev, dev_dbg(&client->dev,
"%s: - i2c_master_recv get RESET rsp header Error\n", __func__); "%s: - i2c_master_recv get RESET rsp header Error\n", __func__);
goto err_nfcc_hw_check; gpio_retry_count = gpio_retry_count + 1;
} if (gpio_retry_count < MAX_RETRY_COUNT)
ret = i2c_master_recv(client, &nci_reset_rsp[NCI_PAYLOAD_START_INDEX], goto reset_enable_gpio;
nci_reset_rsp[NCI_PAYLOAD_LENGTH_INDEX]);
if (ret != nci_reset_rsp[NCI_PAYLOAD_LENGTH_INDEX]) {
dev_dbg(&client->dev,
"%s: - i2c_master_recv get RESET rsp data Error\n", __func__);
goto err_nfcc_hw_check; goto err_nfcc_hw_check;
} }
/* Retrieve NFCC HW info */ /* hardware dependent delay */
ret = get_nfcc_hw_info(client, nqx_dev, msleep(30);
nci_reset_rsp[NCI_PAYLOAD_LENGTH_INDEX]);
#ifdef NQ_READ_INT
ret = is_data_available_for_read(nqx_dev);
if (ret <= 0) {
nqx_disable_irq(nqx_dev);
goto err_nfcc_hw_check;
}
#endif
/* Read Notification of RESET command */
ret = i2c_master_recv(client, nci_reset_ntf, NCI_RESET_NTF_LEN);
if (ret < 0) { if (ret < 0) {
dev_dbg(&client->dev, dev_dbg(&client->dev,
"%s: - Error in getting NFCC HW info\n", __func__); "%s: - Error in getting NFCC HW info\n", __func__);
goto err_nfcc_hw_check; goto err_nfcc_hw_check;
} }
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_reset_ntf[reset_ntf_len - 3];
nqx_dev->nqx_info.info.rom_version =
nci_reset_ntf[reset_ntf_len - 2];
nqx_dev->nqx_info.info.fw_major =
nci_reset_ntf[reset_ntf_len - 1];
nqx_dev->nqx_info.info.fw_minor =
nci_reset_ntf[reset_ntf_len];
}
dev_dbg(&client->dev, dev_dbg(&client->dev,
"%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n", "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
@@ -1367,6 +1419,7 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
done: done:
kfree(nci_reset_rsp); kfree(nci_reset_rsp);
kfree(nci_reset_ntf);
kfree(nci_reset_cmd); kfree(nci_reset_cmd);
kfree(nci_get_version_cmd); kfree(nci_get_version_cmd);
kfree(nci_get_version_rsp); kfree(nci_get_version_rsp);