diff options
| -rw-r--r-- | Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt | 29 | ||||
| -rw-r--r-- | drivers/nfc/nfcmrvl/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/nfc/nfcmrvl/Makefile | 3 | ||||
| -rw-r--r-- | drivers/nfc/nfcmrvl/nfcmrvl.h | 7 | ||||
| -rw-r--r-- | drivers/nfc/nfcmrvl/uart.c | 225 | ||||
| -rw-r--r-- | include/linux/platform_data/nfcmrvl.h | 9 | ||||
| -rw-r--r-- | net/nfc/nci/uart.c | 1 |
7 files changed, 284 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt new file mode 100644 index 000000000000..7c4a0cc370cf --- /dev/null +++ b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | * Marvell International Ltd. NCI NFC Controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Should be "mrvl,nfc-uart". | ||
| 5 | |||
| 6 | Optional SoC specific properties: | ||
| 7 | - pinctrl-names: Contains only one value - "default". | ||
| 8 | - pintctrl-0: Specifies the pin control groups used for this controller. | ||
| 9 | - reset-n-io: Output GPIO pin used to reset the chip (active low). | ||
| 10 | - hci-muxed: Specifies that the chip is muxing NCI over HCI frames. | ||
| 11 | |||
| 12 | Optional UART-based chip specific properties: | ||
| 13 | - flow-control: Specifies that the chip is using RTS/CTS. | ||
| 14 | - break-control: Specifies that the chip needs specific break management. | ||
| 15 | |||
| 16 | Example (for ARM-based BeagleBoard Black with 88W8887 on UART5): | ||
| 17 | |||
| 18 | &uart5 { | ||
| 19 | status = "okay"; | ||
| 20 | |||
| 21 | nfcmrvluart: nfcmrvluart@5 { | ||
| 22 | compatible = "mrvl,nfc-uart"; | ||
| 23 | |||
| 24 | reset-n-io = <&gpio3 16 0>; | ||
| 25 | |||
| 26 | hci-muxed; | ||
| 27 | flow-control; | ||
| 28 | } | ||
| 29 | }; | ||
diff --git a/drivers/nfc/nfcmrvl/Kconfig b/drivers/nfc/nfcmrvl/Kconfig index 5e18afd9abe2..796be2411440 100644 --- a/drivers/nfc/nfcmrvl/Kconfig +++ b/drivers/nfc/nfcmrvl/Kconfig | |||
| @@ -21,3 +21,14 @@ config NFC_MRVL_USB | |||
| 21 | 21 | ||
| 22 | Say Y here to compile support for Marvell NFC-over-USB driver | 22 | Say Y here to compile support for Marvell NFC-over-USB driver |
| 23 | into the kernel or say M to compile it as module. | 23 | into the kernel or say M to compile it as module. |
| 24 | |||
| 25 | config NFC_MRVL_UART | ||
| 26 | tristate "Marvell NFC-over-UART driver" | ||
| 27 | depends on NFC_MRVL && NFC_NCI_UART | ||
| 28 | help | ||
| 29 | Marvell NFC-over-UART driver. | ||
| 30 | |||
| 31 | This driver provides support for Marvell NFC-over-UART devices | ||
| 32 | |||
| 33 | Say Y here to compile support for Marvell NFC-over-UART driver | ||
| 34 | into the kernel or say M to compile it as module. | ||
diff --git a/drivers/nfc/nfcmrvl/Makefile b/drivers/nfc/nfcmrvl/Makefile index 97a0de72dc01..775196274d1f 100644 --- a/drivers/nfc/nfcmrvl/Makefile +++ b/drivers/nfc/nfcmrvl/Makefile | |||
| @@ -7,3 +7,6 @@ obj-$(CONFIG_NFC_MRVL) += nfcmrvl.o | |||
| 7 | 7 | ||
| 8 | nfcmrvl_usb-y += usb.o | 8 | nfcmrvl_usb-y += usb.o |
| 9 | obj-$(CONFIG_NFC_MRVL_USB) += nfcmrvl_usb.o | 9 | obj-$(CONFIG_NFC_MRVL_USB) += nfcmrvl_usb.o |
| 10 | |||
| 11 | nfcmrvl_uart-y += uart.o | ||
| 12 | obj-$(CONFIG_NFC_MRVL_UART) += nfcmrvl_uart.o | ||
diff --git a/drivers/nfc/nfcmrvl/nfcmrvl.h b/drivers/nfc/nfcmrvl/nfcmrvl.h index 214412bd6110..09780d57c9b8 100644 --- a/drivers/nfc/nfcmrvl/nfcmrvl.h +++ b/drivers/nfc/nfcmrvl/nfcmrvl.h | |||
| @@ -43,6 +43,11 @@ | |||
| 43 | #define NFCMRVL_HCI_OGF 0x81 | 43 | #define NFCMRVL_HCI_OGF 0x81 |
| 44 | #define NFCMRVL_HCI_OCF 0xFE | 44 | #define NFCMRVL_HCI_OCF 0xFE |
| 45 | 45 | ||
| 46 | enum nfcmrvl_phy { | ||
| 47 | NFCMRVL_PHY_USB = 0, | ||
| 48 | NFCMRVL_PHY_UART = 1, | ||
| 49 | }; | ||
| 50 | |||
| 46 | 51 | ||
| 47 | struct nfcmrvl_private { | 52 | struct nfcmrvl_private { |
| 48 | 53 | ||
| @@ -61,6 +66,8 @@ struct nfcmrvl_private { | |||
| 61 | void *drv_data; | 66 | void *drv_data; |
| 62 | /* PHY device */ | 67 | /* PHY device */ |
| 63 | struct device *dev; | 68 | struct device *dev; |
| 69 | /* PHY type */ | ||
| 70 | enum nfcmrvl_phy phy; | ||
| 64 | /* Low level driver ops */ | 71 | /* Low level driver ops */ |
| 65 | struct nfcmrvl_if_ops *if_ops; | 72 | struct nfcmrvl_if_ops *if_ops; |
| 66 | }; | 73 | }; |
diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c new file mode 100644 index 000000000000..61442d6528a6 --- /dev/null +++ b/drivers/nfc/nfcmrvl/uart.c | |||
| @@ -0,0 +1,225 @@ | |||
| 1 | /** | ||
| 2 | * Marvell NFC-over-UART driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2015, Marvell International Ltd. | ||
| 5 | * | ||
| 6 | * This software file (the "File") is distributed by Marvell International | ||
| 7 | * Ltd. under the terms of the GNU General Public License Version 2, June 1991 | ||
| 8 | * (the "License"). You may use, redistribute and/or modify this File in | ||
| 9 | * accordance with the terms and conditions of the License, a copy of which | ||
| 10 | * is available on the worldwide web at | ||
| 11 | * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. | ||
| 12 | * | ||
| 13 | * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE | ||
| 14 | * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE | ||
| 15 | * ARE EXPRESSLY DISCLAIMED. The License provides additional details about | ||
| 16 | * this warranty disclaimer. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/of_gpio.h> | ||
| 22 | #include <net/nfc/nci.h> | ||
| 23 | #include <net/nfc/nci_core.h> | ||
| 24 | #include "nfcmrvl.h" | ||
| 25 | |||
| 26 | static unsigned int hci_muxed; | ||
| 27 | static unsigned int flow_control; | ||
| 28 | static unsigned int break_control; | ||
| 29 | static unsigned int reset_n_io; | ||
| 30 | |||
| 31 | /* | ||
| 32 | ** NFCMRVL NCI OPS | ||
| 33 | */ | ||
| 34 | |||
| 35 | static int nfcmrvl_uart_nci_open(struct nfcmrvl_private *priv) | ||
| 36 | { | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | static int nfcmrvl_uart_nci_close(struct nfcmrvl_private *priv) | ||
| 41 | { | ||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | static int nfcmrvl_uart_nci_send(struct nfcmrvl_private *priv, | ||
| 46 | struct sk_buff *skb) | ||
| 47 | { | ||
| 48 | struct nci_uart *nu = priv->drv_data; | ||
| 49 | |||
| 50 | return nu->ops.send(nu, skb); | ||
| 51 | } | ||
| 52 | |||
| 53 | static struct nfcmrvl_if_ops uart_ops = { | ||
| 54 | .nci_open = nfcmrvl_uart_nci_open, | ||
| 55 | .nci_close = nfcmrvl_uart_nci_close, | ||
| 56 | .nci_send = nfcmrvl_uart_nci_send, | ||
| 57 | }; | ||
| 58 | |||
| 59 | #ifdef CONFIG_OF | ||
| 60 | |||
| 61 | static int nfcmrvl_uart_parse_dt(struct device_node *node, | ||
| 62 | struct nfcmrvl_platform_data *pdata) | ||
| 63 | { | ||
| 64 | struct device_node *matched_node; | ||
| 65 | int ret; | ||
| 66 | |||
| 67 | matched_node = of_find_compatible_node(node, NULL, "mrvl,nfc-uart"); | ||
| 68 | if (!matched_node) | ||
| 69 | return -ENODEV; | ||
| 70 | |||
| 71 | ret = nfcmrvl_parse_dt(matched_node, pdata); | ||
| 72 | if (ret < 0) { | ||
| 73 | pr_err("Failed to get generic entries\n"); | ||
| 74 | return ret; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (of_find_property(matched_node, "flow-control", NULL)) | ||
| 78 | pdata->flow_control = 1; | ||
| 79 | else | ||
| 80 | pdata->flow_control = 0; | ||
| 81 | |||
| 82 | if (of_find_property(matched_node, "break-control", NULL)) | ||
| 83 | pdata->break_control = 1; | ||
| 84 | else | ||
| 85 | pdata->break_control = 0; | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | #else | ||
| 91 | |||
| 92 | static int nfcmrvl_uart_parse_dt(struct device_node *node, | ||
| 93 | struct nfcmrvl_platform_data *pdata) | ||
| 94 | { | ||
| 95 | return -ENODEV; | ||
| 96 | } | ||
| 97 | |||
| 98 | #endif | ||
| 99 | |||
| 100 | /* | ||
| 101 | ** NCI UART OPS | ||
| 102 | */ | ||
| 103 | |||
| 104 | static int nfcmrvl_nci_uart_open(struct nci_uart *nu) | ||
| 105 | { | ||
| 106 | struct nfcmrvl_private *priv; | ||
| 107 | struct nfcmrvl_platform_data *pdata = NULL; | ||
| 108 | struct nfcmrvl_platform_data config; | ||
| 109 | |||
| 110 | /* | ||
| 111 | * Platform data cannot be used here since usually it is already used | ||
| 112 | * by low level serial driver. We can try to retrieve serial device | ||
| 113 | * and check if DT entries were added. | ||
| 114 | */ | ||
| 115 | |||
| 116 | if (nu->tty->dev->parent && nu->tty->dev->parent->of_node) | ||
| 117 | if (nfcmrvl_uart_parse_dt(nu->tty->dev->parent->of_node, | ||
| 118 | &config) == 0) | ||
| 119 | pdata = &config; | ||
| 120 | |||
| 121 | |||
