···11+* Marvell International Ltd. NCI NFC Controller22+33+Required properties:44+- compatible: Should be "mrvl,nfc-uart".55+66+Optional SoC specific properties:77+- pinctrl-names: Contains only one value - "default".88+- pintctrl-0: Specifies the pin control groups used for this controller.99+- reset-n-io: Output GPIO pin used to reset the chip (active low).1010+- hci-muxed: Specifies that the chip is muxing NCI over HCI frames.1111+1212+Optional UART-based chip specific properties:1313+- flow-control: Specifies that the chip is using RTS/CTS.1414+- break-control: Specifies that the chip needs specific break management.1515+1616+Example (for ARM-based BeagleBoard Black with 88W8887 on UART5):1717+1818+&uart5 {1919+ status = "okay";2020+2121+ nfcmrvluart: nfcmrvluart@5 {2222+ compatible = "mrvl,nfc-uart";2323+2424+ reset-n-io = <&gpio3 16 0>;2525+2626+ hci-muxed;2727+ flow-control;2828+ }2929+};
+11
drivers/nfc/nfcmrvl/Kconfig
···21212222 Say Y here to compile support for Marvell NFC-over-USB driver2323 into the kernel or say M to compile it as module.2424+2525+config NFC_MRVL_UART2626+ tristate "Marvell NFC-over-UART driver"2727+ depends on NFC_MRVL && NFC_NCI_UART2828+ help2929+ Marvell NFC-over-UART driver.3030+3131+ This driver provides support for Marvell NFC-over-UART devices3232+3333+ Say Y here to compile support for Marvell NFC-over-UART driver3434+ into the kernel or say M to compile it as module.
···11+/**22+ * Marvell NFC-over-UART driver33+ *44+ * Copyright (C) 2015, Marvell International Ltd.55+ *66+ * This software file (the "File") is distributed by Marvell International77+ * Ltd. under the terms of the GNU General Public License Version 2, June 199188+ * (the "License"). You may use, redistribute and/or modify this File in99+ * accordance with the terms and conditions of the License, a copy of which1010+ * is available on the worldwide web at1111+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.1212+ *1313+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE1414+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE1515+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about1616+ * this warranty disclaimer.1717+ */1818+1919+#include <linux/module.h>2020+#include <linux/delay.h>2121+#include <linux/of_gpio.h>2222+#include <net/nfc/nci.h>2323+#include <net/nfc/nci_core.h>2424+#include "nfcmrvl.h"2525+2626+static unsigned int hci_muxed;2727+static unsigned int flow_control;2828+static unsigned int break_control;2929+static unsigned int reset_n_io;3030+3131+/*3232+** NFCMRVL NCI OPS3333+*/3434+3535+static int nfcmrvl_uart_nci_open(struct nfcmrvl_private *priv)3636+{3737+ return 0;3838+}3939+4040+static int nfcmrvl_uart_nci_close(struct nfcmrvl_private *priv)4141+{4242+ return 0;4343+}4444+4545+static int nfcmrvl_uart_nci_send(struct nfcmrvl_private *priv,4646+ struct sk_buff *skb)4747+{4848+ struct nci_uart *nu = priv->drv_data;4949+5050+ return nu->ops.send(nu, skb);5151+}5252+5353+static struct nfcmrvl_if_ops uart_ops = {5454+ .nci_open = nfcmrvl_uart_nci_open,5555+ .nci_close = nfcmrvl_uart_nci_close,5656+ .nci_send = nfcmrvl_uart_nci_send,5757+};5858+5959+#ifdef CONFIG_OF6060+6161+static int nfcmrvl_uart_parse_dt(struct device_node *node,6262+ struct nfcmrvl_platform_data *pdata)6363+{6464+ struct device_node *matched_node;6565+ int ret;6666+6767+ matched_node = of_find_compatible_node(node, NULL, "mrvl,nfc-uart");6868+ if (!matched_node)6969+ return -ENODEV;7070+7171+ ret = nfcmrvl_parse_dt(matched_node, pdata);7272+ if (ret < 0) {7373+ pr_err("Failed to get generic entries\n");7474+ return ret;7575+ }7676+7777+ if (of_find_property(matched_node, "flow-control", NULL))7878+ pdata->flow_control = 1;7979+ else8080+ pdata->flow_control = 0;8181+8282+ if (of_find_property(matched_node, "break-control", NULL))8383+ pdata->break_control = 1;8484+ else8585+ pdata->break_control = 0;8686+8787+ return 0;8888+}8989+9090+#else9191+9292+static int nfcmrvl_uart_parse_dt(struct device_node *node,9393+ struct nfcmrvl_platform_data *pdata)9494+{9595+ return -ENODEV;9696+}9797+9898+#endif9999+100100+/*101101+** NCI UART OPS102102+*/103103+104104+static int nfcmrvl_nci_uart_open(struct nci_uart *nu)105105+{106106+ struct nfcmrvl_private *priv;107107+ struct nfcmrvl_platform_data *pdata = NULL;108108+ struct nfcmrvl_platform_data config;109109+110110+ /*111111+ * Platform data cannot be used here since usually it is already used112112+ * by low level serial driver. We can try to retrieve serial device113113+ * and check if DT entries were added.114114+ */115115+116116+ if (nu->tty->dev->parent && nu->tty->dev->parent->of_node)117117+ if (nfcmrvl_uart_parse_dt(nu->tty->dev->parent->of_node,118118+ &config) == 0)119119+ pdata = &config;120120+121121+ if (!pdata) {122122+ pr_info("No platform data / DT -> fallback to module params\n");123123+ config.hci_muxed = hci_muxed;124124+ config.reset_n_io = reset_n_io;125125+ config.flow_control = flow_control;126126+ config.break_control = break_control;127127+ pdata = &config;128128+ }129129+130130+ priv = nfcmrvl_nci_register_dev(nu, &uart_ops, nu->tty->dev, pdata);131131+ if (IS_ERR(priv))132132+ return PTR_ERR(priv);133133+134134+ priv->phy = NFCMRVL_PHY_UART;135135+136136+ nu->drv_data = priv;137137+ nu->ndev = priv->ndev;138138+139139+ /* Set BREAK */140140+ if (priv->config.break_control && nu->tty->ops->break_ctl)141141+ nu->tty->ops->break_ctl(nu->tty, -1);142142+143143+ return 0;144144+}145145+146146+static void nfcmrvl_nci_uart_close(struct nci_uart *nu)147147+{148148+ nfcmrvl_nci_unregister_dev((struct nfcmrvl_private *)nu->drv_data);149149+}150150+151151+static int nfcmrvl_nci_uart_recv(struct nci_uart *nu, struct sk_buff *skb)152152+{153153+ return nfcmrvl_nci_recv_frame((struct nfcmrvl_private *)nu->drv_data,154154+ skb);155155+}156156+157157+static void nfcmrvl_nci_uart_tx_start(struct nci_uart *nu)158158+{159159+ struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data;160160+161161+ /* Remove BREAK to wake up the NFCC */162162+ if (priv->config.break_control && nu->tty->ops->break_ctl) {163163+ nu->tty->ops->break_ctl(nu->tty, 0);164164+ usleep_range(3000, 5000);165165+ }166166+}167167+168168+static void nfcmrvl_nci_uart_tx_done(struct nci_uart *nu)169169+{170170+ struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data;171171+172172+ /*173173+ ** To ensure that if the NFCC goes in DEEP SLEEP sate we can wake him174174+ ** up. we set BREAK. Once we will be ready to send again we will remove175175+ ** it.176176+ */177177+ if (priv->config.break_control && nu->tty->ops->break_ctl)178178+ nu->tty->ops->break_ctl(nu->tty, -1);179179+}180180+181181+static struct nci_uart nfcmrvl_nci_uart = {182182+ .owner = THIS_MODULE,183183+ .name = "nfcmrvl_uart",184184+ .driver = NCI_UART_DRIVER_MARVELL,185185+ .ops = {186186+ .open = nfcmrvl_nci_uart_open,187187+ .close = nfcmrvl_nci_uart_close,188188+ .recv = nfcmrvl_nci_uart_recv,189189+ .tx_start = nfcmrvl_nci_uart_tx_start,190190+ .tx_done = nfcmrvl_nci_uart_tx_done,191191+ }192192+};193193+194194+/*195195+** Module init196196+*/197197+198198+static int nfcmrvl_uart_init_module(void)199199+{200200+ return nci_uart_register(&nfcmrvl_nci_uart);201201+}202202+203203+static void nfcmrvl_uart_exit_module(void)204204+{205205+ nci_uart_unregister(&nfcmrvl_nci_uart);206206+}207207+208208+module_init(nfcmrvl_uart_init_module);209209+module_exit(nfcmrvl_uart_exit_module);210210+211211+MODULE_AUTHOR("Marvell International Ltd.");212212+MODULE_DESCRIPTION("Marvell NFC-over-UART");213213+MODULE_LICENSE("GPL v2");214214+215215+module_param(flow_control, uint, 0);216216+MODULE_PARM_DESC(flow_control, "Tell if UART needs flow control at init.");217217+218218+module_param(break_control, uint, 0);219219+MODULE_PARM_DESC(break_control, "Tell if UART driver must drive break signal.");220220+221221+module_param(hci_muxed, uint, 0);222222+MODULE_PARM_DESC(hci_muxed, "Tell if transport is muxed in HCI one.");223223+224224+module_param(reset_n_io, uint, 0);225225+MODULE_PARM_DESC(reset_n_io, "GPIO that is wired to RESET_N signal.");
+9
include/linux/platform_data/nfcmrvl.h
···2626 unsigned int reset_n_io;2727 /* Tell if transport is muxed in HCI one */2828 unsigned int hci_muxed;2929+3030+ /*3131+ * UART specific3232+ */3333+3434+ /* Tell if UART needs flow control at init */3535+ unsigned int flow_control;3636+ /* Tell if firmware supports break control for power management */3737+ unsigned int break_control;2938};30393140#endif /* _NFCMRVL_PTF_H_ */
-1
net/nfc/nci/uart.c
···1212 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE1313 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about1414 * this warranty disclaimer.1515-1615 */17161817/* Inspired (hugely) by HCI LDISC implementation in Bluetooth.