^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Marvell NFC driver: major functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2014-2015 Marvell International Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This software file (the "File") is distributed by Marvell International
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Ltd. under the terms of the GNU General Public License Version 2, June 1991
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (the "License"). You may use, redistribute and/or modify this File in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * accordance with the terms and conditions of the License, a copy of which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * is available on the worldwide web at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * this warranty disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/nfc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/nfc/nci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <net/nfc/nci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "nfcmrvl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static int nfcmrvl_nci_open(struct nci_dev *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Reset possible fault of previous session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) err = priv->if_ops->nci_open(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int nfcmrvl_nci_close(struct nci_dev *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (!test_and_clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) priv->if_ops->nci_close(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int nfcmrvl_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) nfc_info(priv->dev, "send entry, len %d\n", skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) skb->dev = (void *)ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (priv->config.hci_muxed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned char *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned char len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) hdr = skb_push(skb, NFCMRVL_HCI_EVENT_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) hdr[0] = NFCMRVL_HCI_COMMAND_CODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) hdr[1] = NFCMRVL_HCI_OGF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) hdr[2] = NFCMRVL_HCI_OCF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) hdr[3] = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return priv->if_ops->nci_send(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int nfcmrvl_nci_setup(struct nci_dev *ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) __u8 val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) nci_set_config(ndev, NFCMRVL_PB_BAIL_OUT, 1, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int nfcmrvl_nci_fw_download(struct nci_dev *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) const char *firmware_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return nfcmrvl_fw_dnld_start(ndev, firmware_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static struct nci_ops nfcmrvl_nci_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .open = nfcmrvl_nci_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .close = nfcmrvl_nci_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .send = nfcmrvl_nci_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .setup = nfcmrvl_nci_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .fw_download = nfcmrvl_nci_fw_download,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) void *drv_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct nfcmrvl_if_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct nfcmrvl_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct nfcmrvl_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int headroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int tailroom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u32 protocols;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) priv = kzalloc(sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) priv->drv_data = drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) priv->if_ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) priv->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) priv->phy = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) memcpy(&priv->config, pdata, sizeof(*pdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (gpio_is_valid(priv->config.reset_n_io)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) rc = gpio_request_one(priv->config.reset_n_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) GPIOF_OUT_INIT_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "nfcmrvl_reset_n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) priv->config.reset_n_io = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) nfc_err(dev, "failed to request reset_n io\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (phy == NFCMRVL_PHY_SPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) headroom = NCI_SPI_HDR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) tailroom = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) headroom = tailroom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (priv->config.hci_muxed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) headroom += NFCMRVL_HCI_EVENT_HEADER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) protocols = NFC_PROTO_JEWEL_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) | NFC_PROTO_MIFARE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) | NFC_PROTO_FELICA_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) | NFC_PROTO_ISO14443_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) | NFC_PROTO_ISO14443_B_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) | NFC_PROTO_ISO15693_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) | NFC_PROTO_NFC_DEP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) priv->ndev = nci_allocate_device(&nfcmrvl_nci_ops, protocols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) headroom, tailroom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!priv->ndev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) nfc_err(dev, "nci_allocate_device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) goto error_free_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) rc = nfcmrvl_fw_dnld_init(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) nfc_err(dev, "failed to initialize FW download %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) goto error_free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) nci_set_drvdata(priv->ndev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) rc = nci_register_device(priv->ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) nfc_err(dev, "nci_register_device failed %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) goto error_fw_dnld_deinit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Ensure that controller is powered off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) nfcmrvl_chip_halt(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) nfc_info(dev, "registered with nci successfully\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) error_fw_dnld_deinit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) nfcmrvl_fw_dnld_deinit(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) error_free_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) nci_free_device(priv->ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) error_free_gpio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (gpio_is_valid(priv->config.reset_n_io))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) gpio_free(priv->config.reset_n_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) EXPORT_SYMBOL_GPL(nfcmrvl_nci_register_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct nci_dev *ndev = priv->ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) nci_unregister_device(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (priv->ndev->nfc_dev->fw_download_in_progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) nfcmrvl_fw_dnld_abort(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) nfcmrvl_fw_dnld_deinit(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (gpio_is_valid(priv->config.reset_n_io))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) gpio_free(priv->config.reset_n_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) nci_free_device(ndev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) EXPORT_SYMBOL_GPL(nfcmrvl_nci_unregister_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (priv->config.hci_muxed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (skb->data[0] == NFCMRVL_HCI_EVENT_CODE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) skb->data[1] == NFCMRVL_HCI_NFC_EVENT_CODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* Data packet, let's extract NCI payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) skb_pull(skb, NFCMRVL_HCI_EVENT_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Skip this packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (priv->ndev->nfc_dev->fw_download_in_progress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) nfcmrvl_fw_dnld_recv_frame(priv, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (test_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) nci_recv_frame(priv->ndev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Drop this packet since nobody wants it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) EXPORT_SYMBOL_GPL(nfcmrvl_nci_recv_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) void nfcmrvl_chip_reset(struct nfcmrvl_private *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* Reset possible fault of previous session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (gpio_is_valid(priv->config.reset_n_io)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) nfc_info(priv->dev, "reset the chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) gpio_set_value(priv->config.reset_n_io, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) gpio_set_value(priv->config.reset_n_io, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) nfc_info(priv->dev, "no reset available on this interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) void nfcmrvl_chip_halt(struct nfcmrvl_private *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (gpio_is_valid(priv->config.reset_n_io))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) gpio_set_value(priv->config.reset_n_io, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int nfcmrvl_parse_dt(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct nfcmrvl_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int reset_n_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) reset_n_io = of_get_named_gpio(node, "reset-n-io", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (reset_n_io < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) pr_info("no reset-n-io config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) } else if (!gpio_is_valid(reset_n_io)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) pr_err("invalid reset-n-io GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return reset_n_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) pdata->reset_n_io = reset_n_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (of_find_property(node, "hci-muxed", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) pdata->hci_muxed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) pdata->hci_muxed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) EXPORT_SYMBOL_GPL(nfcmrvl_parse_dt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) MODULE_AUTHOR("Marvell International Ltd.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) MODULE_DESCRIPTION("Marvell NFC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) MODULE_LICENSE("GPL v2");