Loading drivers/nfc/nfc-nci.c +94 −56 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ MODULE_DEVICE_TABLE(of, msm_match_table); #define CORE_RESET_RSP_GID (0x60) #define CORE_RESET_OID (0x00) #define CORE_RST_NTF_LENGTH (0x02) #define WAKE_TIMEOUT (10000) static void clk_req_update(struct work_struct *work); Loading Loading @@ -342,10 +343,10 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, /* Read the header */ ret = i2c_master_recv(qca199x_dev->client, len, PAYLOAD_HEADER_LENGTH); /* We ignore all packets of length PAYLOAD_HEADER_LENGTH or less (i.e <=3). In this case return a total length of ZERO. So ALL PACKETS MUST HAVE A PAYLOAD. If ret < 0 then this is an error code. * We ignore all packets of length PAYLOAD_HEADER_LENGTH * or less (i.e <=3). In this case return a total length * of ZERO. So ALL PACKETS MUST HAVE A PAYLOAD. * If ret < 0 then this is an error code. */ if (ret != PAYLOAD_HEADER_LENGTH) { if (ret < 0) Loading Loading @@ -385,13 +386,13 @@ done: } /* Local routine to read from nfcc buffer. This is called to clear any pending receive messages in the nfcc's read buffer, which may be there following a POR. In this way, the upper layers (Device Transport) will associate the next rsp/ntf nci message with the next nci command to the nfcc. Otherwise, the DT may interpret a ntf from the nfcc as being from the nci core reset command when in fact it was already present in the nfcc read buffer following a POR. * Local routine to read from nfcc buffer. This is called to clear any * pending receive messages in the nfcc's read buffer, which may be there * following a POR. In this way, the upper layers (Device Transport) will * associate the next rsp/ntf nci message with the next nci command to the * nfcc. Otherwise, the DT may interpret a ntf from the nfcc as being from * the nci core reset command when in fact it was already present in the * nfcc read buffer following a POR. */ int nfcc_read_buff_svc(struct qca199x_dev *qca199x_dev) Loading Loading @@ -448,10 +449,10 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, return -EFAULT; } /* A catch for when the DT is sending the initial NCI write following a hardware POR. In this case we should clear any pending messages in nfcc buffer and open the interrupt gate for new messages coming from the nfcc. * A catch for when the DT is sending the initial NCI write * following a hardware POR. In this case we should clear any * pending messages in nfcc buffer and open the interrupt gate * for new messages coming from the nfcc. */ if ((qca199x_dev->sent_first_nci_write == false) && (qca199x_dev->irq_enabled == false)) { Loading Loading @@ -614,9 +615,9 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, msleep(20); } else if (arg == 1) { /* We are attempting a hardware reset so let us disable interrupts to avoid spurious notifications to upper layers. * We are attempting a hardware reset so let us disable * interrupts to avoid spurious notifications to upper * layers. */ qca199x_disable_irq(qca199x_dev); /* Deselection of clock */ Loading @@ -624,10 +625,10 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, if (r < 0) goto err_req; /* Also, set flag for initial NCI write following reset as may wish to do some house keeping. Ensure no pending messages in NFCC buffers which may be wrongly construed as response to initial message * Also, set flag for initial NCI write following resetas * may wish to do some house keeping. Ensure no pending * messages in NFCC buffers which may be wrongly * construed as response to initial message */ qca199x_dev->sent_first_nci_write = false; gpio_set_value(qca199x_dev->dis_gpio, 0); Loading Loading @@ -734,9 +735,11 @@ int nfc_ioctl_nfcc_version(struct file *filp, unsigned int cmd, unsigned long arg) { int r = 0; int time_taken = 0; unsigned short slave_addr = 0xE; unsigned short curr_addr; unsigned char raw_nci_wake[] = {0x10, 0x0F}; unsigned char raw_nci_read; unsigned char raw_chip_version_addr = 0x00; unsigned char raw_chip_rev_id_addr = 0x9C; unsigned char raw_chip_version = 0xFF; Loading @@ -754,39 +757,73 @@ int nfc_ioctl_nfcc_version(struct file *filp, unsigned int cmd, qca199x_dev->client->addr = slave_addr; r = nfc_i2c_write(qca199x_dev->client, &raw_nci_wake[0], sizeof(raw_nci_wake)); r = sizeof(raw_nci_wake); if (r != sizeof(raw_nci_wake)) goto invalid_wake_up; dev_err(&qca199x_dev->client->dev, "nfc_ioctl_nfcc_version : failed to send wake command\n"); /* * After placing the NFCC to sleep by a PROP * SLEEP NCI msg (2F 03) and we need to wake * it back up to obtain some information (by * setting the wake bit).We need to determine * when it has in actual fact woken before we * can read the required data. We do that by * reading back & testing if that wake bit has * been cleared. */ do { r = i2c_master_recv(qca199x_dev->client, &raw_nci_read, sizeof(raw_nci_read)); udelay(1); time_taken++; } while ((r == 1) && (raw_nci_read & NCI_WAKE) && (time_taken < WAKE_TIMEOUT)); if (time_taken < WAKE_TIMEOUT) qca199x_dev->state = NFCC_STATE_NORMAL_WAKE; else dev_err(&qca199x_dev->client->dev, "nfc_ioctl_nfcc_version : TIMED OUT to get WAKEUP bit\n"); if (r != 1) { /* * r < 0 indicates an error, maybe chip isn't * up yet.What should we do??? r = 0 indicates * nothing read, maybe chip isn't up yet. (should * not happen) r > 1 indicates too many bytes read, * maybe ?(should not happen) */ dev_err(&qca199x_dev->client->dev, "nfc_ioctl_nfcc_version : i2c error %d\n", r); } /* sleep to ensure the NFCC has time to wake up */ usleep(100); if (arg == 0) { r = nfc_i2c_write(qca199x_dev->client, &raw_chip_version_addr, 1); if (r < 0) goto invalid_wr; usleep(10); r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1); /* Restore original NFCC slave I2C address */ qca199x_dev->client->addr = curr_addr; } else if (arg == 1) { r = nfc_i2c_write(qca199x_dev->client, &raw_chip_rev_id_addr, 1); if (r < 0) goto invalid_wr; usleep(20); r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1); } else { /* Restore original NFCC slave I2C address */ qca199x_dev->client->addr = curr_addr; return -EINVAL; } return raw_chip_version; invalid_wake_up: raw_chip_version = 0xFE; invalid_wr: raw_chip_version = 0xFF; if (r < 0) { /* Restore original NFCC slave I2C address */ qca199x_dev->client->addr = curr_addr; dev_err(&qca199x_dev->client->dev, "\nNFCC_INVALID_CHIP_VERSION = %d\n", raw_chip_version); "NFCC_INVALID_CHIP_VERSION : i2c write fail\n"); return -EIO; } usleep(10); r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1); /* Restore original NFCC slave I2C address */ qca199x_dev->client->addr = curr_addr; return raw_chip_version; } Loading Loading @@ -1050,9 +1087,9 @@ static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr) client->addr = NCI_I2C_SLAVE; /* Start with small delay and then we will poll until we get a core reset notification - This is time for chip & NFCC controller to come-up. * Start with small delay and then we will poll until we * get a core reset notification - This is time for chip * & NFCC controller to come-up. */ usleep(1000); /* 1 ms */ Loading Loading @@ -1438,7 +1475,8 @@ static int qca199x_probe(struct i2c_client *client, } logging_level = 0; /* request irq. The irq is set whenever the chip has data available /* * request irq. The irq is set whenever the chip has data available * for reading. It is cleared when all data has been read. */ device_mode.handle_flavour = UNSOLICITED_MODE; Loading Loading
drivers/nfc/nfc-nci.c +94 −56 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ MODULE_DEVICE_TABLE(of, msm_match_table); #define CORE_RESET_RSP_GID (0x60) #define CORE_RESET_OID (0x00) #define CORE_RST_NTF_LENGTH (0x02) #define WAKE_TIMEOUT (10000) static void clk_req_update(struct work_struct *work); Loading Loading @@ -342,10 +343,10 @@ static ssize_t nfc_read(struct file *filp, char __user *buf, /* Read the header */ ret = i2c_master_recv(qca199x_dev->client, len, PAYLOAD_HEADER_LENGTH); /* We ignore all packets of length PAYLOAD_HEADER_LENGTH or less (i.e <=3). In this case return a total length of ZERO. So ALL PACKETS MUST HAVE A PAYLOAD. If ret < 0 then this is an error code. * We ignore all packets of length PAYLOAD_HEADER_LENGTH * or less (i.e <=3). In this case return a total length * of ZERO. So ALL PACKETS MUST HAVE A PAYLOAD. * If ret < 0 then this is an error code. */ if (ret != PAYLOAD_HEADER_LENGTH) { if (ret < 0) Loading Loading @@ -385,13 +386,13 @@ done: } /* Local routine to read from nfcc buffer. This is called to clear any pending receive messages in the nfcc's read buffer, which may be there following a POR. In this way, the upper layers (Device Transport) will associate the next rsp/ntf nci message with the next nci command to the nfcc. Otherwise, the DT may interpret a ntf from the nfcc as being from the nci core reset command when in fact it was already present in the nfcc read buffer following a POR. * Local routine to read from nfcc buffer. This is called to clear any * pending receive messages in the nfcc's read buffer, which may be there * following a POR. In this way, the upper layers (Device Transport) will * associate the next rsp/ntf nci message with the next nci command to the * nfcc. Otherwise, the DT may interpret a ntf from the nfcc as being from * the nci core reset command when in fact it was already present in the * nfcc read buffer following a POR. */ int nfcc_read_buff_svc(struct qca199x_dev *qca199x_dev) Loading Loading @@ -448,10 +449,10 @@ static ssize_t nfc_write(struct file *filp, const char __user *buf, return -EFAULT; } /* A catch for when the DT is sending the initial NCI write following a hardware POR. In this case we should clear any pending messages in nfcc buffer and open the interrupt gate for new messages coming from the nfcc. * A catch for when the DT is sending the initial NCI write * following a hardware POR. In this case we should clear any * pending messages in nfcc buffer and open the interrupt gate * for new messages coming from the nfcc. */ if ((qca199x_dev->sent_first_nci_write == false) && (qca199x_dev->irq_enabled == false)) { Loading Loading @@ -614,9 +615,9 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, msleep(20); } else if (arg == 1) { /* We are attempting a hardware reset so let us disable interrupts to avoid spurious notifications to upper layers. * We are attempting a hardware reset so let us disable * interrupts to avoid spurious notifications to upper * layers. */ qca199x_disable_irq(qca199x_dev); /* Deselection of clock */ Loading @@ -624,10 +625,10 @@ int nfc_ioctl_power_states(struct file *filp, unsigned int cmd, if (r < 0) goto err_req; /* Also, set flag for initial NCI write following reset as may wish to do some house keeping. Ensure no pending messages in NFCC buffers which may be wrongly construed as response to initial message * Also, set flag for initial NCI write following resetas * may wish to do some house keeping. Ensure no pending * messages in NFCC buffers which may be wrongly * construed as response to initial message */ qca199x_dev->sent_first_nci_write = false; gpio_set_value(qca199x_dev->dis_gpio, 0); Loading Loading @@ -734,9 +735,11 @@ int nfc_ioctl_nfcc_version(struct file *filp, unsigned int cmd, unsigned long arg) { int r = 0; int time_taken = 0; unsigned short slave_addr = 0xE; unsigned short curr_addr; unsigned char raw_nci_wake[] = {0x10, 0x0F}; unsigned char raw_nci_read; unsigned char raw_chip_version_addr = 0x00; unsigned char raw_chip_rev_id_addr = 0x9C; unsigned char raw_chip_version = 0xFF; Loading @@ -754,39 +757,73 @@ int nfc_ioctl_nfcc_version(struct file *filp, unsigned int cmd, qca199x_dev->client->addr = slave_addr; r = nfc_i2c_write(qca199x_dev->client, &raw_nci_wake[0], sizeof(raw_nci_wake)); r = sizeof(raw_nci_wake); if (r != sizeof(raw_nci_wake)) goto invalid_wake_up; dev_err(&qca199x_dev->client->dev, "nfc_ioctl_nfcc_version : failed to send wake command\n"); /* * After placing the NFCC to sleep by a PROP * SLEEP NCI msg (2F 03) and we need to wake * it back up to obtain some information (by * setting the wake bit).We need to determine * when it has in actual fact woken before we * can read the required data. We do that by * reading back & testing if that wake bit has * been cleared. */ do { r = i2c_master_recv(qca199x_dev->client, &raw_nci_read, sizeof(raw_nci_read)); udelay(1); time_taken++; } while ((r == 1) && (raw_nci_read & NCI_WAKE) && (time_taken < WAKE_TIMEOUT)); if (time_taken < WAKE_TIMEOUT) qca199x_dev->state = NFCC_STATE_NORMAL_WAKE; else dev_err(&qca199x_dev->client->dev, "nfc_ioctl_nfcc_version : TIMED OUT to get WAKEUP bit\n"); if (r != 1) { /* * r < 0 indicates an error, maybe chip isn't * up yet.What should we do??? r = 0 indicates * nothing read, maybe chip isn't up yet. (should * not happen) r > 1 indicates too many bytes read, * maybe ?(should not happen) */ dev_err(&qca199x_dev->client->dev, "nfc_ioctl_nfcc_version : i2c error %d\n", r); } /* sleep to ensure the NFCC has time to wake up */ usleep(100); if (arg == 0) { r = nfc_i2c_write(qca199x_dev->client, &raw_chip_version_addr, 1); if (r < 0) goto invalid_wr; usleep(10); r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1); /* Restore original NFCC slave I2C address */ qca199x_dev->client->addr = curr_addr; } else if (arg == 1) { r = nfc_i2c_write(qca199x_dev->client, &raw_chip_rev_id_addr, 1); if (r < 0) goto invalid_wr; usleep(20); r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1); } else { /* Restore original NFCC slave I2C address */ qca199x_dev->client->addr = curr_addr; return -EINVAL; } return raw_chip_version; invalid_wake_up: raw_chip_version = 0xFE; invalid_wr: raw_chip_version = 0xFF; if (r < 0) { /* Restore original NFCC slave I2C address */ qca199x_dev->client->addr = curr_addr; dev_err(&qca199x_dev->client->dev, "\nNFCC_INVALID_CHIP_VERSION = %d\n", raw_chip_version); "NFCC_INVALID_CHIP_VERSION : i2c write fail\n"); return -EIO; } usleep(10); r = i2c_master_recv(qca199x_dev->client, &raw_chip_version, 1); /* Restore original NFCC slave I2C address */ qca199x_dev->client->addr = curr_addr; return raw_chip_version; } Loading Loading @@ -1050,9 +1087,9 @@ static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr) client->addr = NCI_I2C_SLAVE; /* Start with small delay and then we will poll until we get a core reset notification - This is time for chip & NFCC controller to come-up. * Start with small delay and then we will poll until we * get a core reset notification - This is time for chip * & NFCC controller to come-up. */ usleep(1000); /* 1 ms */ Loading Loading @@ -1438,7 +1475,8 @@ static int qca199x_probe(struct i2c_client *client, } logging_level = 0; /* request irq. The irq is set whenever the chip has data available /* * request irq. The irq is set whenever the chip has data available * for reading. It is cleared when all data has been read. */ device_mode.handle_flavour = UNSOLICITED_MODE; Loading