Merge "NFC: Detection of NQ chip set and firmware version"

This commit is contained in:
Linux Build Service Account 2016-11-10 15:14:34 -08:00 committed by Gerrit - the friendly Code Review server
commit 68776a1e98
6 changed files with 132 additions and 11 deletions

View file

@ -53,6 +53,7 @@ struct nqx_dev {
struct mutex read_mutex; struct mutex read_mutex;
struct i2c_client *client; struct i2c_client *client;
struct miscdevice nqx_device; struct miscdevice nqx_device;
union nqx_uinfo nqx_info;
/* NFC GPIO variables */ /* NFC GPIO variables */
unsigned int irq_gpio; unsigned int irq_gpio;
unsigned int en_gpio; unsigned int en_gpio;
@ -467,6 +468,25 @@ int nfc_ioctl_core_reset_ntf(struct file *filp)
return nqx_dev->core_reset_ntf; return nqx_dev->core_reset_ntf;
} }
/*
* Inside nfc_ioctl_nfcc_info
*
* @brief nfc_ioctl_nfcc_info
*
* Check the NQ Chipset and firmware version details
*/
unsigned int nfc_ioctl_nfcc_info(struct file *filp, unsigned long arg)
{
unsigned int r = 0;
struct nqx_dev *nqx_dev = filp->private_data;
r = nqx_dev->nqx_info.i;
dev_dbg(&nqx_dev->client->dev,
"nqx nfc : nfc_ioctl_nfcc_info r = %d\n", r);
return r;
}
static long nfc_ioctl(struct file *pfile, unsigned int cmd, static long nfc_ioctl(struct file *pfile, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
@ -489,6 +509,9 @@ static long nfc_ioctl(struct file *pfile, unsigned int cmd,
case NFCC_INITIAL_CORE_RESET_NTF: case NFCC_INITIAL_CORE_RESET_NTF:
r = nfc_ioctl_core_reset_ntf(pfile); r = nfc_ioctl_core_reset_ntf(pfile);
break; break;
case NFCC_GET_INFO:
r = nfc_ioctl_nfcc_info(pfile, arg);
break;
default: default:
r = -ENOIOCTLCMD; r = -ENOIOCTLCMD;
} }
@ -508,13 +531,16 @@ static const struct file_operations nfc_dev_fops = {
}; };
/* 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, unsigned int enable_gpio) static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev)
{ {
int ret = 0; int ret = 0;
unsigned char raw_nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x00}; unsigned char raw_nci_reset_cmd[] = {0x20, 0x00, 0x01, 0x00};
unsigned char raw_nci_init_cmd[] = {0x20, 0x01, 0x00};
unsigned char nci_init_rsp[28];
unsigned char nci_reset_rsp[6]; 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. */ /* making sure that the NFCC starts in a clean state. */
gpio_set_value(enable_gpio, 0);/* ULPM: Disable */ gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
/* hardware dependent delay */ /* hardware dependent delay */
@ -536,16 +562,75 @@ static int nfcc_hw_check(struct i2c_client *client, unsigned int enable_gpio)
/* Read Response of RESET command */ /* Read Response of RESET command */
ret = i2c_master_recv(client, nci_reset_rsp, ret = i2c_master_recv(client, nci_reset_rsp,
sizeof(nci_reset_rsp)); sizeof(nci_reset_rsp));
dev_err(&client->dev, dev_err(&client->dev,
"%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n", "%s: - nq - reset cmd answer : NfcNciRx %x %x %x\n",
__func__, nci_reset_rsp[0], __func__, nci_reset_rsp[0],
nci_reset_rsp[1], nci_reset_rsp[2]); nci_reset_rsp[1], nci_reset_rsp[2]);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, dev_err(&client->dev,
"%s: - i2c_master_recv Error\n", __func__); "%s: - i2c_master_recv Error\n", __func__);
goto err_nfcc_hw_check; goto err_nfcc_hw_check;
} }
ret = i2c_master_send(client, 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;
}
/* hardware dependent delay */
msleep(30);
/* Read Response of INIT command */
ret = i2c_master_recv(client, nci_init_rsp,
sizeof(nci_init_rsp));
if (ret < 0) {
dev_err(&client->dev,
"%s: - i2c_master_recv Error\n", __func__);
goto err_nfcc_hw_check;
}
init_rsp_len = 2 + nci_init_rsp[2]; /*payload + len*/
if (init_rsp_len > PAYLOAD_HEADER_LENGTH) {
nqx_dev->nqx_info.info.chip_type =
nci_init_rsp[init_rsp_len - 3];
nqx_dev->nqx_info.info.rom_version =
nci_init_rsp[init_rsp_len - 2];
nqx_dev->nqx_info.info.fw_major =
nci_init_rsp[init_rsp_len - 1];
nqx_dev->nqx_info.info.fw_minor =
nci_init_rsp[init_rsp_len];
}
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",
nqx_dev->nqx_info.info.rom_version,
nqx_dev->nqx_info.info.fw_major,
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__);
break;
case NFCC_NQ_330:
dev_dbg(&client->dev,
"%s: ## NFCC == NQ330 ##\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 */ gpio_set_value(enable_gpio, 0);/* ULPM: Disable */
ret = 0; ret = 0;
goto done; goto done;
@ -566,9 +651,7 @@ done:
static int nqx_clock_select(struct nqx_dev *nqx_dev) static int nqx_clock_select(struct nqx_dev *nqx_dev)
{ {
int r = 0; int r = 0;
nqx_dev->s_clk = clk_get(&nqx_dev->client->dev, "ref_clk");
nqx_dev->s_clk =
clk_get(&nqx_dev->client->dev, "ref_clk");
if (nqx_dev->s_clk == NULL) if (nqx_dev->s_clk == NULL)
goto err_clk; goto err_clk;
@ -867,8 +950,7 @@ static int nqx_probe(struct i2c_client *client,
* present before attempting further hardware initialisation. * present before attempting further hardware initialisation.
* *
*/ */
r = nfcc_hw_check(client, nqx_dev);
r = nfcc_hw_check(client, platform_data->en_gpio);
if (r) { if (r) {
/* make sure NFCC is not enabled */ /* make sure NFCC is not enabled */
gpio_set_value(platform_data->en_gpio, 0); gpio_set_value(platform_data->en_gpio, 0);

View file

@ -22,6 +22,7 @@
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/nfcinfo.h>
#define NFC_SET_PWR _IOW(0xE9, 0x01, unsigned int) #define NFC_SET_PWR _IOW(0xE9, 0x01, unsigned int)
#define ESE_SET_PWR _IOW(0xE9, 0x02, unsigned int) #define ESE_SET_PWR _IOW(0xE9, 0x02, unsigned int)
@ -42,4 +43,12 @@ enum nfcc_initial_core_reset_ntf {
DEFAULT_INITIAL_CORE_RESET_NTF, /*2*/ DEFAULT_INITIAL_CORE_RESET_NTF, /*2*/
}; };
enum nfcc_chip_variant {
NFCC_NQ_210 = 0x48, /**< NFCC NQ210 */
NFCC_NQ_220 = 0x58, /**< NFCC NQ220 */
NFCC_NQ_310 = 0x40, /**< NFCC NQ310 */
NFCC_NQ_330 = 0x51, /**< NFCC NQ330 */
NFCC_NOT_SUPPORTED = 0xFF /**< NFCC is not supported */
};
#endif #endif

6
include/linux/nfcinfo.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef _NFCINFO_H
#define _NFCINFO_H
#include <uapi/linux/nfc/nfcinfo.h>
#endif

View file

@ -23,6 +23,7 @@ header-y += netfilter_ipv6/
header-y += usb/ header-y += usb/
header-y += wimax/ header-y += wimax/
header-y += mfd/ header-y += mfd/
header-y += nfc/
genhdr-y += version.h genhdr-y += version.h

View file

@ -0,0 +1,2 @@
#UAPI export list
header-y += nfcinfo.h

View file

@ -0,0 +1,21 @@
#ifndef _UAPI_NFCINFO_H_
#define _UAPI_NFCINFO_H_
#include <linux/ioctl.h>
#define NFCC_MAGIC 0xE9
#define NFCC_GET_INFO _IOW(NFCC_MAGIC, 0x09, unsigned int)
struct nqx_devinfo {
unsigned char chip_type;
unsigned char rom_version;
unsigned char fw_major;
unsigned char fw_minor;
};
union nqx_uinfo {
unsigned int i;
struct nqx_devinfo info;
};
#endif