static void nfcmrvl_bulk_complete(struct urb *urb) { struct nfcmrvl_usb_drv_data *drv_data = urb->context; int err; dev_dbg(&drv_data->udev->dev, "urb %p status %d count %d", urb, urb->status, urb->actual_length); if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags)) return; if (!urb->status) { if (nfcmrvl_nci_recv_frame(drv_data->priv, urb->transfer_buffer, urb->actual_length) < 0) nfc_err(&drv_data->udev->dev, "corrupted Rx packet"); } if (!test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags)) return; usb_anchor_urb(urb, &drv_data->bulk_anchor); usb_mark_last_busy(drv_data->udev); err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { /* -EPERM: urb is being killed; * -ENODEV: device got disconnected */ if (err != -EPERM && err != -ENODEV) nfc_err(&drv_data->udev->dev, "urb %p failed to resubmit (%d)", urb, -err); usb_unanchor_urb(urb); } }
static int nxp_nci_i2c_parse_devtree(struct i2c_client *client) { struct nxp_nci_i2c_phy *phy = i2c_get_clientdata(client); struct device_node *pp; int r; pp = client->dev.of_node; if (!pp) return -ENODEV; r = of_get_named_gpio(pp, "enable-gpios", 0); if (r == -EPROBE_DEFER) r = of_get_named_gpio(pp, "enable-gpios", 0); if (r < 0) { nfc_err(&client->dev, "Failed to get EN gpio, error: %d\n", r); return r; } phy->gpio_en = r; r = of_get_named_gpio(pp, "firmware-gpios", 0); if (r == -EPROBE_DEFER) r = of_get_named_gpio(pp, "firmware-gpios", 0); if (r < 0) { nfc_err(&client->dev, "Failed to get FW gpio, error: %d\n", r); return r; } phy->gpio_fw = r; return 0; }
static irqreturn_t nfcmrvl_i2c_int_irq_thread_fn(int irq, void *drv_data_ptr) { struct nfcmrvl_i2c_drv_data *drv_data = drv_data_ptr; struct sk_buff *skb = NULL; int ret; if (!drv_data->priv) return IRQ_HANDLED; if (test_bit(NFCMRVL_PHY_ERROR, &drv_data->priv->flags)) return IRQ_HANDLED; ret = nfcmrvl_i2c_read(drv_data, &skb); switch (ret) { case -EREMOTEIO: set_bit(NFCMRVL_PHY_ERROR, &drv_data->priv->flags); break; case -ENOMEM: case -EBADMSG: nfc_err(&drv_data->i2c->dev, "read failed %d\n", ret); break; default: if (nfcmrvl_nci_recv_frame(drv_data->priv, skb) < 0) nfc_err(&drv_data->i2c->dev, "corrupted RX packet\n"); break; } return IRQ_HANDLED; }
static int nxp_nci_i2c_write(void *phy_id, struct sk_buff *skb) { int r; struct nxp_nci_i2c_phy *phy = phy_id; struct i2c_client *client = phy->i2c_dev; if (phy->hard_fault != 0) return phy->hard_fault; r = i2c_master_send(client, skb->data, skb->len); if (r < 0) { /* Retry, chip was in standby */ msleep(110); r = i2c_master_send(client, skb->data, skb->len); } if (r < 0) { nfc_err(&client->dev, "Error %d on I2C send\n", r); } else if (r != skb->len) { nfc_err(&client->dev, "Invalid length sent: %u (expected %u)\n", r, skb->len); r = -EREMOTEIO; } else { /* Success but return 0 and not number of bytes */ r = 0; } return r; }
static int st_nci_i2c_of_request_resources(struct i2c_client *client) { struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); struct device_node *pp; int gpio; int r; pp = client->dev.of_node; if (!pp) return -ENODEV; /* Get GPIO from device tree */ gpio = of_get_named_gpio(pp, "reset-gpios", 0); if (gpio < 0) { nfc_err(&client->dev, "Failed to retrieve reset-gpios from device tree\n"); return gpio; } /* GPIO request and configuration */ r = devm_gpio_request_one(&client->dev, gpio, GPIOF_OUT_INIT_HIGH, "clf_reset"); if (r) { nfc_err(&client->dev, "Failed to request reset pin\n"); return r; } phy->gpio_reset = gpio; phy->irq_polarity = irq_get_trigger_type(client->irq); return 0; }
static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, __u32 protocol) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); nfc_dbg("entry, target_idx %d, protocol 0x%x", target_idx, protocol); if (!test_bit(NCI_POLL_ACTIVE, &ndev->flags)) { nfc_err("there is no available target to activate"); return -EINVAL; } if (ndev->target_active_prot) { nfc_err("there is already an active target"); return -EBUSY; } if (!(ndev->target_available_prots & (1 << protocol))) { nfc_err("target does not support the requested protocol 0x%x", protocol); return -EINVAL; } ndev->target_active_prot = protocol; ndev->target_available_prots = 0; return 0; }
/* -- Default recv_buf handler -- * * This handler supposes that NCI frames are sent over UART link without any * framing. It reads NCI header, retrieve the packet size and once all packet * bytes are received it passes it to nci_uart driver for processing. */ static int nci_uart_default_recv_buf(struct nci_uart *nu, const u8 *data, char *flags, int count) { int chunk_len; if (!nu->ndev) { nfc_err(nu->tty->dev, "receive data from tty but no NCI dev is attached yet, drop buffer\n"); return 0; } /* Decode all incoming data in packets * and enqueue then for processing. */ while (count > 0) { /* If this is the first data of a packet, allocate a buffer */ if (!nu->rx_skb) { nu->rx_packet_len = -1; nu->rx_skb = nci_skb_alloc(nu->ndev, NCI_MAX_PACKET_SIZE, GFP_KERNEL); if (!nu->rx_skb) return -ENOMEM; } /* Eat byte after byte till full packet header is received */ if (nu->rx_skb->len < NCI_CTRL_HDR_SIZE) { *skb_put(nu->rx_skb, 1) = *data++; --count; continue; } /* Header was received but packet len was not read */ if (nu->rx_packet_len < 0) nu->rx_packet_len = NCI_CTRL_HDR_SIZE + nci_plen(nu->rx_skb->data); /* Compute how many bytes are missing and how many bytes can * be consumed. */ chunk_len = nu->rx_packet_len - nu->rx_skb->len; if (count < chunk_len) chunk_len = count; memcpy(skb_put(nu->rx_skb, chunk_len), data, chunk_len); data += chunk_len; count -= chunk_len; /* Chcek if packet is fully received */ if (nu->rx_packet_len == nu->rx_skb->len) { /* Pass RX packet to driver */ if (nu->ops.recv(nu, nu->rx_skb) != 0) nfc_err(nu->tty->dev, "corrupted RX packet\n"); /* Next packet will be a new one */ nu->rx_skb = NULL; } } return 0; }
static int microread_i2c_read(struct microread_i2c_phy *phy, struct sk_buff **skb) { int r; u8 len; u8 tmp[MICROREAD_I2C_LLC_MAX_SIZE - 1]; struct i2c_client *client = phy->i2c_dev; r = i2c_master_recv(client, &len, 1); if (r != 1) { nfc_err(&client->dev, "cannot read len byte\n"); return -EREMOTEIO; } if ((len < MICROREAD_I2C_LLC_MIN_SIZE) || (len > MICROREAD_I2C_LLC_MAX_SIZE)) { nfc_err(&client->dev, "invalid len byte\n"); r = -EBADMSG; goto flush; } *skb = alloc_skb(1 + len, GFP_KERNEL); if (*skb == NULL) { r = -ENOMEM; goto flush; } *skb_put(*skb, 1) = len; r = i2c_master_recv(client, skb_put(*skb, len), len); if (r != len) { kfree_skb(*skb); return -EREMOTEIO; } I2C_DUMP_SKB("cc frame read", *skb); r = check_crc(*skb); if (r != 0) { kfree_skb(*skb); r = -EBADMSG; goto flush; } skb_pull(*skb, 1); skb_trim(*skb, (*skb)->len - MICROREAD_I2C_FRAME_TAILROOM); usleep_range(3000, 6000); return 0; flush: if (i2c_master_recv(client, tmp, sizeof(tmp)) < 0) r = -EREMOTEIO; usleep_range(3000, 6000); return r; }
static int st_nci_spi_probe(struct spi_device *dev) { struct st_nci_spi_phy *phy; int r; dev_dbg(&dev->dev, "%s\n", __func__); dev_dbg(&dev->dev, "IRQ: %d\n", dev->irq); /* Check SPI platform functionnalities */ if (!dev) { pr_debug("%s: dev is NULL. Device is not accessible.\n", __func__); return -ENODEV; } phy = devm_kzalloc(&dev->dev, sizeof(struct st_nci_spi_phy), GFP_KERNEL); if (!phy) return -ENOMEM; phy->spi_dev = dev; spi_set_drvdata(dev, phy); r = devm_acpi_dev_add_driver_gpios(&dev->dev, acpi_st_nci_gpios); if (r) dev_dbg(&dev->dev, "Unable to add GPIO mapping table\n"); /* Get RESET GPIO */ phy->gpiod_reset = devm_gpiod_get(&dev->dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(phy->gpiod_reset)) { nfc_err(&dev->dev, "Unable to get RESET GPIO\n"); return PTR_ERR(phy->gpiod_reset); } phy->se_status.is_ese_present = device_property_read_bool(&dev->dev, "ese-present"); phy->se_status.is_uicc_present = device_property_read_bool(&dev->dev, "uicc-present"); r = ndlc_probe(phy, &spi_phy_ops, &dev->dev, ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, &phy->ndlc, &phy->se_status); if (r < 0) { nfc_err(&dev->dev, "Unable to register ndlc layer\n"); return r; } phy->irq_active = true; r = devm_request_threaded_irq(&dev->dev, dev->irq, NULL, st_nci_irq_thread_fn, IRQF_ONESHOT, ST_NCI_SPI_DRIVER_NAME, phy); if (r < 0) nfc_err(&dev->dev, "Unable to register IRQ handler\n"); return r; }
static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) { struct nci_vs_nfcc_info_cmd *cmd; struct sk_buff *skb; unsigned long comp_ret; int rc; skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd), GFP_KERNEL); if (!skb) { nfc_err(&drv->pdev->dev, "no memory for nci_vs_nfcc_info_cmd\n"); return -ENOMEM; } cmd = (struct nci_vs_nfcc_info_cmd *) skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd)); cmd->gid = NCI_VS_NFCC_INFO_CMD_GID; cmd->oid = NCI_VS_NFCC_INFO_CMD_OID; cmd->plen = 0; drv->nfcc_info.plen = 0; rc = nfcwilink_send(drv->ndev, skb); if (rc) return rc; comp_ret = wait_for_completion_timeout(&drv->completed, msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n", comp_ret); if (comp_ret == 0) { nfc_err(&drv->pdev->dev, "timeout on wait_for_completion_timeout\n"); return -ETIMEDOUT; } dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d\n", drv->nfcc_info.plen, drv->nfcc_info.status); if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) { nfc_err(&drv->pdev->dev, "invalid nci_vs_nfcc_info_rsp\n"); return -EINVAL; } snprintf(file_name, BTS_FILE_NAME_MAX_SIZE, "TINfcInit_%d.%d.%d.%d.bts", drv->nfcc_info.hw_id, drv->nfcc_info.sw_ver_x, drv->nfcc_info.sw_ver_z, drv->nfcc_info.patch_id); nfc_info(&drv->pdev->dev, "nfcwilink FW file name: %s\n", file_name); return 0; }
static int st21nfcb_nci_i2c_request_resources(struct i2c_client *client) { struct st21nfcb_nfc_platform_data *pdata; struct st21nfcb_i2c_phy *phy = i2c_get_clientdata(client); int r; int irq; pdata = client->dev.platform_data; if (pdata == NULL) { nfc_err(&client->dev, "No platform data\n"); return -EINVAL; } /* store for later use */ phy->gpio_irq = pdata->gpio_irq; phy->gpio_reset = pdata->gpio_reset; phy->irq_polarity = pdata->irq_polarity; r = devm_gpio_request(&client->dev, phy->gpio_irq, "wake_up"); if (r) { pr_err("%s : gpio_request failed\n", __FILE__); return -ENODEV; } r = gpio_direction_input(phy->gpio_irq); if (r) { pr_err("%s : gpio_direction_input failed\n", __FILE__); return -ENODEV; } r = devm_gpio_request(&client->dev, phy->gpio_reset, "clf_reset"); if (r) { pr_err("%s : reset gpio_request failed\n", __FILE__); return -ENODEV; } r = gpio_direction_output(phy->gpio_reset, 1); if (r) { pr_err("%s : reset gpio_direction_output failed\n", __FILE__); return -ENODEV; } /* IRQ */ irq = gpio_to_irq(phy->gpio_irq); if (irq < 0) { nfc_err(&client->dev, "Unable to get irq number for GPIO %d error %d\n", phy->gpio_irq, r); return -ENODEV; } client->irq = irq; return 0; }
static int nfcmrvl_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct nfcmrvl_i2c_drv_data *drv_data; struct nfcmrvl_platform_data *pdata; struct nfcmrvl_platform_data config; int ret; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { nfc_err(&client->dev, "Need I2C_FUNC_I2C\n"); return -ENODEV; } drv_data = devm_kzalloc(&client->dev, sizeof(*drv_data), GFP_KERNEL); if (!drv_data) return -ENOMEM; drv_data->i2c = client; drv_data->dev = &client->dev; drv_data->priv = NULL; i2c_set_clientdata(client, drv_data); pdata = client->dev.platform_data; if (!pdata && client->dev.of_node) if (nfcmrvl_i2c_parse_dt(client->dev.of_node, &config) == 0) pdata = &config; if (!pdata) return -EINVAL; /* Request the read IRQ */ ret = devm_request_threaded_irq(&drv_data->i2c->dev, pdata->irq, NULL, nfcmrvl_i2c_int_irq_thread_fn, pdata->irq_polarity | IRQF_ONESHOT, "nfcmrvl_i2c_int", drv_data); if (ret < 0) { nfc_err(&drv_data->i2c->dev, "Unable to register IRQ handler\n"); return ret; } drv_data->priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_I2C, drv_data, &i2c_ops, &drv_data->i2c->dev, pdata); if (IS_ERR(drv_data->priv)) return PTR_ERR(drv_data->priv); drv_data->priv->support_fw_dnld = true; return 0; }
static int nfcwilink_probe(struct platform_device *pdev) { static struct nfcwilink *drv; int rc; __u32 protocols; drv = devm_kzalloc(&pdev->dev, sizeof(struct nfcwilink), GFP_KERNEL); if (!drv) { rc = -ENOMEM; goto exit; } drv->pdev = pdev; protocols = NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK | NFC_PROTO_ISO14443_B_MASK | NFC_PROTO_NFC_DEP_MASK; drv->ndev = nci_allocate_device(&nfcwilink_ops, protocols, NFCWILINK_HDR_LEN, 0); if (!drv->ndev) { nfc_err(&pdev->dev, "nci_allocate_device failed\n"); rc = -ENOMEM; goto exit; } nci_set_parent_dev(drv->ndev, &pdev->dev); nci_set_drvdata(drv->ndev, drv); rc = nci_register_device(drv->ndev); if (rc < 0) { nfc_err(&pdev->dev, "nci_register_device failed %d\n", rc); goto free_dev_exit; } dev_set_drvdata(&pdev->dev, drv); goto exit; free_dev_exit: nci_free_device(drv->ndev); exit: return rc; }
static int microread_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct microread_i2c_phy *phy; struct microread_nfc_platform_data *pdata = dev_get_platdata(&client->dev); int r; dev_dbg(&client->dev, "client %p\n", client); if (!pdata) { nfc_err(&client->dev, "client %p: missing platform data\n", client); return -EINVAL; } phy = devm_kzalloc(&client->dev, sizeof(struct microread_i2c_phy), GFP_KERNEL); if (!phy) return -ENOMEM; i2c_set_clientdata(client, phy); phy->i2c_dev = client; r = request_threaded_irq(client->irq, NULL, microread_i2c_irq_thread_fn, IRQF_TRIGGER_RISING | IRQF_ONESHOT, MICROREAD_I2C_DRIVER_NAME, phy); if (r) { nfc_err(&client->dev, "Unable to register IRQ handler\n"); return r; } r = microread_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, MICROREAD_I2C_FRAME_HEADROOM, MICROREAD_I2C_FRAME_TAILROOM, MICROREAD_I2C_LLC_MAX_PAYLOAD, &phy->hdev); if (r < 0) goto err_irq; nfc_info(&client->dev, "Probed\n"); return 0; err_irq: free_irq(client->irq, phy); return r; }
static void nci_rx_work(struct work_struct *work) { struct nci_dev *ndev = container_of(work, struct nci_dev, rx_work); struct sk_buff *skb; while ((skb = skb_dequeue(&ndev->rx_q))) { /* Process frame */ switch (nci_mt(skb->data)) { case NCI_MT_RSP_PKT: nci_rsp_packet(ndev, skb); break; case NCI_MT_NTF_PKT: nci_ntf_packet(ndev, skb); break; case NCI_MT_DATA_PKT: nci_rx_data_packet(ndev, skb); break; default: nfc_err("unknown MT 0x%x", nci_mt(skb->data)); kfree_skb(skb); break; } } }
static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv, struct sk_buff *skb) { struct nfcmrvl_i2c_drv_data *drv_data = priv->drv_data; int ret; if (test_bit(NFCMRVL_PHY_ERROR, &priv->flags)) return -EREMOTEIO; ret = i2c_master_send(drv_data->i2c, skb->data, skb->len); /* Retry if chip was in standby */ if (ret == -EREMOTEIO) { nfc_info(drv_data->dev, "chip may sleep, retry\n"); usleep_range(6000, 10000); ret = i2c_master_send(drv_data->i2c, skb->data, skb->len); } if (ret >= 0) { if (ret != skb->len) { nfc_err(drv_data->dev, "Invalid length sent: %u (expected %u)\n", ret, skb->len); ret = -EREMOTEIO; } else ret = 0; kfree_skb(skb); } return ret; }
int ndlc_probe(void *phy_id, struct nfc_phy_ops *phy_ops, struct device *dev, int phy_headroom, int phy_tailroom, struct llt_ndlc **ndlc_id) { struct llt_ndlc *ndlc; ndlc = devm_kzalloc(dev, sizeof(struct llt_ndlc), GFP_KERNEL); if (!ndlc) { nfc_err(dev, "Cannot allocate memory for ndlc.\n"); return -ENOMEM; } ndlc->ops = phy_ops; ndlc->phy_id = phy_id; ndlc->dev = dev; *ndlc_id = ndlc; /* start timers */ init_timer(&ndlc->t1_timer); ndlc->t1_timer.data = (unsigned long)ndlc; ndlc->t1_timer.function = ndlc_t1_timeout; init_timer(&ndlc->t2_timer); ndlc->t2_timer.data = (unsigned long)ndlc; ndlc->t2_timer.function = ndlc_t2_timeout; skb_queue_head_init(&ndlc->rcv_q); skb_queue_head_init(&ndlc->send_q); skb_queue_head_init(&ndlc->ack_pending_q); INIT_WORK(&ndlc->sm_work, llt_ndlc_sm_work); return st21nfcb_nci_probe(ndlc, phy_headroom, phy_tailroom); }
/* Called by ST when receive data is available */ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) { struct nfcwilink *drv = priv_data; int rc; if (!skb) return -EFAULT; if (!drv) { kfree_skb(skb); return -EFAULT; } dev_dbg(&drv->pdev->dev, "receive entry, len %d\n", skb->len); /* strip the ST header (apart for the chnl byte, which is not received in the hdr) */ skb_pull(skb, (NFCWILINK_HDR_LEN-1)); if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) { nfcwilink_fw_download_receive(drv, skb); return 0; } /* Forward skb to NCI core layer */ rc = nci_recv_frame(drv->ndev, skb); if (rc < 0) { nfc_err(&drv->pdev->dev, "nci_recv_frame failed %d\n", rc); return rc; } return 0; }
static int st_nci_i2c_request_resources(struct i2c_client *client) { struct st_nci_nfc_platform_data *pdata; struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); int r; pdata = client->dev.platform_data; if (pdata == NULL) { nfc_err(&client->dev, "No platform data\n"); return -EINVAL; } /* store for later use */ phy->gpio_reset = pdata->gpio_reset; phy->irq_polarity = pdata->irq_polarity; r = devm_gpio_request_one(&client->dev, phy->gpio_reset, GPIOF_OUT_INIT_HIGH, ST_NCI_GPIO_NAME_RESET); if (r) { pr_err("%s : reset gpio_request failed\n", __FILE__); return r; } phy->se_status.is_ese_present = pdata->is_ese_present; phy->se_status.is_uicc_present = pdata->is_uicc_present; return 0; }
static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb) { struct nfcwilink *drv = nci_get_drvdata(ndev); struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000}; long len; dev_dbg(&drv->pdev->dev, "send entry, len %d\n", skb->len); if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) { kfree_skb(skb); return -EINVAL; } /* add the ST hdr to the start of the buffer */ hdr.len = cpu_to_le16(skb->len); memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN); /* Insert skb to shared transport layer's transmit queue. * Freeing skb memory is taken care in shared transport layer, * so don't free skb memory here. */ len = drv->st_write(skb); if (len < 0) { kfree_skb(skb); nfc_err(&drv->pdev->dev, "st_write failed %ld\n", len); return -EFAULT; } return 0; }
static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols) { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); int rc; nfc_dbg("entry"); if (test_bit(NCI_DISCOVERY, &ndev->flags)) { nfc_err("unable to start poll, since poll is already active"); return -EBUSY; } if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) { nfc_dbg("target already active, first deactivate..."); rc = nci_request(ndev, nci_rf_deactivate_req, 0, msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); if (rc) return -EBUSY; } rc = nci_request(ndev, nci_rf_discover_req, protocols, msecs_to_jiffies(NCI_RF_DISC_TIMEOUT)); if (!rc) ndev->poll_prots = protocols; return rc; }
static int st_nci_i2c_acpi_request_resources(struct i2c_client *client) { struct st_nci_i2c_phy *phy = i2c_get_clientdata(client); struct gpio_desc *gpiod_reset; struct device *dev = &client->dev; u8 tmp; /* Get RESET GPIO from ACPI */ gpiod_reset = devm_gpiod_get_index(dev, ST_NCI_GPIO_NAME_RESET, 1, GPIOD_OUT_HIGH); if (IS_ERR(gpiod_reset)) { nfc_err(dev, "Unable to get RESET GPIO\n"); return -ENODEV; } phy->gpio_reset = desc_to_gpio(gpiod_reset); phy->irq_polarity = irq_get_trigger_type(client->irq); phy->se_status.is_ese_present = false; phy->se_status.is_uicc_present = false; if (device_property_present(dev, "ese-present")) { device_property_read_u8(dev, "ese-present", &tmp); phy->se_status.is_ese_present = tmp; } if (device_property_present(dev, "uicc-present")) { device_property_read_u8(dev, "uicc-present", &tmp); phy->se_status.is_uicc_present = tmp; } return 0; }
/* Send NCI command */ int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload) { struct nci_ctrl_hdr *hdr; struct sk_buff *skb; nfc_dbg("entry, opcode 0x%x, plen %d", opcode, plen); skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL); if (!skb) { nfc_err("no memory for command"); return -ENOMEM; } hdr = (struct nci_ctrl_hdr *) skb_put(skb, NCI_CTRL_HDR_SIZE); hdr->gid = nci_opcode_gid(opcode); hdr->oid = nci_opcode_oid(opcode); hdr->plen = plen; nci_mt_set((__u8 *)hdr, NCI_MT_CMD_PKT); nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST); if (plen) memcpy(skb_put(skb, plen), payload, plen); skb->dev = (void *) ndev; skb_queue_tail(&ndev->cmd_q, skb); queue_work(ndev->cmd_wq, &ndev->cmd_work); return 0; }
void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) { __u16 ntf_opcode = nci_opcode(skb->data); nfc_dbg("NCI RX: MT=ntf, PBF=%d, GID=0x%x, OID=0x%x, plen=%d", nci_pbf(skb->data), nci_opcode_gid(ntf_opcode), nci_opcode_oid(ntf_opcode), nci_plen(skb->data)); /* strip the nci control header */ skb_pull(skb, NCI_CTRL_HDR_SIZE); switch (ntf_opcode) { case NCI_OP_CORE_CONN_CREDITS_NTF: nci_core_conn_credits_ntf_packet(ndev, skb); break; case NCI_OP_RF_INTF_ACTIVATED_NTF: nci_rf_intf_activated_ntf_packet(ndev, skb); break; case NCI_OP_RF_DEACTIVATE_NTF: nci_rf_deactivate_ntf_packet(ndev, skb); break; default: nfc_err("unknown ntf opcode 0x%x", ntf_opcode); break; } kfree_skb(skb); }
static int st21nfca_admin_event_received(struct nfc_hci_dev *hdev, u8 event, struct sk_buff *skb) { struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); pr_debug("admin event: %x\n", event); switch (event) { case ST21NFCA_EVT_HOT_PLUG: if (info->se_info.se_active) { if (!ST21NFCA_EVT_HOT_PLUG_IS_INHIBITED(skb)) { del_timer_sync(&info->se_info.se_active_timer); info->se_info.se_active = false; complete(&info->se_info.req_completion); } else { mod_timer(&info->se_info.se_active_timer, jiffies + msecs_to_jiffies(ST21NFCA_SE_TO_PIPES)); } } break; default: nfc_err(&hdev->ndev->dev, "Unexpected event on admin gate\n"); } kfree_skb(skb); return 0; }
/* Send NCI data */ int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb) { int rc = 0; nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len); /* check if the packet need to be fragmented */ if (skb->len <= ndev->max_data_pkt_payload_size) { /* no need to fragment packet */ nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST); skb_queue_tail(&ndev->tx_q, skb); } else { /* fragment packet and queue the fragments */ rc = nci_queue_tx_data_frags(ndev, conn_id, skb); if (rc) { nfc_err("failed to fragment tx data packet"); goto free_exit; } } queue_work(ndev->tx_wq, &ndev->tx_work); goto exit; free_exit: kfree_skb(skb); exit: return rc; }
static int st_nci_spi_request_resources(struct spi_device *dev) { struct st_nci_nfc_platform_data *pdata; struct st_nci_spi_phy *phy = spi_get_drvdata(dev); int r; pdata = dev->dev.platform_data; if (pdata == NULL) { nfc_err(&dev->dev, "No platform data\n"); return -EINVAL; } /* store for later use */ phy->gpio_reset = pdata->gpio_reset; phy->irq_polarity = pdata->irq_polarity; r = devm_gpio_request_one(&dev->dev, phy->gpio_reset, GPIOF_OUT_INIT_HIGH, "clf_reset"); if (r) { pr_err("%s : reset gpio_request failed\n", __FILE__); return r; } phy->se_status.is_ese_present = pdata->is_ese_present; phy->se_status.is_uicc_present = pdata->is_uicc_present; return 0; }
/* * Reads an ndlc frame and returns it in a newly allocated sk_buff. * returns: * frame size : if received frame is complete (find ST21NFCB_SOF_EOF at * end of read) * -EAGAIN : if received frame is incomplete (not find ST21NFCB_SOF_EOF * at end of read) * -EREMOTEIO : i2c read error (fatal) * -EBADMSG : frame was incorrect and discarded * (value returned from st21nfcb_nci_i2c_repack) * -EIO : if no ST21NFCB_SOF_EOF is found after reaching * the read length end sequence */ static int st21nfcb_nci_i2c_read(struct st21nfcb_i2c_phy *phy, struct sk_buff **skb) { int r; u8 len; u8 buf[ST21NFCB_NCI_I2C_MAX_SIZE]; struct i2c_client *client = phy->i2c_dev; r = i2c_master_recv(client, buf, ST21NFCB_NCI_I2C_MIN_SIZE); if (r == -EREMOTEIO) { /* Retry, chip was in standby */ usleep_range(1000, 4000); r = i2c_master_recv(client, buf, ST21NFCB_NCI_I2C_MIN_SIZE); } else if (r != ST21NFCB_NCI_I2C_MIN_SIZE) { nfc_err(&client->dev, "cannot read ndlc & nci header\n"); return -EREMOTEIO; } len = be16_to_cpu(*(__be16 *) (buf + 2)); if (len > ST21NFCB_NCI_I2C_MAX_SIZE) { nfc_err(&client->dev, "invalid frame len\n"); return -EBADMSG; } *skb = alloc_skb(ST21NFCB_NCI_I2C_MIN_SIZE + len, GFP_KERNEL); if (*skb == NULL) return -ENOMEM; skb_reserve(*skb, ST21NFCB_NCI_I2C_MIN_SIZE); skb_put(*skb, ST21NFCB_NCI_I2C_MIN_SIZE); memcpy((*skb)->data, buf, ST21NFCB_NCI_I2C_MIN_SIZE); if (!len) return 0; r = i2c_master_recv(client, buf, len); if (r != len) { kfree_skb(*skb); return -EREMOTEIO; } skb_put(*skb, len); memcpy((*skb)->data + ST21NFCB_NCI_I2C_MIN_SIZE, buf, len); I2C_DUMP_SKB("i2c frame read", *skb); return 0; }
static void pn533_recv_ack(struct urb *urb) { struct pn533_usb_phy *phy = urb->context; struct pn533 *priv = phy->priv; struct pn533_cmd *cmd = priv->cmd; struct pn533_std_frame *in_frame; int rc; cmd->status = urb->status; switch (urb->status) { case 0: break; /* success */ case -ECONNRESET: case -ENOENT: dev_dbg(&phy->udev->dev, "The urb has been stopped (status %d)\n", urb->status); goto sched_wq; case -ESHUTDOWN: default: nfc_err(&phy->udev->dev, "Urb failure (status %d)\n", urb->status); goto sched_wq; } in_frame = phy->in_urb->transfer_buffer; if (!pn533_rx_frame_is_ack(in_frame)) { nfc_err(&phy->udev->dev, "Received an invalid ack\n"); cmd->status = -EIO; goto sched_wq; } rc = pn533_submit_urb_for_response(phy, GFP_ATOMIC); if (rc) { nfc_err(&phy->udev->dev, "usb_submit_urb failed with result %d\n", rc); cmd->status = rc; goto sched_wq; } return; sched_wq: queue_work(priv->wq, &priv->cmd_complete_work); }
static int st21nfcb_nci_i2c_of_request_resources(struct i2c_client *client) { struct st21nfcb_i2c_phy *phy = i2c_get_clientdata(client); struct device_node *pp; int gpio; int r; pp = client->dev.of_node; if (!pp) return -ENODEV; /* Get GPIO from device tree */ gpio = of_get_named_gpio(pp, "reset-gpios", 0); if (gpio < 0) { nfc_err(&client->dev, "Failed to retrieve reset-gpios from device tree\n"); return gpio; } /* GPIO request and configuration */ r = devm_gpio_request(&client->dev, gpio, "clf_reset"); if (r) { nfc_err(&client->dev, "Failed to request reset pin\n"); return -ENODEV; } r = gpio_direction_output(gpio, 1); if (r) { nfc_err(&client->dev, "Failed to set reset pin direction as output\n"); return -ENODEV; } phy->gpio_reset = gpio; /* IRQ */ r = irq_of_parse_and_map(pp, 0); if (r < 0) { nfc_err(&client->dev, "Unable to get irq, error: %d\n", r); return r; } phy->irq_polarity = irq_get_trigger_type(r); client->irq = r; return 0; }